Saltar a contenido

Ciclo de vida de un stack

Traducción automática del original francés.

Crear

  1. Crear 10-stacks/<nom>/ en el vault, con README.md y decisions.md.
  2. Escribir /opt/docker/<nom>/docker-compose.yml en el host, según las normas.
  3. Validar: docker compose -f /opt/docker/<nom>/docker-compose.yml config.
  4. Iniciar: docker compose -f /opt/docker/<nom>/docker-compose.yml up -d.
  5. Si el servicio está expuesto en la web → Publicar un nuevo servicio.
  6. En vm-docker y vm-compute-01, registrar el stack en /opt/docker/scripts/stack-waves.conf — de lo contrario, desaparece al primer reinicio (ver más abajo).
  7. Confirmar el vault y subir a los dos repositorios remotos.

Modificar

Cualquier modificación de configuración se acompaña, inmediatamente, de una entrada fechada en 10-stacks/<nom>/decisions.md: lo que ha cambiado, por qué, y cómo volver atrás.

No es burocracia. Es el único canal que todas las sesiones de trabajo revisan: un mensaje enviado en voz alta o una nota en memoria tienen cada uno un modo de fallo silencioso, decisions.md no tiene ninguno.

Inicio al arrancar

En vm-docker y vm-compute-01, los servicios declaran restart: on-failure:5, nunca always.

docker-staggered.service es la única autoridad de inicio al arrancar. Lee /opt/docker/scripts/stack-waves.conf, monta los proyectos por fases y espera entre cada uno.

sequenceDiagram
    autonumber
    participant S as systemd
    participant D as dockerd
    participant G as docker-staggered
    participant C as conteneurs

    S->>D: docker.service
    D-->>S: prêt
    S->>G: After=docker.service
    loop vagues 0 à 5, 15 s d'écart
        G->>C: compose up -d (projets de la vague)
    end
    Note over S,G: à l'arrêt, l'ordre s'inverse :<br/>staggered-stop tourne PENDANT que dockerd est encore debout

¿Por qué existe esta mecánica?

  • En vm-compute-01, el punto de conflicto es el bloqueo xtables: cada aplicación de iptables tarda entre 20 y 28 segundos, y dockerd se bloquea durante más de diez minutos;
  • En vm-docker, es la espera de E/S: 80 contenedores en un disco virtual con ~1,4 ms por lectura aleatoria elevan la carga a 85.
stateDiagram-v2
    [*] --> running: compose up -d
    running --> crash: le processus meurt<br/>(exit ≠ 0)
    crash --> running: on-failure:5 relance
    crash --> abandonne: 5 échecs d'affilée

    running --> arrete: staggered-stop<br/>(exit 0, arrêt PROPRE)
    arrete --> running: docker-staggered au boot,<br/>SI le projet est dans stack-waves.conf
    arrete --> oublie: sinon, personne ne le rallume

    note right of oublie
        exited · ExitCode=0 · RestartCount=0
        aucune erreur, aucune alerte
        et le vhost Caddy répond en 502
    end note

on-failure:5 solo cubre la rama izquierda. La rama derecha no tiene ningún control automático: es el archivo de fases, y nada más.

Un stack ausente de stack-waves.conf no se activa, y nadie lo señala

Es el resultado directo de on-failure:5: un contenedor detenido correctamente (código 0) no se reinicia por Docker. O, más bien, es exactamente lo que hace staggered-stop antes de reiniciar el host: un apagado limpio.

Si el proyecto no está en stack-waves.conf, nadie lo enciende al arrancar. El contenedor permanece en exited con ExitCode=0, RestartCount=0, sin errores en los registros, sin alertas: no ha fallado, se ha apagado y nunca se ha vuelto a encender.

Esto ocurrió el 30 de agosto de 2026 en homelab-docs, se puso en funcionamiento la noche anterior y desapareció del archivo: apagado limpio a las 01:45 durante el reinicio nocturno de parches, hasta que lo buscamos. El vhost de Caddy, en cambio, seguía respondiendo (en 502).

La comprobación, después de la puesta en funcionamiento:

grep -c '<nom-du-projet>' /opt/docker/scripts/stack-waves.conf   # doit rendre 1

Verificar que un contenedor respete la política declarada

docker inspect <conteneur> \
  --format '{{.HostConfig.RestartPolicy.Name}}:{{.HostConfig.RestartPolicy.MaximumRetryCount}}'

Para compararlo con restart: del archivo Compose. Una discrepancia significa que un up -d --force-recreate ha rearmado la política anterior.

Diagnosticar

Orden de lectura, del más barato al más caro:

  1. docker ps — ¿el contenedor está funcionando y desde cuándo?
  2. RestartCount — ¿se está reiniciando en bucle?
  3. docker logs --since 1h — ¿qué dice él mismo?
  4. Estado de salud — pero ver la advertencia a continuación.
  5. Red, volúmenes, memoria.

healthy no significa «el servicio está funcionando»

El estado de salud es lo que la imagen ha elegido probar, nada más. Casos reales encontrados aquí: un puerto cerrado aunque el contenedor está healthy, un servicio secundario muerto sin afectar a la sonda, un interval de 15 minutos que hace que el estado sea inútil en caso de fallo.

Consecuencia para la supervisión: fallar en unhealthy, nunca en starting.

Una sonda puede medir algo más que el servicio

Un servicio de un solo proceso que escribe su estado en disco de forma sincronizada bloquea su bucle de eventos durante la escritura — de 20 a 30 segundos para un grafo de 45.000 nodos. La sonda se desconecta, pero el contenedor nunca se ha reiniciado. La respuesta está en el lado de la supervisión (tiempo más largo, umbral de fallos consecutivos), no en el lado del servicio.

Desactivar

  1. Detener y retirar: docker compose -f /opt/docker/<nom>/docker-compose.yml down.
  2. Retirar el bloque del archivo Caddyfile, de ambos Caddy si el servicio es público.
  3. Retirar el nombre del dominio de la lista de emisión de certificados.
  4. Retirar la entrada stack-waves.conf de los hosts orquestados.
  5. Archivar la carpeta del vault en lugar de eliminarla, y cerrar decisions.md con una entrada fechada.

Un nombre publicado en el borde con un certificado válido es una puerta que espera

Dejar el bloque de Caddy en su lugar después de detener el contenedor no "hace nada": cuando alguien inicia un contenedor con el mismo nombre de servicio, se vuelve público instantáneamente, sin necesidad de pasar por una revisión. Se han retirado bloques por esta misma razón durante la auditoría de la superficie pública del 22 de julio de 2026.

Dernière vérification de cette page : 2026-08-30