Docker has revolutionized how we deploy applications, but it's not without its challenges. After deploying multiple applications with Docker, I've encountered and solved many common problems. Here's what you need to know.
Common Docker Deployment Problems
1. Container Keeps Crashing / Exits Immediately
The Problem:
$ docker ps -a
CONTAINER ID STATUS
abc123 Exited (0) 2 seconds agoWhy It Happens:
- Application exits after starting
- No process keeps container running
- Application crashes on startup
The Fix:
# BAD - Container exits when command finishes
CMD ["node", "script.js"]
# GOOD - Keep container running
CMD ["node", "server.js"] # Server keeps running
# Or use a process manager
CMD ["npm", "start"]
# For development, use interactive mode
docker run -it myappCheck logs:
docker logs <container-id>
docker logs -f <container-id> # Follow logs2. Port Already in Use
The Problem:
Error: bind: address already in useWhy It Happens:
Another process is using the port, or another container is already using it.
The Fix:
# Find what's using the port
lsof -i :3000
# Or on Windows
netstat -ano | findstr :3000
# Stop the container using the port
docker ps
docker stop <container-id>
# Or use a different port
docker run -p 3001:3000 myapp
# Or remove all stopped containers
docker container prune3. Volume Mounting Not Working
The Problem:
Files in mounted volume don't appear in container, or changes aren't reflected.
Common Mistakes:
# BAD - Wrong path format on Windows
docker run -v C:Usersmeapp:/app myapp
# BAD - Relative path issues
docker run -v ./app:/app myappThe Fix:
# GOOD - Use absolute paths
docker run -v /absolute/path/to/app:/app myapp
# On Windows, use forward slashes or double backslashes
docker run -v C:/Users/me/app:/app myapp
# Use named volumes for production
docker volume create myapp-data
docker run -v myapp-data:/app/data myapp
# Check volume mounts
docker inspect <container-id> | grep Mounts4. "Cannot connect to Docker daemon"
The Problem:
Cannot connect to the Docker daemon. Is the docker daemon running?The Fix:
# Start Docker daemon
# On Linux:
sudo systemctl start docker
sudo systemctl enable docker # Start on boot
# On macOS/Windows:
# Start Docker Desktop application
# Check if Docker is running
docker ps
# Add user to docker group (Linux)
sudo usermod -aG docker $USER
# Log out and back in5. Out of Disk Space
The Problem:
no space left on deviceWhy It Happens:
Docker images, containers, and volumes accumulate over time.
The Fix:
# Clean up unused resources
docker system prune
# Remove all unused images, containers, networks
docker system prune -a
# Remove unused volumes (careful - deletes data!)
docker volume prune
# Check disk usage
docker system df
# Remove specific images
docker rmi <image-id>
# Remove stopped containers
docker container prune6. Environment Variables Not Working
The Problem:
Environment variables aren't available in the container.
Common Mistakes:
# BAD - Using ENV in Dockerfile (build-time only)
ENV NODE_ENV=productionThe Fix:
# GOOD - Pass env vars at runtime
docker run -e NODE_ENV=production myapp
# Or use .env file
docker run --env-file .env myapp
# In docker-compose.yml
services:
app:
environment:
- NODE_ENV=production
env_file:
- .envDockerfile:
# Use ARG for build-time variables
ARG NODE_ENV
ENV NODE_ENV=$NODE_ENV
# Build with:
docker build --build-arg NODE_ENV=production .7. Dockerfile Build Fails
Common Issues:
Issue 1: Cannot find package
npm ERR! code E404
npm ERR! 404 Not Found: package@versionFix:
# Make sure package.json is copied before npm install
COPY package*.json ./
RUN npm install
COPY . .Issue 2: Permission denied
Permission denied: /app/node_modulesFix:
# Create user and set permissions
RUN groupadd -r appuser && useradd -r -g appuser appuser
RUN chown -R appuser:appuser /app
USER appuserIssue 3: Build context too large
Error: build context is too largeFix:
# Add .dockerignore file
node_modules
.git
.env
*.log
dist
build8. Container Can't Connect to Database
The Problem:
Application in container can't reach database.
Why It Happens:
- Using `localhost` instead of service name
- Network isolation
- Wrong port
The Fix:
# docker-compose.yml
services:
app:
build: .
environment:
- DATABASE_URL=postgresql://user:pass@db:5432/mydb
# Use service name 'db', not 'localhost'
depends_on:
- db
db:
image: postgres:14
environment:
- POSTGRES_DB=mydb
- POSTGRES_USER=user
- POSTGRES_PASSWORD=passIn your application:
// BAD - localhost doesn't work in Docker
const dbUrl = 'postgresql://localhost:5432/mydb';
// GOOD - Use service name or host.docker.internal
const dbUrl = process.env.DATABASE_URL || 'postgresql://db:5432/mydb';
// Or for external database: 'postgresql://host.docker.internal:5432/mydb'9. Multi-Stage Build Issues
The Problem:
Final image is too large or missing files.
Common Mistakes:
# BAD - Copying from wrong stage
FROM node:16 AS builder
WORKDIR /app
COPY . .
RUN npm run build
FROM node:16
COPY . . # Wrong! Should copy from builderThe Fix:
# GOOD - Proper multi-stage build
FROM node:16 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
FROM node:16-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package*.json ./
CMD ["node", "dist/index.js"]10. Docker Compose Networking Issues
The Problem:
Services can't communicate with each other.
The Fix:
# docker-compose.yml
services:
app:
build: .
networks:
- mynetwork
db:
image: postgres:14
networks:
- mynetwork
networks:
mynetwork:
driver: bridgeCheck networking:
# List networks
docker network ls
# Inspect network
docker network inspect <network-name>
# Connect container to network
docker network connect <network-name> <container-id>Docker Best Practices
1. Use .dockerignore - Reduce build context size
2. Multi-stage builds - Smaller final images
3. Don't run as root - Create non-root user
4. Use specific tags - Don't use latest
5. Health checks - Monitor container health
6. Resource limits - Prevent resource exhaustion
FROM node:16-alpine
# Create non-root user
RUN addgroup -g 1001 -S nodejs && adduser -S nextjs -u 1001
WORKDIR /app
# Copy files
COPY --chown=nextjs:nodejs package*.json ./
RUN npm ci --only=production
COPY --chown=nextjs:nodejs . .
# Switch to non-root user
USER nextjs
# Health check
HEALTHCHECK --interval=30s --timeout=3s CMD node healthcheck.js || exit 1
CMD ["node", "server.js"]Debugging Docker Issues
Useful commands:
# Check container logs
docker logs <container-id>
docker logs -f <container-id> # Follow
# Execute command in running container
docker exec -it <container-id> /bin/sh
# Inspect container
docker inspect <container-id>
# Check resource usage
docker stats
# View Docker events
docker events
# Check Docker info
docker infoProduction Deployment Tips
1. Use orchestration - Docker Swarm or Kubernetes
2. Set resource limits - Prevent one container from consuming all resources
3. Use secrets - Don't hardcode credentials
4. Monitor containers - Set up logging and monitoring
5. Backup volumes - Regular backups of data volumes
6. Update regularly - Keep images updated for security
# docker-compose.prod.yml
services:
app:
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
reservations:
cpus: '0.25'
memory: 256M
secrets:
- db_passwordConclusion
Docker deployment issues are common but solvable. The key is to:
1. Understand the error - Read logs carefully
2. Check networking - Services need to communicate
3. Verify volumes - Paths and permissions matter
4. Monitor resources - Clean up regularly
5. Follow best practices - Security and performance
Most Docker problems come from:
- Network configuration
- Volume mounting
- Environment variables
- Resource limits
With these solutions, you should be able to fix most Docker deployment issues.