Come posso eseguire il mio servizio systemd tramite un utente specifico e avviarlo all'avvio?


133

Ho appena effettuato l'aggiornamento dal server Ubuntu 14 alla versione 15. Ho avuto problemi a far funzionare il mio script upstart dopo l'aggiornamento e ho letto che systemd è il nuovo predefinito. Sono tutt'altro che un esperto di Linux, quindi per favore andate piano con me :-)

Ecco cosa era prima il mio script upstart:

description "NZBGet upstart script"

setuid robert
setgid robert

start on runlevel [2345]
stop on runlevel [016]

respawn

expect fork

script
    exec nzbget -D
end script

pre-stop script
    exec nzbget -Q
end script

Sulla base della pagina upstart to systemd wiki , ho usato le tabelle fornite lì per mappare le cose il più vicino possibile nel mio nuovo file di servizio systemd:

[Unit]
Description=NZBGet Service

[Service]
Type=forking
ExecStart=/usr/local/bin/nzbget -D
ExecStop=/usr/local/bin/nzbget -Q
Restart=on-failure

Questo file si trova in /home/robert/.config/systemd/user/nzbget.service. Per avviare il servizio manualmente, ho fatto:

$ systemctl --user start nzbget

Funziona benissimo. Tuttavia, quando esco dalla sessione SSH, il servizio si arresta. Inoltre, non si avvia all'avvio o al login dell'utente. Voglio che si comporti come un servizio upstart: voglio che si avvii all'avvio, funzioni costantemente e come utente specifico.

Cosa devo fare per ottenere questa configurazione?

Risposte:


164

Primo problema

È possibile specificare le direttive User=e Group=nella [Service]sezione del file di unità.

Secondo problema

Per eseguire il servizio all'avvio, non è necessario inserirlo nella cartella principale. Invece, mettilo sotto /etc/systemd/system/. Questa è la cartella pensata per essere utilizzata dall'amministratore di sistema (cioè tu) per aggiungere nuovi servizi a livello di sistema.

Altre cartelle includono:

  • /usr/lib/systemd/system/è pensato per i pacchetti che vogliono installare file unitari, sebbene in Debian e Ubuntu la cartella sia in realtà /lib/systemd/system/perché le varie bine le libcartelle non sono ancora state unite in un /usr/prefisso unificato .
  • /usr/local/systemd/system/ è per l'installazione di unità tramite pacchetti compilati localmente.

Test dell'unità

Una volta che il file dell'unità si trova in una posizione appropriata, puoi provare ad avviare immediatamente l'unità digitando systemctl start <UNIT_FILENAME>come al solito. Dovrebbe funzionare senza dover digitare il percorso completo dell'unità. Inoltre, non è necessario specificare l'estensione se lo è .service.

Abilitazione dell'unità

Prima di poter abilitare l'unità, è necessario aggiungere una [Install]sezione, in base alla quale è necessario aggiungere la direttiva WantedBy=multi-user.target. Questa direttiva specifica la fase del processo di avvio durante il quale il servizio deve essere avviato (se fosse abilitato). multi-user.targetè appropriato per la maggior parte dei servizi.

Una volta aggiunte tali informazioni, è possibile utilizzare systemctl enable <UNIT_FILENAME>, che abilita l'unità, facendo in modo che systemd da ora in poi la avvii automaticamente durante l'avvio nella fase specificata.


Questo ha funzionato. Ho dovuto specificare il percorso assoluto del nome del file di servizio nel systemctl enablecomando, all'inizio non era ovvio per me. Anche l'abilitazione mi ha dato alcuni avvertimenti su una [Install]sezione mancante . L'ho ignorato, ma non sono sicuro che influenzerà la sua capacità di avvio all'avvio.
void.pointer

2
L' Installavvertimento era davvero molto importante. Non si avvierà all'avvio senza WantedBy=multi-user.targetnella [Install]sezione. Dopo aver aggiunto questo al .servicefile allora si può enableesso.
void.pointer

4
Mi scuso per aver lasciato la risposta incustodita per così tanto tempo. Ho corretto la posizione in cui il file dell'unità dovrebbe andare, ho aggiunto le informazioni mancanti sulla [Install]sezione. Spero che ora sia più utile per chiunque lo cerchi.
Yamaho,

5
Questo diventa molto più semplice quando il nome utente è basato su un modello, ovvero il tuo servizio è definito con un nome file nel formato, something@.servicequindi enabled come something@username.servicel'impostazione diventa User=%iindicante che l'utente non è codificato e che più utenti possono utilizzare la stessa definizione. Un esempio.
Walf,

1
Inizierà se lo metto sotto /etc/systemd/user/?
Khurshid Alam,

46

Potresti essere interessato all'utilizzo della funzionalità "utente persistente" di systemd. È abilitato tramite loginctl enable-linger USERNAME.

Provoca l'avvio di un gestore servizi separato per il rispettivo utente all'avvio, quindi le unità definite dall'utente ~/.config/systemd/userverranno prelevate ed elaborate al momento dell'avvio e dell'arresto in base alla configurazione del servizio.

È inoltre possibile utilizzare systemctl --userper la gestione e la configurazione dei servizi, che opereranno sul gestore dei servizi dell'utente, non su quello del sistema.


6
systemctl --userè una scoperta fantastica. Grazie!
Anwar,

@byteborg Forse puoi contribuire a unix.stackexchange.com/questions/409900/… ? Ho bisogno di dipendenza da PostgreSQL nel servizio persistente dell'utente, ma il database rimane un servizio di sistema, non quello dell'utente.
Michał F,

1
Una volta che i servizi sono in esecuzione, esistono delle tecniche che possono consentire all'utente di vedere i registri del servizio? Un utente non privilegiato non sarebbe in grado di accedere a / var / log / syslog.
MPR

2
Si noti che systemctl --usernon sembra funzionare per le sessioni SSH però.
Mark K Cowan,

2
Dovrebbe essere la soluzione accettata
Drew
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.