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 -aLook 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_nameCheck Exit Code
docker inspect container_name --format='{{.State.ExitCode}}'Exit Code Reference
| Exit Code | Meaning | Common Cause |
|---|---|---|
| 0 | Process terminated normally | Application exited normally (not a daemon) |
| 1 | General error | Application error, check logs |
| 125 | Docker daemon error | Docker runtime issue |
| 126 | Command not executable | Entrypoint not executable, permission denied |
| 127 | Command not found | Binary missing or wrong path |
| 137 | SIGKILL | Out of Memory (OOM), or docker kill |
| 143 | SIGTERM | Graceful 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_containerCommon 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_nameOnce 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 memoryCheck 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: 512mMonitor memory usage:
docker stats container_nameCause 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_nameCheck 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_healthyThis 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 idFix Permissions
If your container runs as UID 1000:
# On host, change ownership
chown -R 1000:1000 /path/on/host
chmod -R 755 /path/on/hostOr run container with correct user:
docker run --user 1000:1000 image_nameUniversal 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
envThis 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 EntrypointSolution
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