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

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:

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}}"

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:

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:

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.