Docker-container start niet of crasht direct
Een container die niet start, geeft in de logs en de exit code bijna altijd genoeg informatie. Het probleem is dat Docker die informatie niet opdringt: je moet ernaar vragen, en dan is het meestal binnen een paar minuten duidelijk.
Loop je hier nu tegenaan?
Bel of mail en leg het voor. Neem ik niet op, stuur dan even een mail.
Herken je dit?
- De container start en stopt onmiddellijk weer.
- Er staat een exit code als 1, 125, 137 of 143.
- Na een update of <code>compose up</code> is de data in de container verdwenen.
- Containers kunnen elkaar niet bereiken op naam.
- Na een image-update werkt het niet meer terwijl niets anders wijzigde.
Waar het meestal aan ligt
In verreweg de meeste gevallen is het één van deze. Loop ze in deze volgorde na.
Exit 137: het proces kreeg een SIGKILL
Vaak geheugen: de OOM-killer of een mem_limit die te laag staat. Het kan ook een docker stop zijn waarbij het proces SIGTERM negeerde en na tien seconden hard werd gestopt. docker inspect -f '{{.State.OOMKilled}}' vertelt welke van de twee.
Exit 125: Docker zelf kan de container niet starten
Een fout in de opdracht of configuratie: een poort die al in gebruik is, een onbekende optie, een image dat niet bestaat. docker run geeft dan 125 en de container blijft op Created staan. Dit is geen applicatiefout.
Het entrypoint eindigt gewoon
Een container leeft zolang het hoofdproces leeft. Een commando dat klaar is, of een dienst die zichzelf naar de achtergrond stuurt, betekent een container die netjes stopt met exit 0.
Data in de container in plaats van in een volume
Zonder volume is alles wat de applicatie schrijft weg bij een docker compose up met een nieuw image. Dat voelt als dataverlies en is een configuratiekeuze.
Netwerken en naamresolutie
Containers vinden elkaar op servicenaam binnen hetzelfde Compose-netwerk. Staan ze in verschillende netwerken of wordt localhost gebruikt, dan is er geen verbinding.
Ontbrekende of verkeerde environment-variabelen
Een ontbrekende databasewachtwoord-variabele of een .env die niet wordt ingelezen, geeft een applicatie die bij het opstarten afbreekt. De log zegt dat meestal letterlijk.
Wat ik als eerste check
Doe deze stappen zelf, of bel en dan lopen we ze samen door.
- 1
Lees de logs van de container
docker logs --tail 100 <naam>, ook (en juist) van een container die al gestopt is. Daar staat in de meeste gevallen de daadwerkelijke foutmelding. - 2
Kijk naar de exit code
docker ps -alaat de exit status zien. 137 is een SIGKILL, 1 is de applicatie, 143 is een nette stop, 126 en 127 betekenen dat het commando niet uitvoerbaar is of niet bestaat. Staat hij op Created, dan kreeg Docker hem niet eens gestart: kijk dan naar de foutmelding vandocker runofcompose up. - 3
Controleer geheugen en limieten
docker statstijdens het starten endmesg -T | grep -i oomerna. Was exit 137 geheugen, dan zie je het hier terug. - 4
Controleer poorten en paden
ss -tlnpvoor poorten die al in gebruik zijn, Bij exit 125 is dit het eerste dat je uitsluit. Kijk ook of elk hostpad in je volumes bestaat. Zo niet, dan maakt Docker het gewoon aan, leeg en van root, en dat geeft weer een eigen soort ellende. - 5
Test de configuratie los
docker compose configlaat zien wat Docker daadwerkelijk leest, inclusief de ingevulde variabelen. Verrassend vaak blijkt daar dat een.envniet wordt meegenomen. - 6
Test de verbinding tussen containers van binnenuit
docker compose exec app ping dbof eencurlnaar de servicenaam. Dat scheidt een netwerkprobleem van een applicatieprobleem.
Containers zijn eerlijk, als je het vraagt
Het verschil tussen frustratie en een snelle oplossing is bij Docker meestal één commando: docker logs op de gestopte container. Omdat een container verdwijnt uit docker ps zodra hij stopt, denken mensen dat de informatie weg is. Dat is niet zo — docker ps -a en docker logs werken prima op een dode container.
De tweede grote categorie is data. Een container is per definitie vervangbaar; alles wat je wilt bewaren, moet in een benoemd volume of in een database daarbuiten staan. Dat is geen detail maar het uitgangspunt.
Veelgestelde vragen
- Wat betekent exit code 137?
- Dat het proces een SIGKILL kreeg. Meestal van de OOM-killer omdat het geheugen op was, op de host of binnen de limiet van de container. Het kan ook een stop zijn waarbij het proces SIGTERM negeerde. Kijk naar
OOMKilledindocker inspect. Was het geheugen, verhoog dan de limiet of zoek uit waar het geheugen heen gaat. Herstarten in een lus helpt niet. - Mijn data is weg na een update. Kan ik dat terughalen?
- Soms: als de oude container of het anonieme volume nog bestaat, is het te redden. Doe dan eerst niets meer met docker system prune. Daarna is de echte les om benoemde volumes te gebruiken, want zonder volume is dataverlies bij een image-update onvermijdelijk.
- Waarom kan mijn applicatie de database niet vinden op localhost?
- Omdat localhost binnen een container naar die container zelf verwijst, niet naar de host of naar een andere container. Binnen Compose gebruik je de servicenaam als hostname. Dat is de meest gemaakte fout bij de eerste containerisatie.
- Kun je helpen met een productie-opzet die een herstart overleeft?
- Ja: benoemde volumes, restart-policies, healthchecks, logrotatie, back-ups van de volumes en een update die je durft te doen. Daar kan je jaren op bouwen.
Verwante problemen
502 Bad Gateway bij nginx oplossen
502 Bad Gateway betekent dat nginx je applicatie niet kan bereiken of geen geldig antwoord krijgt. Dit zijn de oorzaken en de eerste checks.
[Boot en recovery]Server start niet meer op
Een server die na een update of herstart niet meer boot: kernel, fstab, volle schijf of bootloader. Zo kom je via rescue mode weer binnen.
[MySQL-replicatie]MySQL-replicatie is gestopt of loopt achter
Replicatie gestopt met een foutmelding, of een slave die steeds verder achterloopt. Meestal te repareren zonder volledige rebuild. Dit check ik als eerste.
Wil je dit bespreken?
Bel of mail met je vraag. Neem ik niet op, stuur dan even een mail.
Terug naar Linux-serverbeheer en hosting