Inicie o simples servidor Go / Golang com systemd no Debian ou Ubuntu

1

Eu quero começar o seguinte código Golang com o systemd:

...

func main() {
  // main routes
  http.HandleFunc("/", hello)
  log.Fatalln(http.ListenAndServe(":80", nil))
}

func hello(w http.ResponseWriter, r *http.Request) {
  fmt.Fprint(w, "Hello")
}

O código é construído com go build

Nome do binário resultante: MyApp

Caminho: /home/andrei/MyApp/MyApp - o segundo MyApp é o arquivo binário

Dentro de /lib/systemd/system , coloco o arquivo MyApp.service com o conteúdo:

[Unit]
Description=MyApp service
After=network.target

[Socket]
ListenStream=80
NoDelay=true

[Service]
Type=simple
Restart=on-failure
RestartSec=3
User=andrei
Group=andrei

WorkingDirectory=/home/andrei/MyApp
ExecStart=/home/andrei/MyApp/MyApp

[Install]
WantedBy=multi-user.target

No Ubuntu eu corro o comando (com o sudo no Debian):

sistemctl start MyApp.service
sistemctl status MyApp.service

Eu recebo a saída:

● MyApp.service - MyApp service
Loaded: loaded (/lib/systemd/system/MyApp.service; disabled; vendor preset: enabled)
Active: activating (auto-restart) (Result: exit-code) since Wed 2018-11-14 11:30:45 UTC; 1s ago
Process: 14883 ExecStart=/home/andrei/MyApp/MyApp (code=exited, status=1/FAILURE)
Main PID: 14883 (code=exited, status=1/FAILURE)

Nov 14 11:30:45 andrei systemd[1]: MyApp.service: Main process exited, code=exited, status=1/FAILURE
Nov 14 11:30:45 andrei systemd[1]: MyApp.service: Failed with result 'exit-code'.

NOTE:

Quando eu executo o aplicativo no terminal, tudo funciona bem.

Como posso iniciar o aplicativo com o systemd?

Update:

Funciona fazendo o seguinte:

sudo setcap CAP_NET_BIND_SERVICE=+eip /home/andrei/MyApp/MyApp

Um arquivo de unidade melhor é útil - não é necessário para que funcione:

[Unit]
Description=MyApp service
After=network.target

[Service]
Type=simple
Restart=always
User=andrei
Group=andrei
WorkingDirectory=/home/andrei/MyApp
ExecStart=/home/andrei/MyApp/MyApp

# make sure log directory exists and owned by syslog
PermissionsStartOnly=true
ExecStartPre=/bin/mkdir -p /var/log/sleepservice
ExecStartPre=/bin/chown syslog:adm /var/log/sleepservice
ExecStartPre=/bin/chmod 755 /var/log/sleepservice
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=sleepservice

[Install]
WantedBy=multi-user.target

Agora, trabalhe com:

sudo systemctl daemon-reload
sudo systemctl start MyApp.service
sudo systemctl enable MyApp.service # app will start on OS restart
sudo journalctl -f -u MyApp.service # provide information about the app
    
por Gopher 14.11.2018 / 12:58

1 resposta

0

O problema que você está enfrentando é que você está executando o aplicativo com um usuário não raiz ( User=andrei ), mas, em seguida, seu aplicativo está tentando escutar na porta 80 ( http.ListenAndServe(":80", nil) ), que é um privilégio porta que normalmente apenas o root pode escutar.

Quando você diz:

When I run the app from the terminal everything works fine.

Por acaso, você está executando como root ? Porque então, eu esperaria que funcionasse bem.

Se você estiver certo em usar uma porta diferente (número de porta acima de 1024, o que seria sem privilégios), essa seria a solução mais fácil para que seu serviço fosse executado como não-raiz.

Além disso, este snippet do seu arquivo de unidade:

[Socket]
ListenStream=80
NoDelay=true

Isso não funciona realmente em uma unidade de serviço; ela funciona apenas em uma unidade de soquete , para fazer ativação do soquete funcionar, você precisaria de uma unidade MyApp.socket separada com essas configurações.

Mas a ativação de soquete é mais complexa do que apenas criar uma unidade separada, já que o próprio aplicativo precisa de suporte para receber o soquete de escuta do systemd. Por exemplo, um aplicativo C chamaria sd_listend_fds () e o link para libsystemd para implementar isso. Pode haver ligações para fazer o mesmo no Go, procure por coreos / go-systemd por exemplo, pode haver alguns lá .

A ativação do soquete teria a vantagem de poder usar a porta 80 e um usuário não raiz, mas, conforme mencionado, precisa de alterações em seu aplicativo.

    
por 15.11.2018 / 04:45

Tags