Cloud SolutionsNổi bật
Docker Containerization Guide
Do Van G
DevOps Engineer
6 tháng 1, 202506-01
15p
1,567 lượt xem2k
#Docker#DevOps#Containerization#Deployment
Docker Containerization Guide
Làm chủ Docker containerization cho development và production.
Dockerfile cơ bản
DOCKERFILE
# Multi-stage build for Node.js app
# Stage 1: Build stage
FROM node:18-alpine AS builder
WORKDIR /app
# Copy package files
COPY package*.json ./
COPY yarn.lock ./
# Install dependencies
RUN yarn install --frozen-lockfile
# Copy source code
COPY . .
# Build the application
RUN yarn build
# Stage 2: Production stage
FROM node:18-alpine AS production
# Create non-root user
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
WORKDIR /app
# Copy package files
COPY package*.json ./
COPY yarn.lock ./
# Install only production dependencies
RUN yarn install --production --frozen-lockfile && yarn cache clean
# Copy built application from builder stage
COPY /app/.next ./.next
COPY /app/public ./public
# Switch to non-root user
USER nextjs
# Expose port
EXPOSE 3000
# Health check
HEALTHCHECK \
CMD curl -f http://localhost:3000/api/health || exit 1
# Start the application
CMD ["yarn", "start"]
Docker Compose Setup
YAML
# docker-compose.yml
version: '3.8'
services:
# Frontend React App
frontend:
build:
context: ./frontend
dockerfile: Dockerfile
target: production
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- REACT_APP_API_URL=http://backend:5000
depends_on:
- backend
networks:
- app-network
restart: unless-stopped
# Backend Node.js API
backend:
build:
context: ./backend
dockerfile: Dockerfile
ports:
- "5000:5000"
environment:
- NODE_ENV=production
- MONGODB_URI=mongodb://mongo:27017/myapp
- JWT_SECRET=your-super-secret-jwt-key
- REDIS_URL=redis://redis:6379
depends_on:
- mongo
- redis
volumes:
- ./backend/uploads:/app/uploads
networks:
- app-network
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:5000/health"]
interval: 30s
timeout: 10s
retries: 3
# MongoDB Database
mongo:
image: mongo:6.0
ports:
- "27017:27017"
environment:
- MONGO_INITDB_ROOT_USERNAME=admin
- MONGO_INITDB_ROOT_PASSWORD=password123
- MONGO_INITDB_DATABASE=myapp
volumes:
- mongo-data:/data/db
- ./mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro
networks:
- app-network
restart: unless-stopped
# Redis Cache
redis:
image: redis:7-alpine
ports:
- "6379:6379"
command: redis-server --appendonly yes --requirepass redis123
volumes:
- redis-data:/data
networks:
- app-network
restart: unless-stopped
# Nginx Load Balancer
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ./nginx/ssl:/etc/nginx/ssl:ro
depends_on:
- frontend
- backend
networks:
- app-network
restart: unless-stopped
volumes:
mongo-data:
redis-data:
networks:
app-network:
driver: bridge
Nginx Configuration
NGINX
# nginx/nginx.conf
events {
worker_connections 1024;
}
http {
upstream backend {
server backend:5000;
}
upstream frontend {
server frontend:3000;
}
# Rate limiting
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=login:10m rate=1r/s;
server {
listen 80;
server_name localhost;
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
# Frontend routes
location / {
proxy_pass http://frontend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
}
# API routes
location /api/ {
limit_req zone=api burst=20 nodelay;
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
# Timeout settings
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
# Auth endpoints with stricter rate limiting
location /api/auth/ {
limit_req zone=login burst=5 nodelay;
proxy_pass http://backend;
}
# Static files caching
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
proxy_pass http://frontend;
expires 1y;
add_header Cache-Control "public, immutable";
}
}
}
Docker Commands và Scripts
Bash
#!/bin/bash
# scripts/deploy.sh
set -e
echo "🚀 Starting deployment..."
# Build and push images
echo "📦 Building Docker images..."
docker-compose build --no-cache
# Run tests
echo "🧪 Running tests..."
docker-compose run --rm backend npm test
docker-compose run --rm frontend npm test
# Deploy to production
echo "🌟 Deploying to production..."
docker-compose down
docker-compose up -d
# Health check
echo "🏥 Performing health check..."
sleep 30
if curl -f http://localhost/api/health; then
echo "✅ Deployment successful!"
else
echo "❌ Deployment failed!"
docker-compose logs
exit 1
fi
# Cleanup old images
echo "🧹 Cleaning up..."
docker image prune -f
echo "🎉 Deployment completed successfully!"
Bash
#!/bin/bash
# scripts/backup.sh
BACKUP_DIR="/backups/$(date +%Y%m%d_%H%M%S)"
mkdir -p $BACKUP_DIR
echo "📦 Creating database backup..."
docker-compose exec mongo mongodump --out /tmp/backup
docker-compose cp mongo:/tmp/backup $BACKUP_DIR/mongo
echo "💾 Creating volume backup..."
docker run --rm -v mongo-data:/data -v $BACKUP_DIR:/backup alpine tar czf /backup/mongo-volume.tar.gz -C /data .
echo "✅ Backup completed: $BACKUP_DIR"
Development Docker Setup
YAML
# docker-compose.dev.yml
version: '3.8'
services:
frontend:
build:
context: ./frontend
dockerfile: Dockerfile.dev
ports:
- "3000:3000"
volumes:
- ./frontend:/app
- /app/node_modules
environment:
- REACT_APP_API_URL=http://localhost:5000
- CHOKIDAR_USEPOLLING=true
backend:
build:
context: ./backend
dockerfile: Dockerfile.dev
ports:
- "5000:5000"
- "9229:9229" # Debug port
volumes:
- ./backend:/app
- /app/node_modules
environment:
- NODE_ENV=development
- DEBUG=app:*
command: npm run dev:debug
DOCKERFILE
# Dockerfile.dev
FROM node:18-alpine
WORKDIR /app
# Install dependencies
COPY package*.json ./
RUN npm ci
# Copy source
COPY . .
# Development server with hot reload
CMD ["npm", "run", "dev"]
Best Practice: Luôn sử dụng multi-stage builds và non-root users trong production!
Kết luận
Docker giúp standardize development environment và deploy applications một cách consistent.
Do Van G
DevOps Engineer chuyên về containerization và CI/CD.