DEV Community

Yash Sonawane
Yash Sonawane

Posted on

Your Docker Container Is Running… So Why Is Your Application Down?

A practical guide to debugging Docker containers like a real DevOps engineer.

Imagine this situation.

You deploy your application using Docker. Everything looks perfect.

docker ps
Enter fullscreen mode Exit fullscreen mode

Output:

CONTAINER ID   IMAGE          STATUS
a1b2c3d4       my-app:latest  Up 10 minutes
Enter fullscreen mode Exit fullscreen mode

Your container is running. Docker reports no problems. You feel confident.

Then someone messages you:

"Hey, the application is down. Can you fix it?"

You check the container again.

Still running.

You restart it.

Still broken.

You rebuild the image.

Still broken.

Welcome to the real world of DevOps. 😅

A running container does not necessarily mean a healthy application.

Let's learn how to troubleshoot Docker like an engineer instead of randomly restarting containers.


🧠 1. Understand the Difference Between Running and Healthy

Docker can tell you whether a container's main process is running. It cannot automatically guarantee that your application is working correctly.

For example, your container might be running while:

  • The application cannot connect to its database.
  • The API is returning HTTP 500 errors.
  • The application is listening on the wrong port.
  • A required environment variable is missing.
  • The application is responding too slowly.
  • A dependency has crashed.

Think of it like this:

Docker container: RUNNING ✅
Application:       BROKEN  ❌
Database:          UNREACHABLE ❌
Users:             ANGRY 😭
Enter fullscreen mode Exit fullscreen mode

Your job as a DevOps engineer is to discover where the actual failure is happening.

🔍 2. Start With the Logs

Never begin by randomly restarting everything. First, investigate.

Check the application logs:

docker logs my-app
Enter fullscreen mode Exit fullscreen mode

Follow logs in real time:

docker logs -f my-app
Enter fullscreen mode Exit fullscreen mode

Show the latest 100 lines:

docker logs --tail 100 my-app
Enter fullscreen mode Exit fullscreen mode

Include timestamps:

docker logs -t my-app
Enter fullscreen mode Exit fullscreen mode

Look for errors such as:

Connection refused
Database connection failed
Address already in use
Permission denied
Missing environment variable
Enter fullscreen mode Exit fullscreen mode

Pro tip: Logs are often the fastest way to identify the root cause. Read them before changing anything.

🛠️ 3. Inspect the Container

Sometimes the problem is not visible in the logs.

Inspect the container configuration:

docker inspect my-app
Enter fullscreen mode Exit fullscreen mode

Check its state:

docker inspect -f '{{.State.Status}}' my-app
Enter fullscreen mode Exit fullscreen mode

Check its exit code:

docker inspect -f '{{.State.ExitCode}}' my-app
Enter fullscreen mode Exit fullscreen mode

Check whether Docker reports it as healthy:

docker inspect -f '{{.State.Health.Status}}' my-app
Enter fullscreen mode Exit fullscreen mode

Note: The last command requires a health check to be configured. Without one, Docker may return an empty value.

Inspecting a container helps you investigate its configuration, state, network settings, mounts, and other runtime details.

🌐 4. Check Port Mapping

Your application might be listening on port 8080 inside the container, but you may have exposed a different port—or forgotten to publish it.

Check published ports:

docker port my-app
Enter fullscreen mode Exit fullscreen mode

Start a container with the correct mapping:

docker run -d \
  --name my-app \
  -p 8080:8080 \
  my-app:latest
Enter fullscreen mode Exit fullscreen mode

The mapping follows this pattern:

-p HOST_PORT:CONTAINER_PORT
Enter fullscreen mode Exit fullscreen mode

For example:

Your browser
     |
     v
localhost:8080
     |
     v
Docker host port 8080
     |
     v
Container port 8080
     |
     v
Application
Enter fullscreen mode Exit fullscreen mode

Remember: publishing a port does not make an application listen on that port. Your application must actually be listening on the expected interface and port.

💾 5. Check Whether the Container Is Running Out of Resources

An application can become slow or crash when it runs out of memory or struggles with CPU usage.

Check resource consumption:

docker stats
Enter fullscreen mode Exit fullscreen mode

Example:

CONTAINER     CPU %     MEM USAGE / LIMIT
my-app        95%       480MiB / 512MiB
database      15%       300MiB / 1GiB
Enter fullscreen mode Exit fullscreen mode

In this hypothetical example, my-app is consuming almost all its memory limit.

Investigate further before changing resource limits. A memory leak, excessive traffic, or inefficient application code could be the real problem.

Useful commands:

docker ps -a
docker system df
docker events
Enter fullscreen mode Exit fullscreen mode

These help you inspect container states, Docker disk usage, and Docker events.

Important: Avoid running docker system prune -a as a routine troubleshooting step. It can remove unused images and other resources you may still need.

❤️ 6. Add a Docker Health Check

Here's one way to improve your container monitoring.

A health check lets Docker periodically test whether an application is responding to a defined check.

Example Dockerfile:

FROM nginx:alpine

COPY index.html /usr/share/nginx/html/index.html

HEALTHCHECK --interval=30s \
  --timeout=5s \
  --start-period=10s \
  --retries=3 \
  CMD wget -q -O /dev/null http://127.0.0.1/ || exit 1
Enter fullscreen mode Exit fullscreen mode

This example uses a lightweight Nginx image and checks whether its HTTP endpoint responds successfully.

Check the health status:

docker ps
Enter fullscreen mode Exit fullscreen mode

A configured health check can report statuses such as:

starting
healthy
unhealthy
Enter fullscreen mode Exit fullscreen mode

But remember: a health check is only as good as the test you define. A successful HTTP response does not necessarily mean every feature of your application is working.

🔗 7. Investigate Network and Database Problems

Suppose your application depends on a PostgreSQL database.

Your application container is running, but database connections keep failing.

First, inspect your Docker networks:

docker network ls
Enter fullscreen mode Exit fullscreen mode

Inspect the network used by your containers:

docker network inspect my-network
Enter fullscreen mode Exit fullscreen mode

If both services need to communicate, make sure they share an appropriate network.

With Docker Compose, services on the same default network can usually reach each other using their service names.

Example:

services:
  app:
    build: .
    ports:
      - "8080:8080"
    environment:
      DATABASE_URL: postgres://app:password@db:5432/appdb
    depends_on:
      - db

  db:
    image: postgres:17
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: password
      POSTGRES_DB: appdb
Enter fullscreen mode Exit fullscreen mode

Here, db is the database service name.

Important: This is a learning example, not a production-ready configuration. Use secrets rather than hardcoded passwords, persistent storage for database data, and application-level retry logic. Also, depends_on alone does not guarantee that PostgreSQL is ready to accept connections.

🧪 8. Build Your Own Docker Troubleshooting Checklist

When an application goes down, follow this order:

  1. Check the state: docker ps -a
  2. Read the logs: docker logs my-app
  3. Inspect configuration: docker inspect my-app
  4. Check resource usage: docker stats
  5. Verify port mapping: docker port my-app
  6. Investigate networking: docker network inspect my-network
  7. Test the application endpoint: use curl or an appropriate health check.
  8. Apply a fix: change the configuration or code based on evidence.
  9. Verify recovery: repeat the relevant tests and check the logs.

The goal is not simply to make the error disappear.

The goal is to understand why it happened and how to prevent it from happening again.

🚀 9. Take It Further: Build a Container Monitoring Project

Want to turn this knowledge into a portfolio project?

Build a small Docker monitoring stack using:

  • Docker Compose to run the services.
  • Prometheus to collect metrics.
  • Grafana to visualize performance.
  • cAdvisor to expose container resource metrics.
  • Alerting to notify you about important failures.

A simplified architecture:

Docker Containers
       |
       v
    cAdvisor
       |
       v
   Prometheus
       |
       v
     Grafana
       |
       v
 Dashboards & Alerts
Enter fullscreen mode Exit fullscreen mode

Track CPU usage, memory consumption, container restarts, and application availability.

Document one simulated failure, your investigation, the root cause, and the fix. That gives you a concrete project to discuss during DevOps interviews.

🎯 Final Thoughts

Docker makes packaging and running applications easier, but it does not eliminate production problems.

Good DevOps engineers do not blindly restart containers. They collect evidence, understand system behavior, identify root causes, and verify their fixes.

The next time someone says, "The container is running, but the application is down," you'll know where to start.

Your challenge: Run a Docker container, inspect its logs, configure a health check, and deliberately introduce a failure in a local test environment. Can you diagnose the problem without immediately restarting the container?

Share what you discover in the comments! 👇


📚 Keep Building Your DevOps Skills

If you want structured resources to help you learn these tools, explore my guides:

Learn by building, break things in a safe lab, and become better at fixing them.

Top comments (0)