Примеры контейнеризации веб-приложений с Docker и best practices. Включает Dockerfile оптимизацию, multi-stage builds, Docker Compose и безопасность.
- ✅ Оптимизированные Dockerfile с multi-stage builds
- ✅ Docker Compose для разработки и продакшн
- ✅ Nginx reverse proxy конфигурация
- ✅ Безопасность контейнеров
- ✅ Мониторинг и логирование
- ✅ Автоматические обновления
- ✅ CI/CD интеграция
- Docker и Docker Compose
- Nginx reverse proxy
- Linux контейнеры
- API разработка
- Multi-stage builds
- Security scanning
docker-containerization/
├── web-app/
│ ├── Dockerfile # Оптимизированный Dockerfile
│ ├── Dockerfile.multi-stage # Multi-stage build
│ ├── docker-compose.yml # Development environment
│ ├── docker-compose.prod.yml # Production environment
│ ├── nginx.conf # Nginx configuration
│ ├── src/ # Application source code
│ │ ├── app.py # Python Flask app
│ │ ├── package.json # Node.js app
│ │ ├── requirements.txt # Python dependencies
│ │ └── static/ # Static files
│ └── tests/ # Application tests
├── api-service/
│ ├── Dockerfile # API service Dockerfile
│ ├── docker-compose.yml # API service compose
│ ├── src/ # API source code
│ │ ├── main.py # FastAPI application
│ │ ├── requirements.txt # Dependencies
│ │ └── models/ # Data models
│ └── tests/ # API tests
├── examples/
│ ├── multi-stage-build/ # Multi-stage examples
│ ├── optimization/ # Optimization examples
│ ├── security/ # Security examples
│ └── monitoring/ # Monitoring examples
├── scripts/
│ ├── build.sh # Build script
│ ├── deploy.sh # Deployment script
│ ├── security-scan.sh # Security scanning
│ └── cleanup.sh # Cleanup script
├── monitoring/
│ ├── prometheus.yml # Prometheus config
│ ├── grafana/ # Grafana dashboards
│ └── alerts/ # Alert rules
├── security/
│ ├── docker-security.md # Security best practices
│ ├── scan-results/ # Security scan results
│ └── policies/ # Security policies
└── docs/
├── best-practices.md # Docker best practices
├── optimization.md # Optimization guide
├── security.md # Security guide
└── troubleshooting.md # Troubleshooting guide
git clone https://github.com/twinleq/docker-containerization.git
cd docker-containerization# Запуск веб-приложения для разработки
cd web-app
docker-compose up -d
# Запуск API сервиса
cd ../api-service
docker-compose up -d# Сборка оптимизированных образов
./scripts/build.sh
# Развертывание в продакшн
./scripts/deploy.shFROM python:3.11-slim
WORKDIR /app
# Установка системных зависимостей
RUN apt-get update && apt-get install -y \
gcc \
&& rm -rf /var/lib/apt/lists/*
# Копирование и установка зависимостей
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Копирование приложения
COPY . .
# Создание непривилегированного пользователя
RUN useradd --create-home --shell /bin/bash app
USER app
# Открытие порта
EXPOSE 5000
# Запуск приложения
CMD ["python", "app.py"]# Stage 1: Build
FROM node:18-alpine AS builder
WORKDIR /app
# Копирование package.json и установка зависимостей
COPY package*.json ./
RUN npm ci --only=production
# Копирование исходного кода и сборка
COPY . .
RUN npm run build
# Stage 2: Production
FROM node:18-alpine AS production
WORKDIR /app
# Установка только production зависимостей
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force
# Копирование собранного приложения
COPY --from=builder /app/dist ./dist
# Создание пользователя
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
USER nextjs
# Открытие порта
EXPOSE 3000
# Запуск приложения
CMD ["node", "dist/server.js"]version: '3.8'
services:
web:
build: .
ports:
- "3000:3000"
volumes:
- .:/app
- /app/node_modules
environment:
- NODE_ENV=development
depends_on:
- db
- redis
api:
build: ./api-service
ports:
- "8000:8000"
environment:
- DATABASE_URL=postgresql://user:pass@db:5432/app
- REDIS_URL=redis://redis:6379
depends_on:
- db
- redis
db:
image: postgres:15-alpine
environment:
- POSTGRES_DB=app
- POSTGRES_USER=user
- POSTGRES_PASSWORD=pass
volumes:
- postgres_data:/var/lib/postgresql/data
redis:
image: redis:7-alpine
volumes:
- redis_data:/data
nginx:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
depends_on:
- web
- api
volumes:
postgres_data:
redis_data:version: '3.8'
services:
web:
build:
context: .
dockerfile: Dockerfile.multi-stage
restart: unless-stopped
environment:
- NODE_ENV=production
depends_on:
- db
- redis
networks:
- app-network
api:
build:
context: ./api-service
dockerfile: Dockerfile
restart: unless-stopped
environment:
- DATABASE_URL=postgresql://user:pass@db:5432/app
- REDIS_URL=redis://redis:6379
depends_on:
- db
- redis
networks:
- app-network
nginx:
image: nginx:alpine
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.prod.conf:/etc/nginx/nginx.conf
- ./ssl:/etc/nginx/ssl
depends_on:
- web
- api
networks:
- app-network
db:
image: postgres:15-alpine
restart: unless-stopped
environment:
- POSTGRES_DB=app
- POSTGRES_USER=user
- POSTGRES_PASSWORD=pass
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- app-network
redis:
image: redis:7-alpine
restart: unless-stopped
volumes:
- redis_data:/data
networks:
- app-network
networks:
app-network:
driver: bridge
volumes:
postgres_data:
redis_data:events {
worker_connections 1024;
}
http {
upstream web_backend {
server web:3000;
}
upstream api_backend {
server api:8000;
}
server {
listen 80;
server_name localhost;
# Web application
location / {
proxy_pass http://web_backend;
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;
}
# API endpoints
location /api/ {
proxy_pass http://api_backend/;
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;
}
# Static files
location /static/ {
alias /var/www/static/;
expires 1y;
add_header Cache-Control "public, immutable";
}
}
}- Используйте непривилегированных пользователей
- Минимизируйте образы (alpine, distroless)
- Сканируйте на уязвимости
- Используйте multi-stage builds
- Не храните секреты в образах
- Регулярно обновляйте базовые образы
# Сканирование на уязвимости
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy image your-image:latest
# Анализ зависимостей
docker run --rm -v $(pwd):/app \
securecodewarrior/docker-security-scan /appfrom prometheus_client import Counter, Histogram, start_http_server
REQUEST_COUNT = Counter('http_requests_total', 'Total HTTP requests', ['method', 'endpoint'])
REQUEST_LATENCY = Histogram('http_request_duration_seconds', 'HTTP request latency')
@app.before_request
def before_request():
request.start_time = time.time()
@app.after_request
def after_request(response):
request_latency = time.time() - request.start_time
REQUEST_LATENCY.observe(request_latency)
REQUEST_COUNT.labels(method=request.method, endpoint=request.endpoint).inc()
return responseimport logging
import json
# Настройка структурированного логирования
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
# Структурированные логи
logger.info(json.dumps({
'event': 'request_completed',
'method': request.method,
'endpoint': request.endpoint,
'status_code': response.status_code,
'duration': request_latency
}))name: Docker Build and Deploy
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build Docker image
run: docker build -t your-app:${{ github.sha }} .
- name: Security scan
run: docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy image your-app:${{ github.sha }}
- name: Push to registry
run: |
docker tag your-app:${{ github.sha }} your-registry/your-app:latest
docker push your-registry/your-app:latest
- name: Deploy to production
run: |
docker-compose -f docker-compose.prod.yml up -d-
Большой размер образа
# Используйте multi-stage builds # Очищайте кэш пакетного менеджера # Используйте .dockerignore
-
Медленная сборка
# Используйте Docker layer caching # Оптимизируйте порядок команд # Используйте BuildKit
-
Проблемы с сетью
# Проверьте Docker networks docker network ls docker network inspect bridge
# Анализ размера образа
docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}"
# Просмотр слоев
docker history your-image:latest
# Мониторинг контейнеров
docker stats
# Логи контейнеров
docker logs -f container-name
# Вход в контейнер
docker exec -it container-name /bin/bashMIT License - см. файл LICENSE
Ромадановский Виталий Денисович - Junior DevOps Engineer
- GitHub: @twinleq
- Email: twinleq@bk.ru
- Website: https://romadanovsky.ru