¿Cómo hago que mi servicio systemd se ejecute a través de un usuario específico y comience en el arranque?

133

Acabo de actualizar desde el servidor Ubuntu 14 a la versión 15. Tuve problemas para que mi script de arranque funcionara después de la actualización, y leí que systemd es el nuevo valor predeterminado. Estoy lejos de ser un experto en Linux, así que por favor, sé fácil conmigo :-)

Aquí está lo que era mi script inicial:

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

Basado en el inicio de la página wiki de systemd , utilicé las tablas proporcionadas allí para mapear las cosas lo más cerca que pude en mi nuevo archivo de servicio systemd:

[Unit]
Description=NZBGet Service

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

Este archivo está ubicado en /home/robert/.config/systemd/user/nzbget.service. Para iniciar el servicio manualmente, he estado haciendo:

$ systemctl --user start nzbget

Esto funciona muy bien. Sin embargo, cuando salgo de mi sesión SSH, el servicio se cierra. Además, no se inicia en el arranque ni en el inicio de sesión del usuario. Quiero que se comporte de la misma manera que un servicio de arranque: quiero que se inicie en el arranque, se ejecute constantemente y como un usuario específico.

¿Qué debo hacer para obtener esta configuración?

void.pointer
fuente

Respuestas:

164

Primer problema

Puede especificar las directivas User=y Group=en la [Service]sección del archivo de la unidad.

Segundo problema

Para que el servicio se ejecute en el arranque, no debe colocarlo en su carpeta de inicio. En cambio, póngalo debajo /etc/systemd/system/. Esta es la carpeta que debe utilizar el administrador del sistema (es decir, usted) para agregar nuevos servicios en todo el sistema.

Otras carpetas incluyen:

  • /usr/lib/systemd/system/está destinado a paquetes que desean instalar archivos de unidad, aunque en Debian y Ubuntu la carpeta se /lib/systemd/system/debe en realidad a que las diversas carpetas biny libaún no se han fusionado en un /usr/prefijo unificado .
  • /usr/local/systemd/system/ es para instalar unidades mediante paquetes compilados localmente.

Probar la unidad

Una vez que el archivo de la unidad está en una ubicación adecuada, puede intentar iniciar la unidad de inmediato escribiendo systemctl start <UNIT_FILENAME>como de costumbre. Debería funcionar sin tener que escribir la ruta completa de la unidad. La extensión tampoco tiene que especificarse si es así .service.

Habilitando la unidad

Antes de poder habilitar su unidad, necesita agregar una [Install]sección, bajo la cual debe agregar la directiva WantedBy=multi-user.target. Esta directiva especifica la etapa del proceso de arranque durante el cual se debe iniciar el servicio (si estuviera habilitado). multi-user.targetEs apropiado para la mayoría de los servicios.

Una vez que se agrega esa información, puede usar systemctl enable <UNIT_FILENAME>, lo que habilita la unidad, haciendo que systemd a partir de ahora se inicie automáticamente durante el arranque en la etapa especificada.

Yamaho
fuente
Esto funcionó. Sin systemctl enableembargo, tuve que especificar la ruta absoluta al nombre de archivo del servicio en el comando, esto no era obvio para mí al principio. También habilitar me dio alguna advertencia sobre una [Install]sección que falta . Lo ignoré, pero no estoy seguro de si afectará su capacidad para comenzar en el momento del arranque.
void.pointer
2
La Installadvertencia fue realmente muy importante. No comenzará en el arranque sin WantedBy=multi-user.targetdebajo de la [Install]sección. Después de añadir esto al .servicearchivo, a continuación, puede enableella.
void.pointer
44
Pido disculpas por dejar la respuesta desatendida durante tanto tiempo. Arreglé la ubicación donde debería ir el archivo de la unidad, agregué la información que faltaba sobre la [Install]sección. Espero que ahora sea más útil para cualquiera que lo busque.
Yamaho
55
Esto se vuelve mucho más fácil cuando el nombre de usuario está en plantilla, es decir, su servicio se define con un nombre de archivo en el formato y [email protected]luego enabled, como [email protected]la configuración, User=%isignifica que el usuario no está codificado y que varios usuarios pueden usar la misma definición. Un ejemplo.
Walf
1
¿Comenzará si lo pongo debajo /etc/systemd/user/?
Khurshid Alam
46

Puede que le interese utilizar la funcionalidad de "persistencia del usuario" de systemd. Está habilitado a través de loginctl enable-linger USERNAME.

Causa un administrador de servicio separado para el usuario respectivo que se inicia en el arranque, por lo que sus unidades definidas por el usuario se ~/.config/systemd/userrecogerán y procesarán en los tiempos de arranque y apagado de acuerdo con la configuración de su servicio.

También puede usarlo systemctl --userpara administrar y configurar los servicios, que operarán en el administrador de servicios de su usuario, no en el del sistema.

byteborg
fuente
66
systemctl --userEs un hallazgo fantástico. ¡Gracias!
Anwar
@byteborg ¿Quizás pueda contribuir a unix.stackexchange.com/questions/409900/… ? Necesito dependencia de PostgreSQL en el servicio persistente del usuario, pero la base de datos sigue siendo el servicio del sistema, no el del usuario.
Michał F
1
Una vez que se ejecutan los servicios, ¿hay alguna técnica que permita al usuario ver los registros del servicio? Un usuario no privilegiado no podría acceder a / var / log / syslog.
mpr
2
Sin systemctl --userembargo, tenga en cuenta que no parece funcionar para sesiones SSH.
Mark K Cowan
2
Debería ser la solución aceptada
Drew