Switch Language
Toggle Theme

Docker Compose Troubleshooting Guide: Quick Solutions for 5 Common Errors

Docker Compose error troubleshooting workflow diagram

Friday afternoon, 3:30 PM. Two hours until the code submission deadline.

I stared at that red error message in my terminal — Error starting userland proxy: Bind for 0.0.0.0:8080 failed: port is already allocated. It was working fine yesterday, and now it won’t start.

Ctrl+C, retry. Still fails. Googled “docker compose port already allocated”, opened five or six Stack Overflow threads, tried every solution: restart Docker, delete containers, change ports… The error message wouldn’t budge. Palms started sweating.

If you’ve been through this, you know exactly what I’m talking about. Docker Compose error messages can span dozens of lines, with the one useful piece of information buried on line 23, while you’re already panicking at line 1. Worse yet, every new error means starting the troubleshooting process from scratch.

This article summarizes the pitfalls I (and my team) have encountered over two years. We’ve organized 5 major categories of common Docker Compose errors, each following the pattern: “Error Characteristics → Root Causes → Solutions (from simple to complex).” You’ll find that 90% of errors can be resolved in 5 minutes — once you know where to start.

Troubleshooting Basics - Master 3 Core Tools

Before diving into specific errors, let’s talk about the three essential tools for troubleshooting Docker Compose issues — I use these commands dozens of times every day.

Tool 1: docker-compose ps - Check Status Quickly

This command tells you which containers are up and which are down.

docker-compose ps

Focus on the State column:

  • Up - Running normally, breathe easy
  • Exit - Startup failed or crashed during runtime
  • Restarting - Constantly restarting, indicates startup command issues

When I see a service with Exit 1 status, I know it’s time to check the logs.

Tool 2: docker-compose logs - Find Clues in Logs

This is the core of troubleshooting.

# View all services' logs
docker-compose logs

# View only nginx logs
docker-compose logs nginx

# Follow logs in real-time (like tail -f)
docker-compose logs -f

# Show only last 100 lines
docker-compose logs --tail 100 nginx

Honestly, Docker’s log output can be messy, but 90% of the time, the real error message is in the last few dozen lines. Scroll up and look for keywords: ERROR, failed, cannot.

Tool 3: docker inspect - Deep Inspection (When Needed)

Only use this when the first two commands don’t solve the problem.

# View complete container configuration
docker inspect container_name

# Check only status
docker inspect --format='{{.State.Status}}' container_name

# Get IP address
docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container_name

General Troubleshooting Process (Remember This)

Don’t panic when problems arise, follow this flow:

  1. docker-compose ps - See which service failed
  2. docker-compose logs [service_name] - Check specific errors
  3. docker inspect - Deep analysis (rarely needed)

Alright, tools ready. Now let’s tackle the 5 most frequent errors.

Port Conflicts - “port is already allocated”

I’ve seen this error way too many times. You’ll see something like:

Error starting userland proxy: Bind for 0.0.0.0:8080 failed: port is already allocated

Or:

ERROR: for nginx  Cannot start service nginx: driver failed programming external connectivity on endpoint xxx: Bind for 0.0.0.0:80 failed: port is already allocated

Why Does This Happen?

Usually three scenarios:

  1. After last docker-compose up, you hit Ctrl+C but didn’t run docker-compose down, containers still running in background
  2. You changed port configuration in docker-compose.yml, but old containers weren’t cleaned up
  3. Another program on your machine is using that port (like local Nginx, MySQL)

Solutions (Try in Order, Simple to Complex)

Solution 1: Clean and Restart (90% effective)

docker-compose down
docker-compose up -d

This works for me every time. The down command stops all containers and removes them while preserving volume data.

Solution 2: Find Container Occupying the Port

If solution 1 doesn’t work, you might have “ghost containers” — containers not part of current project but occupying the port.

# List all containers (including stopped ones)
docker ps -a | grep 8080

# After finding container_id, kill it
docker stop <container_id>
docker rm <container_id>

Solution 3: Check docker-proxy Processes

Sometimes containers are deleted but docker-proxy processes remain.

# Check docker-proxy processes
ps aux | grep docker-proxy | grep 8080

# If remnants exist, restart Docker service
sudo systemctl restart docker  # Linux
# Or on Mac: Docker Desktop menu → Restart

Solution 4: Check Host Port Usage

Maybe a local program is using the port.

# Linux/Mac
lsof -i :8080
netstat -tlnp | grep 8080

# Windows
netstat -ano | findstr 8080

If you find another program, either stop it or change the port in docker-compose.yml.

Solution 5: Modify Port Configuration (Last Resort)

Edit docker-compose.yml:

services:
  web:
    ports:
      - "8081:80"  # Change 8080 to 8081

My Recommendations

Develop the habit: stop containers with docker-compose down, not just Ctrl+C. I used to take shortcuts with Ctrl+C, resulting in frequent port conflicts. After changing this habit, these errors basically disappeared.

Also, use non-standard ports in development environments. Don’t use 80, 3306 directly; change to 8080, 3307 to avoid conflicts with system services.

Network Issues - “network declared as external but could not be found”

This error typically looks like:

ERROR: Network my_network declared as external, but could not be found. Please create the network manually using `docker network create my_network` and try again.

Why This Error?

Docker Compose has an easy pitfall: if you mark a network as external: true in docker-compose.yml, Docker assumes the network already exists and won’t create it automatically. Then it searches, can’t find it, and errors out.

Common scenarios:

  1. You copied someone’s config file with an external network, but you don’t have it locally
  2. You restarted Docker and some network configurations were lost
  3. Network name case is wrong (Docker network names are case-sensitive!)

Solutions

Solution 1: List Existing Networks, Verify Name

docker network ls

You might discover the actual network name is myproject_app_network, not the app_network you configured. Docker Compose automatically prefixes network names with the project name.

Solution 2: Manually Create Missing Network

If the network truly doesn’t exist, create it:

docker network create my_network

Solution 3: Fix Configuration File

Three ways, pick one:

# Method A: Remove external, let Compose create automatically
networks:
  app_network:
    driver: bridge

# Method B: Use name field to explicitly specify network name
networks:
  app_network:
    external: true
    name: my_actual_network_name

# Method C: Manually create network first, then reference with external

I personally prefer Method A. Unless you need to share networks across multiple Compose projects, letting Compose manage networks is much easier.

Solution 4: Clean and Rebuild (Network Lost After Docker Restart)

docker-compose down
docker network prune  # Clean unused networks
docker-compose up -d

Pitfall Prevention

  • Clearly distinguish which networks should be external (cross-project sharing) and which should be Compose-managed (single project use)
  • Use the name field to explicitly specify network names, avoiding confusion from Compose auto-prefixing
  • Document pre-created external networks in team README to prevent newcomers from stumbling

Build Failures - “service failed to build”

Don’t panic when you see this error:

ERROR: Service 'app' failed to build: Build failed

Key Technique: Scroll Up the Logs

“service failed to build” is just a summary error; the real problem is earlier. You need to scroll up 50-100 lines and look for keywords: ERROR, failed, cannot, not found, permission denied.

First time I encountered this error, I stared at the last line forever before realizing I needed to scroll up. The real error could be “npm install failed” or “file not found”, buried in piles of output.

Common Sub-Error Types

Type 1: File Not Found

COPY failed: stat /var/lib/docker/tmp/.../package.json: no such file or directory

Causes:

  • Incorrect build context path
  • .dockerignore excluded necessary files

Solutions:

# Check context configuration in docker-compose.yml
services:
  app:
    build:
      context: ./my-app  # Confirm this path is correct
      dockerfile: Dockerfile

# Temporarily rename .dockerignore for testing
mv .dockerignore .dockerignore.bak
docker-compose build app

Type 2: Dependency Installation Failure

npm ERR! 404 Not Found - GET https://registry.npmjs.org/xxx

Or:

E: Unable to locate package xxx

Causes: Wrong package name, non-existent version, network issues

Solutions:

# Use domestic mirror (in Dockerfile)
RUN npm config set registry https://registry.npmmirror.com
RUN npm install

# Or switch apt source
RUN sed -i 's/deb.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list
RUN apt-get update && apt-get install -y xxx

Type 3: Out of Memory

The command '/bin/sh -c npm install' returned a non-zero code: 137
signal: killed

Exit code 137 usually indicates insufficient memory.

Solutions:

  • Docker Desktop → Settings → Resources → Memory, increase to 4GB+
  • Or reduce concurrent builds in Dockerfile: RUN npm install --max_old_space_size=4096

Type 4: Dockerfile Syntax Error

For example, misspelled instruction names or incorrect COPY source file paths.

Solution: Test build separately:

cd build_directory
docker build -t test-build .

This gives clearer error messages.

Debugging Methods

Rebuild Without Cache:

docker-compose build --no-cache service_name

Sometimes cached intermediate layers are problematic; clearing cache and rebuilding can solve it.

Check Build Context:

docker-compose config

This command shows the complete parsed configuration, helping you spot path issues.

My Experience

  • Save a successfully building version as baseline, test changes before continuing
  • Modify Dockerfile one thing at a time; don’t change everything then get lost when errors occur
  • For slow builds, consider multi-stage builds or reorder instructions to leverage cache for unchanging instructions

Container Exits After Starting - “exited with code X”

This situation is more subtle: image builds successfully, container starts, then immediately exits.

Running docker-compose ps shows:

Name              State
app_web_1         Exit 1
app_db_1          Up

Exit Code Meanings (Remember These)

  • Exit 0: Normal program exit — but might be a problem for containers (command finished and ended)
  • Exit 1: Application error (most common)
  • Exit 137: Out of memory (OOM) or killed
  • Exit 139: Segmentation fault
  • Exit 143: Received SIGTERM signal (usually manual stop)

Troubleshooting Steps

Step 1: Check Logs

docker-compose logs service_name

90% of the time, logs will tell you why it exited.

Step 2: Manually Enter Container for Debugging

If logs don’t reveal the problem, modify docker-compose.yml to keep container running:

services:
  app:
    command: sleep infinity  # Keep container from exiting

Then:

docker-compose up -d
docker-compose exec app sh  # Enter container
# Manually execute original startup command, observe errors

Targeted Solutions

Exit 0 - Command Finishes and Exits

For example, if your command is echo "Hello", it has nothing to do after execution, container naturally exits.

Solution: Change to daemon or blocking command:

# Wrong example
command: echo "Started"

# Correct example
command: npm start  # A continuously running process

Exit 1 - Application Error

Check logs to pinpoint specific cause, common ones:

  • Configuration file path errors
  • Missing environment variables
  • Database connection failure (database not ready yet)
  • Permission issues

Exit 137 - Out of Memory

Add memory limit to container:

services:
  app:
    mem_limit: 2g
    memswap_limit: 2g

Or adjust Docker Desktop’s total memory allocation.

Dependent Service Not Ready

I’ve stepped on this mine. Application container started, but database still initializing, application can’t connect and crashes.

Solution: Use depends_on with healthcheck:

services:
  app:
    depends_on:
      db:
        condition: service_healthy

  db:
    image: postgres
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5

This way app waits until db is truly ready before starting.

Pitfalls I’ve Hit

Once had a container repeatedly exiting with Exit 1, logs only said “Config file not found”. Searched forever, turns out I used relative path for config file location, and the working directory in container was different from what I expected. Changed to absolute path and it worked.

Another time database password was wrong, application crashed on startup. Logs were actually clear, but I didn’t look carefully… wasted 20 minutes.

Permission Issues - “permission denied”

This error is particularly common when mounting volumes:

Error: EACCES: permission denied, open '/app/data/config.json'

Or container logs say “Permission denied” but you don’t know which file.

Why Permission Issues?

Container’s user UID/GID doesn’t match host file owner. For example:

  • File owner on host is you (UID 1000)
  • Application runs as www-data user in container (UID 33)
  • www-data has no permission to read/write your files, errors out

Solutions

Solution 1: Use user to Specify UID/GID (Recommended)

Let container run with your user identity:

services:
  app:
    user: "${UID}:${GID}"
    volumes:
      - ./data:/app/data

At runtime:

UID=$(id -u) GID=$(id -g) docker-compose up

Or write to .env file:

# .env
UID=1000
GID=1000

Solution 2: Change Host File Permissions

Simple and crude:

chmod -R 777 ./data  # Use cautiously, security risk
# Or
chmod -R 755 ./data  # Safer
chown -R $(id -u):$(id -g) ./data

Solution 3: Add Flags for SELinux Systems (CentOS/RHEL)

If using CentOS/RHEL, might be SELinux restrictions:

volumes:
  - ./data:/app/data:z  # Allow multiple containers to share
  # Or
  - ./config:/app/config:Z  # This container only

Difference between lowercase z and uppercase Z: lowercase is shared permissions, uppercase is private permissions.

Solution 4: Use Named Volume Instead of Bind Mount

Docker-managed volumes don’t have permission issues:

services:
  app:
    volumes:
      - app_data:/app/data  # named volume

volumes:
  app_data:  # Docker automatically manages permissions

Downside is you can’t directly modify files on host, only access through container.

Solution 5: Adjust Permissions in Entrypoint Script

For complex scenarios:

# entrypoint.sh
#!/bin/sh
chown -R appuser:appuser /app/data
exec "$@"
COPY entrypoint.sh /
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
CMD ["node", "app.js"]

My Recommendations

  • Production: Use named volumes, secure and no permission worries
  • Development: Use Solution 1 (user specify UID/GID), convenient to modify files directly on host
  • Avoid 777 permissions: Unless you completely trust code running in container, don’t give 777

Permission issues are indeed tricky, but once you understand UID/GID matching logic, not that difficult.

General Debugging Techniques Summary

After covering specific errors, let’s discuss systematic troubleshooting approaches.

Standard Troubleshooting Process (Follow This)

1. docker-compose ps           → Check status, locate problematic service
2. docker-compose logs <service>  → Find key error messages in logs
3. docker-compose config       → Validate config file syntax
4. docker inspect <container>  → Deep inspection (when necessary)
5. Isolated testing            → Start problematic service separately

Develop this habit, won’t be clueless when problems arise.

Common Cleanup Commands (Regular Maintenance)

# Stop and remove containers (keep volumes)
docker-compose down

# Delete volumes too (use cautiously!)
docker-compose down -v

# Clean dangling resources (unused networks, images, etc.)
docker system prune

# Complete cleanup (including all images)
docker system prune -a

# Rebuild without cache
docker-compose build --no-cache

# Check Docker disk usage
docker system df

I run docker system prune every Friday before leaving work, cleaning up the week’s accumulated garbage. Once found Docker using 50GB disk, after cleanup only 10GB remained…

Preventive Measures

Configuration Validation:

# Validate config file before starting
docker-compose config

This command checks YAML syntax, discovers configuration errors.

Health Checks:

services:
  web:
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:80/health"]
      interval: 30s
      timeout: 10s
      retries: 3

With healthcheck, you can quickly discover services that started but aren’t actually healthy.

Reasonable Restart Policies:

services:
  app:
    restart: unless-stopped  # Recommended: always restart unless manually stopped
    # restart: always        # Always restart
    # restart: on-failure    # Only restart on failure

Centralized Environment Variable Management:

# .env file
DB_PASSWORD=your_password
API_KEY=your_key

# docker-compose.yml
services:
  app:
    environment:
      - DB_PASSWORD=${DB_PASSWORD}
      - API_KEY=${API_KEY}

This way changing configuration doesn’t require modifying YAML file, convenient for team collaboration.

Conclusion

Back to the opening scenario: Friday afternoon 3:30 PM, deadline approaching, containers won’t start. Now you know what to do:

  1. Don’t panic, take a deep breath
  2. Identify error type (port, network, build, exit, permission)
  3. Follow corresponding chapter’s solutions, try simple to complex in order
  4. If all else fails, check logs — the answer is there

Docker Compose errors aren’t scary; what’s scary is not having a systematic troubleshooting approach. Remember these 5 major error categories and corresponding solution patterns, next time you encounter problems, solve them in 5 minutes.

Final suggestion: build a team knowledge base, document pitfalls and solutions. Our team’s Wiki has a “Docker Common Issues” page, newcomers who read it avoid 80% of pitfalls.

Have you encountered any weird Docker Compose errors? Welcome to share in comments, might help others.

9 min read · Published on: Dec 17, 2025 · Modified on: Dec 26, 2025

Comments

Sign in with GitHub to leave a comment

Related Posts