service nginx start) or a CMD that returns instantly. Run docker ps -a to read the exit code (0 = clean exit / missing foreground · 1 = app error · 137 = OOM kill · 127 = command not found), then fix CMD to a foreground form like CMD ["nginx","-g","daemon off;"]. If logs are empty, debug with docker run -it --entrypoint sh your-image.If your Docker container runs docker run and dies within seconds (status "Exited (0)" or "Exited (1)"), it's almost always one of four root causes. Here's the exact diagnostic flow I run on client machines in San Diego.
docker logs <container_id> immediately after exit. 80% of the time the error message (missing binary, permission denied, port in use) is printed on the last line. Use docker ps -a to get the ID of the dead container.service nginx start or a backgrounded process, swap it for nginx -g "daemon off;" or run CMD ["node","server.js"] directly — no &, no nohup.-it flags for interactive shells (docker run -it ubuntu bash). Without -t allocating a pseudo-TTY and -i keeping STDIN open, shells like bash see no terminal and exit with code 0 instantly.docker run -it --entrypoint sh your-image. This skips the broken CMD so you can inspect the filesystem, check for missing files, test your startup script manually, and see the real error.Run docker ps -a. Look at the STATUS column:
Exited (0) → process finished normally (often missing foreground) Exited (1) → app threw an error — read logs Exited (125)→ Docker daemon failed Exited (126)→ command not executable (chmod +x missing) Exited (127)→ command not found (typo or wrong PATH) Exited (137)→ OOM killed — raise memory limit
Exit code tells you which branch of the fix to take before you even read logs.
Every exited container leaves logs behind until you docker rm it:
docker logs --tail 50 <id> docker logs --timestamps <id>
Common culprits you'll see: EADDRINUSE (port conflict), MODULE_NOT_FOUND (bad COPY path), permission denied (entrypoint script not executable), or silent empty output (foreground problem — see step 3).
Most common cause. A container lives exactly as long as PID 1 lives. Bad Dockerfile:
CMD service apache2 start
Apache forks to background, CMD returns, container dies. Fix:
CMD ["apache2ctl","-D","FOREGROUND"] # or for nginx: CMD ["nginx","-g","daemon off;"] # or python: CMD ["python","-u","app.py"]
When logs don't reveal it, crack the image open:
docker run -it --entrypoint sh myimage # inside: ls -la /app cat /entrypoint.sh which node echo $PATH
This bypasses your CMD entirely. You can manually run your startup command and watch it fail in real time. Also check line endings — \r\n in entrypoint scripts (Windows → Linux) causes silent death. Run dos2unix entrypoint.sh.
docker logsIf you built the image on Windows and your entrypoint.sh has CRLF line endings, Linux tries to execute /bin/bash\r — which doesn't exist. Container exits 127 with a cryptic "no such file" error even though the file is right there.
RUN sed -i 's/\r$//' /entrypoint.sh \ && chmod +x /entrypoint.sh
If your compose file has restart: always, the container will crash-loop and you'll see it in docker ps looking alive. Run docker compose logs --tail 100 service_name to see the repeated startup failures. Temporarily set restart: "no" while debugging.
What does exit code 0 vs 1 mean?
Exit 0 = process finished cleanly (often because PID 1 backgrounded itself — Docker had nothing to keep alive). Exit 1 = app threw an uncaught error and crashed; check docker logs for the trace.
What does exit 137 mean?
SIGKILL — almost always OOM. Raise the limit with docker run --memory=2g, or check Docker Desktop → Resources → Memory (default 2GB caps Node/JVM workloads).
What does exit 127 mean?
Command not found. Three causes: typo in CMD, missing binary in image (alpine lacks bash by default), or CRLF line endings in entrypoint.sh making Linux look for /bin/bash\r. Fix with RUN sed -i 's/\r$//' /entrypoint.sh.
ENTRYPOINT vs CMD — which to use?
ENTRYPOINT = the binary that always runs. CMD = default args (overridable at run-time). For single-purpose containers, ENTRYPOINT ["node","server.js"] is cleanest. CMD-only is a common cause of "exits immediately" because docker run image arg1 replaces the whole CMD.
How do I keep PID 1 in foreground?
Never use service start, systemctl, or backgrounding. Use daemon-off forms: CMD ["nginx","-g","daemon off;"], CMD ["apache2ctl","-D","FOREGROUND"], or CMD ["python","-u","app.py"] (-u streams logs live). For interactive testing only: tail -f /dev/null.
I've debugged this exact issue on dozens of client containers — usually it's the foreground/PID 1 thing and takes 5 minutes to fix once you read the exit code. Text me your docker ps -a output and I'll tell you which branch to take.
Don't see what you were looking for?
Text PJ a sentence about what you actually need — I'll build you a free custom shareable on the house. No email, no funnel, no SOW.
📲 Text PJ — free shareable