Cómo configurar el reinicio automático de Contenedores Docker en tu servidor local

Actualizada:

Estamos viendo cómo montar tu propio servidor local con un mini PC y ya hemos descubierto que nos tenemos que deshacer cuanto antes de Windows y tenemos que empezar a usar Linux Mint y Docker. Antes de ponernos a instalar apps con Docker, tenemos que tener claro una cosa importante: tus contenedores tienen que estar siempre en funcionamiento online, y cuando se produzca un problema o un reinicio del servidor, tienes que comenzar automáticamente.

Te cuento que tienes que buscar en archivos de configuración en Docker para asegurarte de que se reinicien automáticamente, y luego te cuento cómo reiniciar los contenedores unhealthy.

Cuando se reinician automáticamente tus contenedores en Docker

En Portainer podemos ver si los contenedores Docker están funcionando bien.

Esto viene bien explicado en: docs.docker.com/engine/containers/start-containers-automatically. En tu archivo de configuración para Docker Compose tienes que buscar la línea que tenga restart y uno de estos valores:

  • on-failure[:max-retries]: Reinicia el contenedor si este termina debido a un error. Puedes limitar el número de veces que el demonio de Docker intenta reiniciar el contenedor usando la opción :max-retries. La política on-failure solo provoca un reinicio si el contenedor termina con un fallo. No reinicia el contenedor si se reinicia el demonio.
  • always: Siempre reinicia el contenedor si se detiene. Si se detiene manualmente, solo se reinicia cuando se reinicia el demonio de Docker o cuando el contenedor se reinicia manualmente.
  • unless-stopped: Similar a always, excepto que cuando el contenedor se detiene (manualmente o de otra forma), no se reinicia ni siquiera después de reiniciar el demonio de Docker.

En nuestro caso, que vamos a instalar cosas como Immich, Jellyfin, Komga, Calibre-web o FreshRSS, la que más nos interesa es unless-stopped: quieres que los contenedores se reinicien automáticamente si el servidor (o Docker) se reinicia, pero no quieres que Docker intente reiniciar los contenedores si los detienes manualmente para mantenimiento.

Vamos, que te recomiendo que en tus contenedores pongas: restart: unless-stopped, como, por ejemplo, en este archivo de configuración de Docker Compose para Calibre-web:

Docker Compose para Calibre web con política de reinicio restart: unless-stopped para nuestro servidor local en un mini PC

Puedes aplicar el cambio cambiando tu archivo de configuración para cada stack en Portainer o cambiarlos mediante estar orden en el terminal uno a uno (por ejemplo, para un contenedor que se llama Jellyfin):

docker run -d --restart unless-stopped Jellyfin

O para todos en un solo comando:

docker update --restart unless-stopped $(docker ps -q)

Vale, ya estamos cubiertos para todos los horrores que se te puedan pasar por la cabeza con nuestro servidor local excepto para uno. ¿Qué pasa si Docker marca el contendor como unhealthy (no pasa una serie de cheqeuos)? Pues que esta política de reinicio no nos va a ayudar. Tenemos que hacer otra cosa.

Reinicio automático de un contenedor Docker Unhealthy o Exited (128)

Mucha gente crea un contenedor que vigila a los demás, tal y como te cuentan en github.com/willfarrell/docker-autoheal, pero yo prefiero crear un script en Linux y gestionarlo con el cron del sistema para que vigile esos contenedores unhealthy o con el código Exited (128).

Desde Docker ofrecen una buena explicación de cuándo se declara un contenedor unhealthy: docs.docker.com/reference/dockerfile/#healthcheck y cómo funciona el comando Healthcheck para comprobarlo (por si tienes problemas graves y el contenedor no se levanta de ninguna manera).

Pero lo que yo quiero conseguir es que se compruebe cada cierto tiempo que todos los contenedores están funcionando en mi servidor local. Para ello, voy a crear un script que revisará cada 5 minutos si todos los contendores funcionan y en caso de que alguno falle y esté marcado como unhealthy o Exited (128), lo reinicie automáticamente. Estos son los pasos para Linux.

1.- Usuario con permisos en Docker.

Nos aseguramos que nuestro usuario de Linux, en mi caso ivan, está en el grupo Docker.

sudo usermod -aG docker ivan

Reiniciamos el mini PC y comprobamos que está en ese grupo con:

getent group docker

Creamos el script con el editor nano (ponlo en tu carpeta home en una carpeta llamada scripts para tenerlo todo controlado):

sudo nano restart-unhealthy-docker.sh

En ese archivo ponemos lo siguiente:

#!/bin/bash

# Reiniciar contenedores unhealthy
for container_id in $(docker ps -q -f health=unhealthy); do
    docker restart "$container_id" >/dev/null 2>&1
done

# Reiniciar contenedores Exited con error (exit code != 0)
for container_id in $(docker ps -a -q -f status=exited); do
    exit_code=$(docker inspect --format='{{.State.ExitCode}}' "$container_id")
    if [ "$exit_code" -ne 0 ]; then
        docker restart "$container_id" >/dev/null 2>&1
    fi
done

No dejamos que salga nada con /dev/null 2>&1. Damos permisos de ejecución al archivo:

sudo chmod +x restart-unhealthy-docker.sh

Lo ponemos en ejecución cada 5 minutos (o 10 o 15 min, según tus necesidades) con el crontab:

crontab -e

Ponemos:

*/5 * * * * /home/ivan/scripts/restart-unhealthy-docker.sh > /dev/null 2>&1

Y guardamos. En principio no queremos guardar logs de resultados, por eso pongo /dev/null 2>&1.

Puedes comprobar en Docker cuánto tiempo llevan activos los contenedores con:

docker ps --format "table {{.Names}}\t{{.Status}}"
Comprobamos en Docker qué contenedores tenemos up y si están Healthy: perfecto para que todo funcione bien en nuestro servidor local.

Como puedes ver en algunos Healthy y en otros no pone nada, solo que están Up. ¿Por qué? Solo los que tienen configurada la opción HEALTHCHECK (en su Dockerfile o por ti en docker-compose.yml), podrán darte ese estado y marcar el contenedor como:

  • (starting): mientras espera resultado en el arranque
  • (healthy): sí responde bien
  • (unhealthy): sí falla
  • Nota: muchas imágenes de contenedores ya incluyen esta comprobación en su interior sin que esté puesta de manera expresa en docker-compose.yml

Configuración de Healthcheck en tus contenedores

¿Moraleja? Solo los que tengan configurada la opción de Healthcheck están cubiertos con el script anterior. Deberías de poner tú mismo en el resto de archivos de configuración de Docker el comando healthcheck. ¿Un ejemplo? Fíjate en la imagen que teníamos antes de la configuración de Calibre-web (sin healthcheck). Deberías añadir algo así al final:

healthcheck:
      test: ["CMD", "curl", "-fsS", "http://localhost:8083"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 30s

Vete probando y comprueba qué es lo que mejor funciona para ti.

Opcional: configuramos Uptime Kuma para saber si los contenedores están funcionando

Puedes configurar fácilmente Uptime Kuma en un contenedor de tu Docker. Es un programa que va a mandar un saludo a tus contenedores para ver si responde bien o mal, es decir, si están funcionando o están caídos. Desde la línea de comandos, puedes poner lo siguiente:

docker run -d --restart=unless-stopped -p 3001:3001 -v uptime-kuma:/app/data --name uptime-kuma louislam/uptime-kuma:1

Puedes cambiar el puerto si lo tienes ocupado y el directorio donde guardas los datos.

O puedes poner esto directamente en Portainer creando un stack:

version: "3.8"

services:
  uptime-kuma:
    image: louislam/uptime-kuma:latest
    container_name: uptime-kuma
    restart: unless-stopped
    ports:
      - "3001:3001"
    volumes:
      - /home/ivan/docker/uptimekuma:/app/data

Donde, como puedes ver, he cambiado la ruta donde están localizados los datos del contendor.

Ya puedes acceder a su panel de control (http://IP-servidor:3001) y añadir un nuevo monitor:

Configuramos un monitor en Uptime Kuma para vigilar nuestros Container en Docker.

Solo tienes que poner:

  • Nombre sencillo: Jellyfin (por ejemplo)
  • URL: http://ip-servicio:8096
  • Intervalo: he puesto cada 300 segundos.
  • Reintentos: 3

Y empezarás a ver algo como esto:

Configuramos un monitor en Uptime Kuma para vigilar nuestros Container en Docker.

Puedes hasta configurar notificaciones con Gotify, Telegram y muchos otros servicios. Con Gotify solo tienes que generar una API de cliente, poner la url del servidor y agregar la notificación a tu monitor. Si un servidor se cae, te llegará un aviso.

Conclusión

Con ambas opciones en Docker ya has cubierto todos los casos importantes para reiniciar siempre tus contendores en tu servidor local:

  • Se reinicia si el proceso muere (ponemos restart: unless-stopped en la configuración del stack).
  • Se reinicia si el healthcheck falla (con el script creado).

Ahora ya estamos listos para instalar el resto de aplicaciones en nuestro Mini PC con Docker.


Descubre más desde Gouforit.com

Suscríbete y recibe las últimas entradas en tu correo electrónico.

Foto del autor

Ivan Benito

Apasionado de la física, la lectura y los viajes, experto en tecnología e informática y fan de los relojes Casio, de los Mac y de los auriculares Sennheiser. Desde el año 2007 me he dedicado a escribir y a crear páginas web donde comparto mis conocimientos y reviews de productos. Si tienes alguna duda y necesitas ayuda... ¡Pregúntame!

Si quieres estar al tanto de los mejores productos tecnológicos del año, no te puedes perder nuestras comparativas, opiniones y análisis de dispositivos tecnológicos. ¡No te los pierdas! Gouforit es soportado por sus lectores. El equipo de editores solo selecciona las mejores opciones mediante reviews independientes. Algunos enlaces del artículo son afiliados: pueden generar un beneficio a Gouforit. Este sitio solo proporciona reseñas; no vendemos productos directamente. Saber más.

Deja un comentario

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.