← Back to Questions
Docker

How to debug crashing Docker containers?

Learn How to debug crashing Docker containers? with simple explanations, real-time examples, interview tips and practical use cases.

How to Debug Crashing Docker Containers?

Debugging crashing Docker containers means identifying why a container starts, fails, exits, restarts, or enters a crash loop in development, staging, or production environments.

Simple Definition: A Docker container usually crashes because the main process inside it exits due to application errors, missing configuration, dependency failures, permission issues, resource limits, or runtime problems.

Why Docker Containers Crash

A Docker container stays alive only while its main process is running. If the main process exits, the container exits.

Container Starts
      |
Main Process Starts
      |
Main Process Fails
      |
Container Exits
      |
Restart Policy May Restart It
    

In production, this may appear as:

  • Container restarting continuously
  • Application unavailable
  • 502 Bad Gateway from Nginx
  • API gateway unable to route traffic
  • Database connection failures

Real-Time Production Example

Consider a Docker Compose-based microservices platform:

Nginx
API Gateway
Portfolio Service
Interview Service
Payment Service
MySQL
Redis
Prometheus
Grafana
    

If payment-service keeps crashing, user payments fail. If api-gateway keeps restarting, the whole platform becomes unavailable.

Common Reasons Containers Crash

Reason Example
Application exception Spring Boot startup failure
Missing environment variable DB_URL not configured
Wrong command Invalid CMD or ENTRYPOINT
Dependency unavailable MySQL not ready
Permission issue Cannot write to mounted volume
Out of memory OOMKilled
Port conflict Host port already in use

Step 1: Check Container Status

docker ps -a
    

Look at the STATUS column.

Example

payment-service   Restarting (1) 10 seconds ago
api-gateway       Exited (1) 2 minutes ago
mysql             Up 5 minutes
    

Status Meaning

Status Meaning
Exited (0) Process completed successfully
Exited (1) Application or command failed
Restarting Container is in crash loop
OOMKilled Container killed due to memory limit

Step 2: Check Container Logs

docker logs container-name
    

Follow Logs

docker logs -f container-name
    

Show Last 100 Lines

docker logs --tail=100 container-name
    

Logs usually reveal the actual error.

Spring Boot Crash Example

Failed to configure a DataSource:
'url' attribute is not specified
    

Root Cause

DB_URL missing
    

Fix

environment:
  DB_URL: jdbc:mysql://mysql:3306/payment_db
  DB_USERNAME: ${DB_USERNAME}
  DB_PASSWORD: ${DB_PASSWORD}
    

Debugging Flow

Container Crashing
      |
docker ps -a
      |
docker logs
      |
Find Error Message
      |
Fix Config / Code / Dependency
      |
Restart Container
    

Step 3: Inspect Exit Code

docker inspect container-name --format='{{.State.ExitCode}}'
    

Common Exit Codes

Exit Code Meaning
0 Success
1 General application error
126 Command cannot execute
127 Command not found
137 Killed, often memory issue
143 Terminated gracefully

Check OOMKilled Status

docker inspect container-name --format='{{.State.OOMKilled}}'
    

If output is true, the container was killed because of memory pressure.

Step 4: Inspect Full Container Details

docker inspect container-name
    

Check:

  • Environment variables
  • Mount paths
  • Network settings
  • Restart policy
  • Memory limits
  • Command and entrypoint

Step 5: Check Environment Variables

docker inspect container-name --format='{{json .Config.Env}}'
    

Missing or incorrect environment variables are a very common production issue.

Common Spring Boot Variables

SPRING_PROFILES_ACTIVE
DB_URL
DB_USERNAME
DB_PASSWORD
JWT_SECRET
GOOGLE_CLIENT_ID
GOOGLE_CLIENT_SECRET
RAZORPAY_KEY_ID
RAZORPAY_KEY_SECRET
    

Step 6: Debug Docker Compose Services

docker compose ps
    
docker compose logs -f service-name
    
docker compose config
    

docker compose config is very useful because it shows the final resolved Compose configuration after applying environment variables.

Step 7: Check Dependency Readiness

Many containers crash because dependencies are not ready.

Example

API starts before MySQL is ready
    

Error

Communications link failure
Connection refused
    

Fix Using Health Checks

mysql:
  image: mysql:8.0
  healthcheck:
    test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
    interval: 10s
    timeout: 5s
    retries: 5
    

Important Note About depends_on

depends_on controls startup order only. It does not always guarantee application readiness.

Production applications should also have retry logic.

Step 8: Test Networking

If container starts but crashes after dependency calls, test internal networking.

docker exec -it api-gateway sh
    
ping mysql
curl http://portfolio-service:8080/actuator/health
nslookup mysql
    

Common Networking Issues

  • Containers are on different networks
  • Wrong service name used
  • Application listens on localhost instead of 0.0.0.0
  • Firewall blocks traffic

Correct Application Binding

Bad

server.address=localhost
    

Good

server.address=0.0.0.0
    

Step 9: Check Volume and Permission Issues

Containers may crash when they cannot read/write mounted paths.

Error Example

Permission denied: /uploads
    

Check Mounts

docker inspect container-name --format='{{json .Mounts}}'
    

Fix Ownership

sudo chown -R 1001:1001 /host/uploads
    

Match host path permissions with the container user UID/GID.

Step 10: Check Memory and CPU

docker stats
    

If memory keeps increasing, container may be killed by OOM.

Java Container Memory Example

ENTRYPOINT ["java", "-XX:+UseContainerSupport", "-XX:MaxRAMPercentage=75.0", "-jar", "app.jar"]
    

Compose Memory Limit Example

deploy:
  resources:
    limits:
      memory: 768M
      cpus: "1.0"
    

Step 11: Debug CMD and ENTRYPOINT

A wrong startup command can immediately crash the container.

Command Not Found Example

exec: "java": executable file not found in $PATH
    

Check Image Command

docker inspect image-name --format='{{json .Config.Entrypoint}} {{json .Config.Cmd}}'
    

Step 12: Start Container with Shell for Debugging

Override entrypoint and enter the container.

docker run --rm -it --entrypoint sh image-name
    

For bash-based images:

docker run --rm -it --entrypoint bash image-name
    

Debug Inside Container

ls -la
env
pwd
whoami
java -version
cat /etc/resolv.conf
    

Step 13: Check Image Build Problems

Sometimes the image does not contain the expected JAR, config file, or binary.

Check Files

docker run --rm -it --entrypoint sh image-name

ls -la /app
    

Common Issue

COPY --from=build /app/target/*.jar app.jar
    

If build output path is wrong, final image may miss the application artifact.

Step 14: Check Port Configuration

Wrong port configuration can make the app look down even if the container is running.

docker port container-name
    

Spring Boot Example

server.port=8080
    

Compose Mapping

ports:
  - "9090:8080"
    

Step 15: Check Host-Level Problems

Sometimes the container is fine, but the host has problems.

Check Disk

df -h
docker system df
    

Check Inodes

df -i
    

Check Docker Daemon

sudo systemctl status docker
    

Step 16: Check Restart Policy

docker inspect container-name --format='{{json .HostConfig.RestartPolicy}}'
    

Recommended Production Policy

restart: unless-stopped
    

Restart policy helps availability, but it should not hide real application bugs.

Production Debugging Workflow

Container Down
      |
docker ps -a
      |
docker logs
      |
docker inspect
      |
Check Exit Code
      |
Check Env / Network / Volume / Memory
      |
Fix Root Cause
      |
Redeploy
      |
Monitor Logs and Metrics
    

Real Production Case Study

Problem

API Gateway container restarted continuously after deployment.

Investigation

docker compose logs -f api-gateway
    

Error Found

Could not resolve placeholder 'PAYMENT_SERVICE_URL'
    

Root Cause

Missing environment variable in production Compose file.

Fix

environment:
  PAYMENT_SERVICE_URL: http://payment-service:8084
    

Prevention

  • Use docker compose config before deployment
  • Add application startup validation
  • Add CI/CD deployment checks

Production Best Practices to Prevent Crashes

  1. Use health checks
  2. Validate environment variables
  3. Add retry logic for databases
  4. Use restart policies
  5. Set memory and CPU limits
  6. Use persistent volumes correctly
  7. Centralize logs
  8. Monitor with Prometheus and Grafana
  9. Use fixed image tags
  10. Run smoke tests after deployment

Useful Commands Summary

Command Purpose
docker ps -a Check container status
docker logs Read crash logs
docker inspect Check full container config
docker stats Check CPU/memory
docker compose logs Read service logs
docker compose config Validate resolved Compose config

Interview Answer

To debug a crashing Docker container, I first check the container status using docker ps -a, then inspect logs using docker logs or docker compose logs. After that, I check the exit code, OOMKilled status, environment variables, mounted volumes, network configuration, resource limits, and startup command using docker inspect.

Most crashing containers fail due to application exceptions, missing environment variables, database connectivity issues, wrong CMD/ENTRYPOINT, permission problems, or memory limits. In production, I also verify health checks, restart policies, logs, metrics, and host disk space.

Quick Summary Table

Problem Debug Step
App error docker logs
Missing env docker inspect / docker compose config
OOMKilled docker inspect + docker stats
Network issue ping/curl/nslookup inside container
Permission issue inspect mounts and UID/GID
Wrong entrypoint override entrypoint with shell

Useful Internal Links

Final Conclusion

Debugging crashing Docker containers requires a systematic approach: status, logs, exit code, environment variables, networking, volumes, resource limits, entrypoint, and host health.

In production, the best long-term solution is prevention through health checks, validated configuration, observability, restart policies, resource limits, persistent storage, and safe CI/CD deployment practices.

Why this Docker question is important?

This interview question helps candidates understand real-time backend development concepts, practical problem solving, coding fundamentals, system design basics and production-ready application behavior.

Practice this question carefully for Java backend roles, Spring Boot developer interviews, microservices interviews, company interviews and full-stack developer preparation.

About the Author

Naresh Kumar is a Senior Java Backend Engineer with experience building enterprise applications using Java, Spring Boot, Microservices, Docker, Kubernetes and Cloud technologies.