Comment puis-je exécuter un simple serveur Go en tant que démon dans Debian?

J’ai récemment écrit un serveur simple dans Go:

package main import ( "net/http" "fmt" "os/exec" ) func main() { http.HandleFunc("/", handler) http.ListenAndServe(":****", nil) } func handler(output http.ResponseWriter, input *http.Request) { instruction := "Instructed to " + input.URL.Path[1:] + "." fmt.Printf(instruction) if input.URL.Path[1:] == "********" { ************* ************* ************* if err != nil { fmt.Println("There was a problem executing the script.") } } else { fmt.Println(" I'm unfamiliar with this instruction.") } } 

Il fonctionne parfaitement s’il est compilé puis exécuté par ./go_http_server & .

Le problème est qu’il ne survit pas aux redémarrages. Donc après quelques lectures, j’ai tenté de le démoniser en plaçant un script dans /etc/init.d:

 #!/bin/sh ### BEGIN INIT INFO # Provides: myservice # Required-Start: $remote_fs $syslog # Required-Stop: $remote_fs $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Put a short description of the service here # Description: Put a long description of the service here ### END INIT INFO # Change the next 3 lines to suit where you install your script and what you want to call it DIR=/****/**** DAEMON=$DIR/go_http_server DAEMON_NAME=********* # Add any command line options for your daemon here DAEMON_OPTS="" # This next line determines what user the script runs as. # Root generally not recommended but necessary if you are using the Raspberry Pi GPIO from Python. DAEMON_USER=***** # The process ID of the script when it runs is stored here: PIDFILE=/var/run/$DAEMON_NAME.pid . /lib/lsb/init-functions do_start () { log_daemon_msg "Starting system $DAEMON_NAME daemon" start-stop-daemon --start --background --pidfile $PIDFILE --make-pidfile --user $DAEMON_USER --chuid $DAEMON_USER --startas $DAEMON -- $DAEMON_OPTS log_end_msg $? } do_stop () { log_daemon_msg "Stopping system $DAEMON_NAME daemon" start-stop-daemon --stop --pidfile $PIDFILE --retry 10 log_end_msg $? } case "$1" in start|stop) do_${1} ;; restart|reload|force-reload) do_stop do_start ;; status) status_of_proc "$DAEMON_NAME" "$DAEMON" && exit 0 || exit $? 

… puis lancez update-rc.d go_http_server par défaut , et poof! Il s’exécute au démarrage, comme vérifié par ps -ef | grep go_http_server .

Mais il ne reçoit pas de requêtes GET lors de l’exécution en tant que service. En pensant qu’il pourrait être en cours d’exécution avant la fin de l’interface réseau, j’ai essayé le service go_http_server stop , suivi du service go_http_server start ; toujours refusé de recevoir des demandes GET. Arrêtez le service puis exécutez ./go_http_server et faites fonctionner le serveur une fois de plus.

Je suis allé sur Google pour quelques jours maintenant. Soit mes requêtes de recherche sont nulles, soit ce n’est pas un problème évident. Comment démoniser mon serveur Go?


EDIT: La même chose se produit avec un serveur que j’ai écrit en Python: il fonctionne comme il se doit lorsqu’il est exécuté en utilisant ./python_server.py , mais – si lancé en tant que service – les requêtes HTTP sont ignorées. Les deux fichiers ont été rendus exécutables, peu importe que l’utilisateur du démon soit root ou tout autre utilisateur. Je ne suis pas sûr que cela aide, mais j’ai pensé que cela pourrait être pertinent.

Superviseur est un bon ajustement ici, et peut automatiquement capturer et faire pivoter les journaux écrits dans stdout, redémarrer sur incident et gérer les ports / permissions.

Voici à quoi ressemblerait un exemple de configuration pour un service Web Go:

 # where 'mygoapp' is the name of your application $ sudo vim /etc/supervisor/conf.d/mygoapp.conf [program:yourapp] command=/home/yourappuser/bin/yourapp # the location of your app autostart=true autorestart=true startresortinges=10 user=yourappuser # the user your app should run as (ie *not* root!) directory=/srv/www/yourapp.com/ # where your application runs from environment=APP_SETTINGS="/srv/www/yourapp.com/prod.toml" # environmental variables redirect_stderr=true stdout_logfile=/var/log/supervisor/yourapp.log # the name of the log file. stdout_logfile_maxbytes=50MB stdout_logfile_backups=10 

J’ai écrit un article [ 1 ] qui vous guidera à travers les étapes, mais la documentation du superviseur est extrêmement complète.

De même, les systèmes Debian utilisent également systemd [ 2 ], ce qui permet d’y parvenir également.