Cómo crear servicios en Ubuntu 16.04 con systemd

En Tutoriales y Guías por

Desde Ubuntu 15.04 Vivid Vervet se integró en Ubuntu el gestor de demonios Systemd como reemplazo a Upstart. No vamos a entrar en el debate de si fue una buena o mala decisión de Canonical adoptar systemd, pero sabiendo que ahora con Ubuntu 16.04 son muchos los programas que recurren a systemd para gestionar sus demonios, era necesario escribir un pequeño tutorial de cómo crear servicios en Ubuntu 16.04 con systemd.

Cómo crear servicios en Ubuntu 16.04 con systemd

Sin ir más lejos, cuando publicamos el artículo de cómo crear un seedbox con Deluge o el de cómo instalar Tiny Tiny RSS, en ambos tutoriales se creaba un servicio que configuramos con systemd. Por este motivo, es importante conocer los aspectos básicos para poder crear nuestros propios servicios y configurarlos correctamente.

¿Qué es un demonio?

Empecemos por tratar de explicar qué es un demonio de forma intuitiva y sin entrar en grandes tecnicismos para que todos los usuarios lo puedan abordar. Un demonio lo podemos definir como un proceso que funciona en segundo plano y que es capaz de autogestionarse, sin que el usuario tenga que interactuar con él.

En sistemas operativos Debian y sus derivados como Ubuntu, tenemos como gestor de demonios el llamado systemd.

Cómo crear servicios en Ubuntu 16.04 con systemd.

En primer lugar debemos conocer los unit files (archivos de unidad), los cuales se emplean para configurar los servicios. Los unit files son archivos de texto que contienen las diferentes instrucciones y están alojados por defecto en la ruta /etc/systemd/system/.

Conceptos básicos sobre los unit files, qué son y para qué sirven.

Los nombres de los unit files se definen por un unit_name (nombre de unidad) y type_extension (tipo de extensión). Para entender esto mejor vamos a proponer un nombre de ejemplo que será midemonio.service.

servicio systemd esquema de ejemplo

Aquí diferenciamos por una parte midemonio como el unit_name y por otro lado tenemos que el type_extension es .service.

Como unit_name podemos elegir un nombre que nos sirva para identificar el demonio, pero como type_extension sólo podemos elegir entre doce posibilidades según la funcionalidad del demonio:

  • .service
  • .target
  • .automount
  • .device
  • .mount
  • .path
  • .scope
  • .slice
  • .snapshot
  • .socket
  • .swap
  • .timer

En este tutorial como pretendemos crear un servicio, vamos a trabajar sólo con el tipo de extensión .service.

Además, pueden existir carpetas que acompañan a los unit files para añadir configuraciones adicionales. Este aspecto no lo vamos a cubrir en este tutorial, pero está bien nombrarlo para que se sepa que existe esta posibilidad. En caso de duda siempre se puede consultar documentación adicional de los unit files (en inglés).

Creando el unit file para configurar el servicio.

En primer lugar debemos crear el unit file con su correspondiente unit_name y type_extension, yo voy a crear el unit file ejemplo.service con los comandos:
sudo touch /etc/systemd/system/ejemplo.service
sudo chmod 664 /etc/systemd/system/ejemplo.service
sudo nano /etc/systemd/system/ejemplo.service

Como contenidos del unit file pego:

[Unit]
Description=servicio de ejemplo
After=network.target mysql.service

[Service]
User=www-data
ExecStart=/ruta/script/demonio
Restart=on-failure

[Install]
WantedBy=multi-user.target

Creo que el contenido del unit file se explica por sí solo, pero aún así vamos a ir comentando las diferentes partes y opciones. Vemos que el archivo se divide en tres partes:

  • [Unit]: en este apartado se establecen las opciones genéricas que no dependen del tipo de extensión.
  • [Service]: en este apartado se establecen las opciones específicas para el tipo de extensión elegido. Como en nuestro ejemplo es type_extension de tipo .service, a este apartado se le llama [Service]. En cambio si fuese de tipo .socket, a este apartado se le llamaría [Socket] y así con el resto de tipos de extensión.
  • [Install]: contiene información sobre la instalación del servicio que afecta a la ejecución de los comandos systemctl enable y systemctl disable que explicaremos más adelante.

Las opciones más importantes del unit file son:

  • La directiva After, que establece el orden en el que se ejecutan los diferentes unit files. También existe la directiva Before que hace lo contrario. En nuestro caso vemos que ejemplo.service se ejecutará después de haber ejecutado network.target y mysql.service.
  • La directiva User establece el usuario bajo el que se ejecutará el script del demonio. También se puede establecer el grupo con la directiva Group. En nuestro caso el script del demonio se ejecutara bajo el usuario www-data.
  • La directiva ExecStart establece el script o comando que se va a ejecutar.

Este es un unit file sencillo que nos sirve a modo de ejemplo, pero para consultar todas las opciones disponibles, puedes consultar la página del manual oficial systemd.service(5) (en inglés).

Gestionar el servicio creado con el comando systemctl.

Ya sólo nos queda conocer el comando systemctl que nos permite gestionar systemd. Con nuestro servicio ejemplo.service ya creado, tenemos que incorporarlo a la secuencia de arranque del sistema con el comando:
sudo systemctl enable ejemplo.service

También disponemos del comando systemctl disable ejemplo.service para eliminar el servicio de la secuencia de arranque. Con el comando systemctl daemon-reload reiniciamos el proceso systemd y se utiliza cuando añadimos o eliminamos un servicio.

Para iniciar el servicio empleamos el comando:
sudo systemctl start ejemplo.service

Del mismo modo podemos:

  • Detener el servicio: sudo systemctl stop ejemplo.service
  • Reiniciar el servicio: sudo systemctl restart ejemplo.service
  • Obtener información del estado del servicio: sudo systemctl status ejemplo.service

No nos olvidemos de que esta guía pretende ser una pequeña introducción que sirve como toma de contacto a la creación de servicios con systemd, ya que para tratar el tema con mayor profundidad haría falta un libro. Espero que a partir de ahora no sea una pesadilla crear servicios en Ubuntu con systemd.