Vai al contenuto

Ciclo di vita di uno stack

Traduzione automatica dell'originale francese.

Creazione

  1. Creare 10-stacks/<nom>/ nel vault, con README.md e decisions.md.
  2. Scrivere /opt/docker/<nom>/docker-compose.yml sull'host, secondo le convenzioni.
  3. Validare: docker compose -f /opt/docker/<nom>/docker-compose.yml config.
  4. Avviare: docker compose -f /opt/docker/<nom>/docker-compose.yml up -d.
  5. Se il servizio è esposto su internet → Pubblicare un nuovo servizio.
  6. Su vm-docker e vm-compute-01, registrare lo stack in /opt/docker/scripts/stack-waves.conf — altrimenti scompare al primo riavvio (vedi sotto).
  7. Commitare il vault e pushare sui due repository remoti.

Modifica

Oguna modifica alla configurazione è accompagnata, immediatamente, da un'entrata datata in 10-stacks/<nom>/decisions.md: cosa è cambiato, perché e come tornare indietro.

Non si tratta di burocrazia. È il solo canale che tutte le sessioni di lavoro consultano: un messaggio inviato verbalmente o una nota in memoria hanno ciascuno un modo di fallimento silenzioso, decisions.md non ne ha.

Avvio all'avvio

Su vm-docker e vm-compute-01, i servizi dichiarano restart: on-failure:5, mai always.

docker-staggered.service è l'unica autorità di avvio all'avvio. Legge /opt/docker/scripts/stack-waves.conf, monta i progetti a ondate e attende tra ogni ondata.

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

Perché esiste questa meccanica:

  • su vm-compute-01, il punto di conflitto è il blocco xtables — ogni implementazione di regole iptables richiede da 20 a 28 secondi, e dockerd si blocca per più di dieci minuti;
  • su vm-docker, è l'attesa di I/O — 80 container su un disco virtuale con ~1,4 ms per ogni lettura casuale fanno salire il carico 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 copre solo la branca sinistra. La branca destra non ha alcun meccanismo automatico: è il file delle ondate, e solo quello.

Uno stack assente da stack-waves.conf non si riavvia, e nessuno lo segnala

È la conseguenza diretta di on-failure:5: un container arrestato correttamente (codice 0) non viene riavviato da Docker. Oppure, è esattamente ciò che fa staggered-stop prima del riavvio dell'host: un arresto pulito.

Se il progetto non è presente in stack-waves.conf, nessuno lo riavvia all'avvio. Il container rimane exited con ExitCode=0, RestartCount=0, senza errori nei log, senza avvisi: non ha smesso di funzionare, è stato spento e non è mai stato riavviato.

Questo è accaduto il 2026-08-30 su homelab-docs, messo in servizio la sera precedente e assente dal file: arresto pulito alle 01:45 durante il riavvio notturno di patching, scomparso fino a quando non lo si cercava. Il vhost Caddy, invece, continuava a rispondere — con codice 502.

Il controllo, dopo l'avvio:

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

Verificare che un container rispetti effettivamente la politica dichiarata

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

Da confrontare con restart: nel file Compose. Una discrepanza significa che un up -d --force-recreate ha riattivato la vecchia politica.

Diagnosticare

Ordine di lettura, dal meno costoso al più costoso:

  1. docker ps — il container è in esecuzione, e da quanto tempo?
  2. RestartCount — si riavvia in loop?
  3. docker logs --since 1h — cosa dice di sé?
  4. Stato di salute — ma vedere l'avviso qui sotto.
  5. Rete, volumi, memoria.

healthy non significa "il servizio funziona"

Lo stato di salute è ciò che l'immagine ha scelto di testare, niente di più. Alcuni casi reali riscontrati qui: una porta chiusa mentre il container è healthy, un servizio secondario inattivo senza effetti sulla sonda, un interval di 15 minuti che rende lo stato inutile in caso di problemi.

Conseguenza per la supervisione: fallire su unhealthy, mai su starting.

Una sonda può misurare anche altro che il servizio

Un servizio a singolo processo che scrive lo stato su disco in modo sincronizzato blocca la sua sequenza di eventi durante la scrittura – 20-30 secondi per un grafo di 45.000 nodi. La sonda si disconnette, ma il contenitore non è mai stato riavviato. La risposta è da attribuire al sistema di supervisione (tempo più lungo, soglia di errori consecutivi), non al servizio stesso.

Disattivare

  1. Arrestare e rimuovere docker compose -f /opt/docker/<nom>/docker-compose.yml down.
  2. Rimuovere il blocco dal file Caddy, da entrambi i Caddy se il servizio è pubblico.
  3. Rimuovere il nome del dominio dall'elenco di emissione dei certificati.
  4. Rimuovere l'entrata stack-waves.conf dagli host orchestrati.
  5. Archivare la cartella del vault invece di eliminarla, e chiudere decisions.md con una voce datata.

Un nome pubblicato all'edge con un certificato valido è una porta che aspetta

Lasciare il blocco Caddy in posizione dopo aver arrestato il contenitore non "fa nulla": quando qualcuno avvia un contenitore con lo stesso nome del servizio, diventa immediatamente pubblico, senza dover passare attraverso una revisione. Alcuni blocchi sono stati rimossi per questo motivo esatto durante l'audit della superficie pubblica del 22-07-2026.

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