Your container is restarting. Over and over. docker ps shows it’s been up for 3 seconds, then 5, then 2. You’re stuck in a loop and the logs aren’t helping.
Here’s how to debug it systematically.
Step 1: Check the Exit Code#
1
| docker inspect --format='{{.State.ExitCode}}' container_name
|
Common exit codes:
- 0: Clean exit (container finished its job)
- 1: Application error (check your code)
- 137: OOMKilled (out of memory)
- 139: Segfault
- 143: SIGTERM (graceful shutdown)
If you see 137, your container is being killed for using too much memory. Skip to the OOM section below.
Step 2: Read the Actual Logs#
1
2
3
4
5
6
7
8
| # Last 100 lines
docker logs --tail 100 container_name
# Follow logs in real-time
docker logs -f container_name
# With timestamps
docker logs -t container_name
|
If logs are empty or truncated, the container might be crashing before it can write anything. Try:
1
2
| # Run interactively to see startup output
docker run -it --rm your_image:tag
|
Step 3: Check Why It Exited#
1
| docker inspect container_name | jq '.[0].State'
|
Look for:
OOMKilled: true — memory problemError — startup error messageExitCode — the exit code
Step 4: Common Causes and Fixes#
The Entrypoint Exits Immediately#
Your entrypoint script runs and exits. Container thinks it’s done.
Fix: Make sure your entrypoint keeps running:
1
2
3
4
5
6
7
8
9
10
| # Bad - exits immediately
#!/bin/bash
echo "Starting app"
./configure.sh
# Good - stays running
#!/bin/bash
echo "Starting app"
./configure.sh
exec ./my-app # exec replaces the shell, keeps PID 1
|
OOMKilled (Exit Code 137)#
Container used more memory than allowed.
1
2
3
4
5
| # Check memory limit
docker inspect --format='{{.HostConfig.Memory}}' container_name
# Check actual usage before crash
docker stats --no-stream container_name
|
Fix: Increase memory limit or fix the memory leak:
1
2
| docker run -m 512m your_image # Set 512MB limit
docker run -m 1g your_image # Set 1GB limit
|
Missing Environment Variables#
App crashes because required config is missing.
1
2
| # Check what env vars are set
docker inspect --format='{{range .Config.Env}}{{println .}}{{end}}' container_name
|
Fix: Pass the required variables:
1
| docker run -e DATABASE_URL=postgres://... your_image
|
Health Check Failing#
If you have a health check defined, Docker might restart “unhealthy” containers.
1
| docker inspect --format='{{json .State.Health}}' container_name | jq
|
Fix: Either fix the health check endpoint or adjust the timing:
1
2
| HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
CMD curl -f http://localhost:8080/health || exit 1
|
Restart Policy Fighting You#
Your restart policy keeps bringing back a broken container.
1
| docker inspect --format='{{.HostConfig.RestartPolicy.Name}}' container_name
|
Fix: Temporarily disable restarts to debug:
1
2
3
| docker update --restart=no container_name
docker stop container_name
docker run -it --rm your_image /bin/sh # Debug interactively
|
Step 5: The Nuclear Option#
Sometimes you need to start fresh:
1
2
3
4
5
6
7
8
9
| # Stop and remove the container
docker rm -f container_name
# Remove the image and rebuild
docker rmi your_image:tag
docker build -t your_image:tag .
# Run with verbose output
docker run --rm -it your_image:tag
|
Quick Debugging Script#
Save this as debug-container.sh:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| #!/bin/bash
CONTAINER=$1
echo "=== Container State ==="
docker inspect --format='ExitCode: {{.State.ExitCode}}, OOMKilled: {{.State.OOMKilled}}, Error: {{.State.Error}}' $CONTAINER
echo -e "\n=== Last 50 Log Lines ==="
docker logs --tail 50 $CONTAINER
echo -e "\n=== Memory Limit ==="
docker inspect --format='Memory: {{.HostConfig.Memory}}' $CONTAINER
echo -e "\n=== Restart Policy ==="
docker inspect --format='RestartPolicy: {{.HostConfig.RestartPolicy.Name}}' $CONTAINER
|
Usage: ./debug-container.sh my-container
Summary#
- Check exit code first — it tells you the category of problem
- Read the logs — but run interactively if logs are empty
- Check for OOMKilled — memory issues are common
- Verify environment variables — missing config crashes apps
- Check health checks — they can trigger restart loops
- Disable restart policy to debug — stop the loop so you can think
The restart loop is a symptom, not the disease. Find the exit code, read the logs, fix the root cause.