Cómo crear servicios en Ubuntu 16.04 con systemd
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.
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
.
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 estype_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 comandossystemctl enable
ysystemctl 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 directivaBefore
que hace lo contrario. En nuestro caso vemos queejemplo.service
se ejecutará después de haber ejecutadonetwork.target
ymysql.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 directivaGroup
. En nuestro caso el script del demonio se ejecutara bajo el usuariowww-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.