What's Actually Happening

Your Docker Compose service fails to start, gets stuck in "Restarting" state, or exits immediately after launching. The service might depend on other services that aren't ready, have configuration errors, or lack proper initialization. This is a common issue when orchestrating multi-container applications.

The Error You'll See

```bash $ docker-compose up -d Creating network "myapp_default" with the default driver Creating myapp_web_1 ... Creating myapp_db_1 ... Creating myapp_web_1 ... done Creating myapp_db_1 ... done

$ docker-compose ps Name Command State Ports ----------------------------------------------------------------- myapp_db_1 docker-entrypoint.sh mysqld Restarting 3306/tcp myapp_web_1 python app.py Exit 1 0.0.0.0:5000->5000/tcp

$ docker-compose logs web web_1 | Error: Cannot connect to database web_1 | Connection refused

$ docker-compose logs db db_1 | Can't create test file /var/lib/mysql/db.lower-test db_1 | Permission denied ```

Why This Happens

  1. 1.Dependency timing: Service starts before dependencies are ready
  2. 2.Health checks missing: No way to verify service readiness
  3. 3.Configuration errors: Invalid environment variables or config files
  4. 4.Permission issues: Volume mounts or user permissions
  5. 5.Resource constraints: Memory or CPU limits too low
  6. 6.Image issues: Missing or corrupted images
  7. 7.Network problems: Services can't communicate
  8. 8.Command/entrypoint failures: Start command failing

Step 1: Check Service Status and Logs

First, identify the failing service:

```bash # Check status of all services docker-compose ps

# Check logs for specific service docker-compose logs <service-name>

# Follow logs in real-time docker-compose logs -f <service-name>

# Check logs for all services docker-compose logs

# Check last 100 lines docker-compose logs --tail=100 <service-name>

# Check container exit code docker inspect <container-id> --format='{{.State.ExitCode}}'

# Check container state docker inspect <container-id> --format='{{.State.Status}}' docker inspect <container-id> --format='{{json .State}}' | jq ```

Step 2: Fix Dependency Order Issues

Services often fail because dependencies aren't ready:

yaml
# Bad: No dependency management
version: '3.8'
services:
  web:
    image: myapp-web
    ports:
      - "5000:5000"
  db:
    image: mysql
    environment:
      MYSQL_ROOT_PASSWORD: password
yaml
# Good: With depends_on
version: '3.8'
services:
  web:
    image: myapp-web
    ports:
      - "5000:5000"
    depends_on:
      - db
  db:
    image: mysql
    environment:
      MYSQL_ROOT_PASSWORD: password

Note: depends_on only waits for container to start, not for the service to be ready. Add health checks for proper dependency management:

yaml
# Better: With health checks
version: '3.8'
services:
  web:
    image: myapp-web
    ports:
      - "5000:5000"
    depends_on:
      db:
        condition: service_healthy
  db:
    image: mysql
    environment:
      MYSQL_ROOT_PASSWORD: password
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 5s
      timeout: 5s
      retries: 10
      start_period: 30s

Step 3: Add Wait Scripts

For services without health check support, use wait scripts:

yaml
# docker-compose.yml with wait-for-it
version: '3.8'
services:
  web:
    image: myapp-web
    command: ["./wait-for-it.sh", "db:3306", "--", "python", "app.py"]
    depends_on:
      - db
  db:
    image: mysql

Create or download wait-for-it script: ``bash # Download wait-for-it script curl -o wait-for-it.sh https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh chmod +x wait-for-it.sh

Using Docker's wait utility: ``yaml version: '3.8' services: web: image: myapp-web entrypoint: - /bin/sh - -c - | until nc -z db 3306; do echo "Waiting for db..." sleep 2 done exec python app.py depends_on: - db db: image: mysql

Step 4: Debug Configuration Issues

Run service interactively to debug:

```bash # Run specific service with logs docker-compose up <service-name>

# Run without starting dependencies docker-compose up --no-deps <service-name>

# Run with interactive shell docker-compose run --rm <service-name> /bin/bash

# Execute into running container docker-compose exec <service-name> /bin/bash

# Check environment variables docker-compose exec <service-name> env

# Check file contents docker-compose exec <service-name> cat /etc/config/app.conf

# Run with different command docker-compose run --rm <service-name> /bin/sh -c "debug-command" ```

Override command for debugging: ``bash # Override command to keep container running docker-compose run --rm --entrypoint /bin/bash <service-name>

Step 5: Fix Volume Mount Issues

Volume mount problems often cause failures:

```bash # Check volume mounts docker-compose exec <service-name> mount | grep /data

# Check if files exist docker-compose exec <service-name> ls -la /data

# Check permissions docker-compose exec <service-name> ls -la /data docker-compose exec <service-name> id

# Test without volumes docker-compose run --rm --no-deps -v /tmp/test:/data <service-name> ```

Fix volume permissions in docker-compose.yml: ``yaml services: app: image: myapp volumes: - ./data:/app/data user: "${UID}:${GID}"

Run with: ``bash UID=$(id -u) GID=$(id -g) docker-compose up

Step 6: Fix Resource Constraints

Services may fail due to resource limits:

yaml
# docker-compose.yml with resource limits
version: '3.8'
services:
  app:
    image: myapp
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 512M
        reservations:
          cpus: '0.25'
          memory: 256M

Check resource usage: ```bash # Check container resource usage docker stats

# Check specific container docker stats <container-id>

# Check memory limit in container docker inspect <container-id> --format='{{.HostConfig.Memory}}' ```

Step 7: Validate Docker Compose File

Check for syntax errors:

```bash # Validate compose file docker-compose config

# Validate with specific file docker-compose -f docker-compose.yml config

# Check for warnings docker-compose config --quiet

# View parsed configuration docker-compose config --services docker-compose config --volumes ```

Common configuration errors: ```yaml # Wrong: Invalid YAML indentation services: web: # Wrong indentation image: nginx

# Correct: Proper indentation services: web: # Correct indentation image: nginx

# Wrong: Invalid port format ports: - 5000 # Missing container port

# Correct: Port mapping format ports: - "5000:5000"

# Wrong: Missing quotes for special characters environment: PASSWORD: p@ss!word # Special characters cause issues

# Correct: Quote values with special characters environment: PASSWORD: "p@ss!word" ```

Step 8: Rebuild and Restart

Sometimes services need clean restart:

```bash # Stop all services docker-compose down

# Remove volumes for clean slate docker-compose down -v

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

# Start services fresh docker-compose up -d

# Force recreate containers docker-compose up -d --force-recreate

# Recreate specific service docker-compose up -d --force-recreate --no-deps <service-name> ```

Step 9: Debug Network Connectivity

Services can't start if they can't communicate:

```bash # Check network exists docker network ls | grep myapp

# Inspect network docker network inspect myapp_default

# Test connectivity between services docker-compose exec web ping db docker-compose exec web nc -zv db 3306

# Check DNS resolution docker-compose exec web nslookup db

# Check service addresses docker-compose exec web cat /etc/hosts ```

Fix network configuration: ```yaml # Explicit network definition version: '3.8' services: web: image: myapp-web networks: - frontend - backend db: image: mysql networks: - backend

networks: frontend: backend: ```

Verify the Fix

Confirm services start correctly:

```bash # Start services docker-compose up -d

# Check all services are running docker-compose ps

# Should show State as "Up" # Name Command State Ports # --------------------------------------------------- # myapp_db_1 docker-entrypoint.sh Up 3306/tcp # myapp_web_1 python app.py Up 0.0.0.0:5000->5000/tcp

# Check logs for successful startup docker-compose logs --tail=50

# Verify health checks passing docker inspect <container-id> --format='{{.State.Health.Status}}'

# Test service is responsive curl http://localhost:5000/health ```

All services should now show "Up" status and pass their health checks.