Resolve Docker Container Networking Issues
Problem
Docker containers cannot communicate with each other or external services, resulting in connection timeouts and application failures.
Root Cause
Container networking issues typically stem from incorrect network configuration, port mapping problems, firewall restrictions, or DNS resolution failures within the Docker environment.
Solution
Diagnose and fix Docker networking step by step:
Step 1: Understand Docker Networks
# List all Docker networks
docker network ls
# Inspect default bridge network
docker network inspect bridge
# Create custom bridge network
docker network create --driver bridge mynetwork
# Connect container to custom network
docker network connect mynetwork mycontainer
Step 2: Fix Container-to-Container Communication
# docker-compose.yml - Proper network setup
version: '3.8'
services:
web:
build: .
ports:
- "3000:3000"
networks:
- app-network
environment:
- API_URL=http://api:8000 # Use service name as hostname
depends_on:
- api
- database
api:
build: ./api
ports:
- "8000:8000"
networks:
- app-network
environment:
- DATABASE_URL=postgresql://user:pass@database:5432/mydb
depends_on:
- database
database:
image: postgres:13
environment:
- POSTGRES_DB=mydb
- POSTGRES_USER=user
- POSTGRES_PASSWORD=pass
networks:
- app-network
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
app-network:
driver: bridge
volumes:
postgres_data:
Step 3: Debug Network Connectivity
# Test container connectivity
docker exec -it container_name ping api
docker exec -it container_name nslookup api
docker exec -it container_name curl http://api:8000/health
# Check if ports are listening
docker exec -it container_name netstat -tlnp
docker exec -it container_name ss -tlnp
# Test external connectivity
docker exec -it container_name ping google.com
docker exec -it container_name curl https://api.github.com
Step 4: Fix Port Mapping Issues
# ❌ Wrong - conflicting port mappings
docker run -p 3000:3000 app1
docker run -p 3000:3000 app2 # Will fail
# ✅ Correct - use different host ports
docker run -p 3000:3000 app1
docker run -p 3001:3000 app2
# Check what ports are in use
docker ps --format "table {{.Names}}\t{{.Ports}}"
netstat -tlnp | grep :3000
Step 5: Application Configuration for Docker
// Node.js app configuration
const express = require('express');
const app = express();
// ❌ Wrong - hardcoded localhost
const API_URL = 'http://localhost:8000';
// ✅ Correct - use environment variables and service names
const API_URL = process.env.API_URL || 'http://api:8000';
// Bind to all interfaces, not just localhost
const PORT = process.env.PORT || 3000;
app.listen(PORT, '0.0.0.0', () => {
console.log(`Server running on port ${PORT}`);
});
Step 6: Dockerfile Best Practices
FROM node:16-alpine
# Create app directory
WORKDIR /usr/src/app
# Copy package files
COPY package*.json ./
# Install dependencies
RUN npm ci --only=production
# Create non-root user
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
# Copy app source
COPY --chown=nextjs:nodejs . .
# Switch to non-root user
USER nextjs
# Expose port
EXPOSE 3000
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3000/health || exit 1
# Start application
CMD ["npm", "start"]