info docker

Docker Exit Code 0 - Success

Understanding Docker exit code 0 - the container's main process completed successfully and exited normally.

What It Means

Docker exit code 0 indicates that the container’s main process (PID 1) terminated successfully. This means the command specified in the CMD or ENTRYPOINT instruction completed its work and exited normally.

For short-lived containers (batch jobs, init containers, one-off tasks), exit code 0 is the expected outcome. For long-running services, an exit code 0 means the process shut down gracefully.

Common Causes

  • Container completed its task (batch job, migration, build)
  • Main process received SIGTERM and shut down gracefully
  • Script ran to completion and exited
  • Init container finished its setup tasks
  • One-shot command completed (e.g., docker run alpine echo "hello")

How to Fix

Exit code 0 means success, so there is nothing to fix. However, if your container is exiting with 0 when it should keep running:

Keep a container running

# Bad: container exits immediately after the command finishes
CMD echo "starting up"

# Good: run a long-lived process
CMD ["node", "server.js"]
CMD ["python", "-m", "flask", "run", "--host=0.0.0.0"]
CMD ["nginx", "-g", "daemon off;"]

Check container exit code

# Check exit code of a stopped container
docker inspect <container-id> --format='{{.State.ExitCode}}'

# See all stopped containers and their exit codes
docker ps -a --filter "status=exited"

# Check container logs before it exited
docker logs <container-id>

Docker Compose restart policy

services:
  worker:
    image: my-worker
    restart: "no"           # Don't restart after clean exit
    # restart: "on-failure" # Only restart on non-zero exit
    # restart: "always"     # Always restart, even on exit 0

Kubernetes: Handle completed containers

# Use a Job for tasks that should complete
apiVersion: batch/v1
kind: Job
metadata:
  name: data-migration
spec:
  template:
    spec:
      containers:
        - name: migrate
          image: my-app
          command: ["python", "manage.py", "migrate"]
      restartPolicy: Never
  backoffLimit: 3