You run docker start container-name or docker-compose up, and your container immediately exits or refuses to start. Sound familiar?
Docker container startup failures are common but can be tricky to debug. This guide covers the most frequent causes and how to fix them systematically.
Step 1: Check Container Status and Logs
First, understand what's happening:
# See all containers (including stopped ones)
docker ps -a
# Check container logs
docker logs container-name
# Follow logs in real-time
docker logs -f container-name
# See last 50 lines
docker logs --tail 50 container-name
• "Exited (0)" = Container ran and finished successfully
• "Exited (1)" or higher = Container crashed with an error
• "Restarting" = Container keeps crashing and Docker is auto-restarting it
Problem 1: Port Already in Use
One of the most common errors: Bind for 0.0.0.0:80 failed: port is already allocated
Finding Port Conflicts:
sudo ss -tlnp | grep :80
# Or
sudo lsof -i :80
Resolving Port Conflicts:
Option 1: Stop the conflicting service
sudo systemctl stop nginx # If nginx is using port 80
docker stop other-container # If another container is using it
Option 2: Change your container's port mapping
# Instead of 80:80, use a different host port
docker run -p 8080:80 image-name
Or in docker-compose.yml:
ports:
- "8080:80" # Host:Container
Problem 2: Permission Denied / Volume Mount Issues
Error: Permission denied or mkdir: cannot create directory: Permission denied
Common Permission Issue Causes:
1. SELinux blocking volume mounts:
# Add :z or :Z to volume mounts
docker run -v /host/path:/container/path:z image-name
# Or in docker-compose.yml:
volumes:
- /host/path:/container/path:z
2. Wrong file permissions on host:
# Check permissions
ls -la /host/path
# Fix ownership (use the UID your container runs as)
sudo chown -R 1000:1000 /host/path
# Or make it world-writable (less secure)
sudo chmod -R 777 /host/path
3. Directory doesn't exist:
mkdir -p /host/path
docker run -v /host/path:/container/path image-name
Problem 3: Container Exits Immediately
Your container starts and immediately exits with code 0 or 1.
Why Containers Exit: No Foreground Process
Docker containers need a process running in the foreground. If your startup command finishes or runs in the background, the container exits.
Bad examples:
CMD ["nginx"] # Wrong - nginx daemonizes
CMD ["./startup.sh"] # Wrong if script exits
Good examples:
CMD ["nginx", "-g", "daemon off;"] # Run nginx in foreground
CMD ["node", "server.js"] # Node stays in foreground
CMD ["python", "app.py"] # Python stays in foreground
Debug with interactive mode:
# Override the entrypoint to investigate
docker run -it --entrypoint /bin/bash image-name
# Once inside, run commands manually to see what fails
Problem 4: Missing Environment Variables
Your app crashes because required environment variables aren't set.
Checking Container Environment Variables:
docker inspect container-name | grep -A 20 Env
Passing Environment Variables:
# Via command line
docker run -e DATABASE_URL="postgres://..." image-name
# Via env file
docker run --env-file .env image-name
# In docker-compose.yml:
environment:
- DATABASE_URL=postgres://...
- API_KEY=secret
# Or use env_file:
env_file:
- .env
Problem 5: Resource Limits (Memory/CPU)
Container is killed because it exceeds memory limits.
Check if the container was OOM (Out of Memory) killed:
docker inspect container-name | grep -i oom
Fixing Resource Limit Issues:
1. Increase memory limit:
# Allow 2GB of RAM
docker run -m 2g image-name
# In docker-compose.yml:
deploy:
resources:
limits:
memory: 2G
2. Check server resources:
free -h # Check available memory
docker stats # See real-time container resource usage
Problem 6: Dependency Container Not Ready
Your app container starts before the database container is ready, causing connection failures.
Managing Container Dependencies:
version: '3.8'
services:
database:
image: postgres:14
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5
app:
depends_on:
database:
condition: service_healthy
environment:
- DATABASE_URL=postgres://database:5432/db
Or use a wait-for script in your application.
Problem 7: Image Pull Failures
Error: manifest unknown or pull access denied
Fixing Image Pull Errors:
# Login to Docker Hub
docker login
# For private registries
docker login registry.example.com
# Pull with full registry path
docker pull registry.example.com/image:tag
# Check if image exists locally
docker images | grep image-name
Docker Debugging Driving You Crazy?
VPS Commander provides pre-built Docker workflows: check container status, view logs, restart services, and manage resources - all from a clean web interface. No more memorizing Docker commands.
Try VPS Commander - $2.99/moAdvanced Debugging Techniques
1. Inspect container configuration:
docker inspect container-name
2. Check Docker daemon logs:
sudo journalctl -u docker -f
3. Run with verbose output:
docker-compose up --verbose
4. Check events:
docker events &
docker start container-name
5. Exec into a running container:
docker exec -it container-name /bin/bash
Quick Troubleshooting Checklist
- ✅ Check logs:
docker logs container-name - ✅ Check port conflicts:
sudo ss -tlnp | grep :port - ✅ Check volume permissions:
ls -la /host/path - ✅ Verify environment variables:
docker inspect - ✅ Check resource usage:
docker stats - ✅ Test image manually:
docker run -it --entrypoint /bin/bash image-name - ✅ Check Docker daemon:
sudo systemctl status docker
Prevention Best Practices
- Always check logs first - they contain 90% of the answers
- Use healthchecks in your docker-compose.yml
- Set resource limits to prevent one container from killing others
- Use specific image tags (not "latest") for reproducibility
- Test locally before deploying to production
- Keep volumes backed up - data in volumes persists
Conclusion
Most Docker container startup issues fall into these categories:
- Port conflicts
- Permission/volume issues
- Missing environment variables
- Resource limits
- Application errors
The key is to always check the logs first - they'll tell you exactly what went wrong. From there, use this guide to systematically eliminate potential causes.