
Planeo alojar varias instancias de la misma aplicación web para clientes que usan systemd
. Me gustaría poder stop
utilizar start
cada instancia de cliente systemd
, así como tratar toda la colección de instancias de cliente como un único servicio que se puede detener e iniciar juntos.
systemd
Parece proporcionar los componentes básicos que necesito para usar PartOf
y los archivos unitarios de plantilla, pero detuve el servicio principal, el servicio al cliente secundario no se detiene. ¿Cómo puedo hacer que esto funcione con systemd? Esto es lo que tengo hasta ahora.
El archivo de la unidad de padres app.service
:
[Unit]
Description=App Web Service
[Service]
# Don't run as a deamon (because we've got nothing to do directly)
Type=oneshot
# Just print something, because ExecStart is required
ExecStart=/bin/echo "App Service exists only to collectively start and stop App instances"
# Keep running after Exit start finished, because we want the instances that depend on this to keep running
RemainAfterExit=yes
StandardOutput=journal
Un archivo de plantilla de unidad denominado [email protected]
, que se utiliza para crear instancias de clientes:
[Unit]
Description=%I Instance of App Web Service
[Service]
PartOf=app.service
ExecStart=/home/mark/bin/app-poc.sh %i
StandardOutput=journal
Mi app-poc.sh
script (prueba de concepto que simplemente se imprime en el archivo de registro en un bucle):
#!/bin/bash
# Just a temporary code to fake a full daemon.
while :
do
echo "The App PoC loop for $@"
sleep 2;
done
Para la prueba de concepto, tengo los archivos de la unidad systemd en formato ~/.config/systemd/user
.
Luego inicio el padre y una instancia basada en la plantilla (después systemctl --user daemon-reload
):
systemctl --user start app
systemctl --user start [email protected]
Desde el uso journalctl -f
puedo ver que ambos comenzaron y que la instancia del cliente continúa ejecutándose. Ahora espero que apagar al padre detenga al niño (porque uséPartOf
), pero no es así. Además, iniciar al padre tampoco inicia al hijo como se esperaba.
systemctl --user stop app
¡Gracias!
(Estoy usando Ubuntu 16.04 con systemd 229).
Respuesta1
Aprendí que para eso sirven las "Unidades de destino" de systemd. Al utilizar una Unidad objetivo, obtengo los beneficios que deseo sin necesidad de crear la [Service]
sección falsa que tenía arriba. Un archivo de ejemplo funcional de "Unidad de destino" se ve así:
# named like app.target
[Unit]
Description=App Web Service
# This collection of apps should be started at boot time.
[Install]
WantedBy=multi-user.target
Luego, cada instancia de cliente debe incluirse PartOf
en la [Unit]
sección (como lo señala @meuh), y también debe tener una [Install]
sección para que enable
funcione disable
en el servicio específico:
# In a file name like [email protected]
[Unit]
Description=%I Instance of App Web Service
PartOf=app.target
[Service]
ExecStart=/home/mark/bin/app-poc.sh %i
Restart=on-failure
StandardOutput=journal
# When the service runs globally, make it run as a particular user for added security
#User=myapp
#Group=myapp
# When systemctl enable is used, make this start when the App service starts
[Install]
WantedBy=app.target
Para abrir la instancia del cliente y hacer que se inicie cuando se inicia el destino, se utiliza este comando de habilitación único:
systemctl enable app
Ahora, en este punto, puedo usar stop
y start
para app@customer
una instancia específica, o puedo usar start app
y stop app
para detener todas las aplicaciones juntas.
Respuesta2
Necesitas mover la línea
PartOf=app.service
fuera [Service]
y dentro de la [Unit]
sección, y agregue a la [Unit]
lista app.service
de clientes para comenzar, por ejemplo
[email protected] [email protected]
o como dijo sourcejedi en los comentarios, Requires=
lo mismo. Puedes conservar los PartOf
servicios que inicias manualmente y que no están en la lista anterior, como .systemctl --user start [email protected]