Common Issues

Docker Container Exits Immediately

Diagnose and fix Docker containers that start and immediately stop, common causes and solutions

A Docker container that starts and immediately exits is one of the most common issues. The cause is almost always an error in the main process (PID 1) or incorrect configuration.


Initial Diagnosis

Check Container Status

View all containers including stopped ones:

docker ps -a

Look for containers with status Exited (X) where X is the exit code.

View Container Logs

This is the first step, 90% of issues are visible here:

# Last 50 lines
docker logs --tail 50 container_name

# Follow logs in real-time (use before restarting)
docker logs -f container_name

# Timestamp logs
docker logs --timestamps container_name

Check Exit Code

docker inspect container_name --format='{{.State.ExitCode}}'

Exit Code Reference

Exit CodeMeaningCommon Cause
0Process terminated normallyApplication exited normally (not a daemon)
1General errorApplication error, check logs
125Docker daemon errorDocker runtime issue
126Command not executableEntrypoint not executable, permission denied
127Command not foundBinary missing or wrong path
137SIGKILLOut of Memory (OOM), or docker kill
143SIGTERMGraceful shutdown, or docker stop

Cause 1: Process is Not a Daemon (Exit 0)

A container exits when its main process terminates. If your application runs and then stops, the container stops.

Example: Nginx Without Foreground Mode

# Wrong: container exits immediately
docker run nginx

# Correct: run in detached mode
docker run -d nginx

# Or ensure the app runs in foreground
docker run nginx nginx -g "daemon off;"

Solution

Ensure your Docker image's ENTRYPOINT or CMD runs a foreground process:

# Good: runs in foreground
ENTRYPOINT ["nginx", "-g", "daemon off;"]

# Good: starts a service that doesn't daemonize
CMD ["/usr/local/bin/my-app"]

# Bad: application daemonizes and exits
CMD ["/usr/sbin/service", "nginx", "start"]

Cause 2: Application Error (Exit 1)

Check docker logs for the actual error message:

docker logs my_container

Common errors:

  • Missing configuration file
  • Missing environment variable
  • Required port already in use on the host
  • Permission denied on mounted volume
  • Dependency not available (database, Redis, etc.)

Debug Interactively

Start the container interactively to investigate:

docker run -it --entrypoint /bin/sh image_name

Once inside, verify:

# Check if config file exists
ls -la /etc/myapp/config.ini

# Check environment variables
env | grep MY_VAR

# Test network connectivity
curl http://database:5432

# Check file permissions
ls -la /app/data/

Cause 3: Out of Memory (Exit 137)

The container was killed because it exceeded memory limits.

Detect OOM Kill

docker inspect container_name | grep -i oomkilled

# Output: "OOMKilled": true, means it ran out of memory

Check system logs:

dmesg | grep -i "out of memory"

Solution

Increase memory limit:

# Run with 512MB limit
docker run -m 512m image_name

# Or in docker-compose
services:
  myapp:
    image: myimage
    mem_limit: 512m
    memswap_limit: 512m

Monitor memory usage:

docker stats container_name

Cause 4: Missing Volume or Mount Point (Exit 1)

If the container depends on a mounted file or directory that doesn't exist on the host:

# Verify the path exists on host
ls -la /path/on/host

# Create if missing
mkdir -p /path/on/host

# Restart container
docker restart container_name

Check Mount in Docker

docker inspect container_name | grep -A 10 "Mounts"

Cause 5: Dependencies Not Ready (Exit 1)

In docker-compose, if a container depends on a service that isn't ready (database still starting), the dependent container may fail.

Solution: Add Service Dependencies with Health Checks

version: '3.8'

services:
  db:
    image: postgres:14
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5

  app:
    image: myapp
    depends_on:
      db:
        condition: service_healthy

This ensures app only starts after db is healthy.

Wait Script Alternative

#!/bin/bash
# wait-for-db.sh
until nc -z postgres 5432; do
  echo "Waiting for postgres..."
  sleep 1
done
echo "Postgres is up!"
exec "$@"

Use in Dockerfile:

COPY wait-for-db.sh /
RUN chmod +x /wait-for-db.sh
ENTRYPOINT ["/wait-for-db.sh"]
CMD ["python", "app.py"]

Cause 6: Permission Denied (Exit 1)

The process inside the container doesn't have permission to access a mounted volume.

Check Permissions

# On host
ls -la /path/on/host

# Check UID inside container
docker run image_name id

Fix Permissions

If your container runs as UID 1000:

# On host, change ownership
chown -R 1000:1000 /path/on/host
chmod -R 755 /path/on/host

Or run container with correct user:

docker run --user 1000:1000 image_name

Universal Debug Technique

Start the container with a dummy process to keep it running, then investigate:

# Terminal 1: Start container sleeping
docker run -it --entrypoint sleep problematic_image infinity

# Terminal 2: Get container ID and execute shell
docker exec -it container_id /bin/sh

# Now investigate inside
cd /app
ls -la
cat config.ini
env

This lets you explore the filesystem and environment without the app crashing immediately.


Cause 7: Missing Binary (Exit 127)

The entrypoint or command binary doesn't exist in the image:

# Verify binary exists in image
docker run image_name which python3

# Or inspect the image
docker inspect image_name | grep Entrypoint

Solution

Either install the binary or use the correct path:

# Install missing dependency
RUN apt-get update && apt-get install -y python3

# Use correct path
ENTRYPOINT ["/usr/bin/python3"]

Anti-Pattern: Using restart: always as Workaround

Never mask the problem with restart policies:

# BAD: Don't do this
services:
  app:
    image: myapp
    restart: always  # Infinite crash loop!

This creates a crash loop. Always identify and fix the root cause.

Use docker logs as your first diagnostic step. 90% of container exit issues are immediately visible in the logs. Combine with docker inspect to check exit codes and resource limits.

Never use restart: always as a band-aid for crashing containers. Fix the underlying issue instead. Use restart: on-failure with a limited retry count if the application occasionally crashes.


Complete Debugging Checklist

# 1. Check if container is actually exited
docker ps -a

# 2. View logs (most important!)
docker logs container_name

# 3. Check exit code
docker inspect container_name --format='{{.State.ExitCode}}'

# 4. Check if OOM killed
docker inspect container_name | grep OOMKilled

# 5. Verify mounted paths exist
docker inspect container_name | grep -A 10 Mounts

# 6. Check resource limits
docker inspect container_name | grep -E "Memory|CpuShares"

# 7. Test with entrypoint override
docker run -it --entrypoint /bin/sh image_name

# 8. Check Docker logs for system-level issues
journalctl -u docker -f

On this page