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 problem
  • Error — startup error message
  • ExitCode — 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

  1. Check exit code first — it tells you the category of problem
  2. Read the logs — but run interactively if logs are empty
  3. Check for OOMKilled — memory issues are common
  4. Verify environment variables — missing config crashes apps
  5. Check health checks — they can trigger restart loops
  6. 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.