Comment faire en sorte que mon service systemd s'exécute via un utilisateur spécifique et démarre au démarrage?

133

Je viens de mettre à niveau la version 15 du serveur Ubuntu 14 vers la version 15. J'ai eu du mal à faire fonctionner mon script d'installation après la mise à niveau et j'ai lu que systemd était la nouvelle valeur par défaut. Je suis loin d'être un expert linux, alors allez-y doucement sur moi :-)

Voici ce que mon script parvenu était avant:

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

Sur la base de la page de wiki de updart to systemd , j’ai utilisé les tables fournies pour mapper le plus fidèlement possible dans mon nouveau fichier de service systemd:

[Unit]
Description=NZBGet Service

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

Ce fichier se trouve à l'adresse /home/robert/.config/systemd/user/nzbget.service. Pour démarrer le service manuellement, je faisais:

$ systemctl --user start nzbget

Cela fonctionne très bien. Cependant, lorsque je me déconnecte de ma session SSH, le service s'arrête. En outre, il ne démarre pas au démarrage ou lors de la connexion de l'utilisateur. Je veux qu'il se comporte comme s'il s'agissait d'un service upstart: je veux qu'il démarre au démarrage, s'exécute constamment et en tant qu'utilisateur spécifique.

Que dois-je faire pour obtenir cette configuration?

void.pointer
la source

Réponses:

164

Premier problème

Vous pouvez spécifier les directives User=et Group=dans la [Service]section du fichier unité.

Deuxième problème

Pour que le service fonctionne au démarrage, vous ne devez pas le placer dans votre dossier personnel. Au lieu de cela, mettez-le sous /etc/systemd/system/. Il s’agit du dossier que l’administrateur système (c’est-à-dire vous-même) doit utiliser pour ajouter de nouveaux services à l’échelle du système.

Les autres dossiers incluent:

  • /usr/lib/systemd/system/est destiné aux paquets qui veulent installer des fichiers unitaires, même si sous Debian et Ubuntu, le dossier est en réalité /lib/systemd/system/car les différents dossiers binet libdossiers n'ont pas encore été fusionnés dans un /usr/préfixe unifié .
  • /usr/local/systemd/system/ est destiné à l'installation d'unités par des packages compilés localement.

Test de l'unité

Une fois que le fichier de l'unité est à un emplacement approprié, vous pouvez essayer de démarrer l'unité immédiatement en tapant systemctl start <UNIT_FILENAME>comme d'habitude. Cela devrait fonctionner sans avoir à taper le chemin complet de l'unité. L'extension n'a pas non plus besoin d'être spécifiée si c'est .service.

Activer l'unité

Avant de pouvoir activer votre unité, vous devez ajouter une [Install]section sous laquelle vous devez ajouter la directive WantedBy=multi-user.target. Cette directive spécifie l'étape du processus de démarrage au cours de laquelle le service doit être démarré (s'il était activé). multi-user.targetest approprié pour la plupart des services.

Une fois ces informations ajoutées, vous pouvez utiliser pour systemctl enable <UNIT_FILENAME>activer l'unité et faire en sorte que systemd la lance automatiquement lors du démarrage à l'étape indiquée.

Yamaho
la source
Cela a fonctionné. Je devais spécifier le chemin absolu du nom de fichier du service dans la systemctl enablecommande, ce n'était pas évident pour moi au début. Cela m'a également mis en garde contre une [Install]section manquante . Je l'ai ignoré, mais je ne sais pas si cela affectera sa capacité à démarrer au démarrage.
void.pointer le
2
L' Installavertissement était réellement important. Il ne commencera pas au démarrage sans WantedBy=multi-user.targetsous la [Install]section. Après avoir ajouté ceci au .servicefichier, alors vous pouvez enablelui.
void.pointer
4
Je m'excuse d'avoir laissé la réponse sans surveillance pendant si longtemps. J'ai corrigé l'emplacement où devrait se trouver le fichier d'unité, ajouté les informations manquantes sur la [Install]section. J'espère que c'est maintenant plus utile pour ceux qui le cherchent.
Yamaho
5
Cela devient beaucoup plus facile lorsque le nom d'utilisateur est basé sur un modèle, c'est-à-dire que votre service est défini avec un nom de fichier au format [email protected]puis enableque [email protected]le paramètre devient alors User=%ique l'utilisateur n'est pas codé en dur et que plusieurs utilisateurs peuvent utiliser la même définition. Un exemple.
Walf
1
Est-ce que ça va commencer si je le mets sous /etc/systemd/user/?
Khurshid Alam
46

Vous pourriez être intéressé par l’utilisation de la fonctionnalité "utilisateur en attente" de systemd. Il est activé via loginctl enable-linger USERNAME.

Cela entraîne le démarrage d'un gestionnaire de services distinct pour l'utilisateur respectif au démarrage. Ainsi, vos unités définies par l'utilisateur ~/.config/systemd/userseront récupérées et traitées aux heures de démarrage et d'arrêt en fonction de la configuration de votre service.

Vous pouvez également utiliser systemctl --userpour gérer et configurer le (s) service (s), qui fonctionneront sur le gestionnaire de service de votre utilisateur, et non sur celui du système.

Byteborg
la source
6
systemctl --userest une découverte fantastique. Merci!
Anwar
@byteborg Peut-être pouvez-vous contribuer à unix.stackexchange.com/questions/409900/… ? J'ai besoin de la dépendance de PostgreSQL dans le service utilisateur, mais la base de données reste le service système et non celui de l'utilisateur.
Michał F
1
Une fois que les services sont en cours d’exécution, existe-t-il des techniques permettant à l’utilisateur de consulter les journaux du service? Un utilisateur sans privilège ne pourrait pas accéder à / var / log / syslog.
Mpr
2
Notez que systemctl --usercela ne semble pas fonctionner pour les sessions SSH.
Mark K Cowan
2
Devrait être la solution acceptée
Drew