Docker Compose
Docker Compose nima?
Docker Compose - bu multi-container Docker ilovalarni aniqlash va ishga tushirish uchun tool hisoblanadi. U YAML fayli orqali ilovangizning barcha service'larini konfiguratsiya qilish imkonini beradi.
Docker Compose'ning afzalliklari:
- Declarative Configuration: YAML orqali infrastructure as code
- Multi-container Management: Bir buyruq bilan ko'plab containerlarni boshqarish
- Service Discovery: Container'lar o'rtasida avtomatik networking
- Environment Management: Turli muhitlar uchun alohida konfiguratsiyalar
- Development Workflow: Local development'ni soddalashtirish
Docker vs Docker Compose:
| Docker | Docker Compose |
|---|---|
| Bitta container | Multi-container |
| Manual networking | Avtomatik networking |
| Manual volume management | Declarative volumes |
| Complex commands | Simple YAML |
| Individual containers | Service orchestration |
Docker Compose O'rnatish
Linux'da O'rnatish
# Docker Compose v2 (plugin sifatida)
sudo apt-get update
sudo apt-get install docker-compose-plugin
# Versiyani tekshirish
docker compose version
# Eski standalone versiya (tavsiya etilmaydi)
sudo curl -L "https://github.com/docker/compose/releases/download/v2.24.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
macOS va Windows
Docker Desktop bilan birga keladi, alohida o'rnatish shart emas.
Compose File Syntax
Basic Structure
# docker-compose.yml
version: '3.8' # Compose file format version
services:
web:
# Service configuration
db:
# Service configuration
volumes:
# Named volumes
networks:
# Custom networks
Version Compatibility
# Version 3.8 (tavsiya etiladi)
version: '3.8'
# Version mapping:
# 3.8 - Docker Engine 19.03.0+
# 3.7 - Docker Engine 18.06.0+
# 3.6 - Docker Engine 18.02.0+
Services Configuration
1. Image-based Services
Public Image
services:
redis:
image: redis:7-alpine
ports:
- "6379:6379"
postgres:
image: postgres:15
environment:
POSTGRES_PASSWORD: secret
POSTGRES_DB: myapp
ports:
- "5432:5432"
Private Registry
services:
app:
image: myregistry.com/myapp:latest
# Registry authentication
# docker login myregistry.com
2. Build-based Services
Simple Build
services:
web:
build: . # Current directory'dagi Dockerfile
ports:
- "3000:3000"
Advanced Build
services:
web:
build:
context: . # Build context
dockerfile: Dockerfile.prod # Custom Dockerfile
args: # Build arguments
NODE_VERSION: 18
BUILD_ENV: production
target: production # Multi-stage build target
ports:
- "3000:3000"
Build Options
services:
app:
build:
context: ./app
dockerfile: Dockerfile
cache_from:
- node:18-alpine
shm_size: '2gb'
network: host
3. Environment Variables
Direct Definition
services:
app:
image: node:18
environment:
NODE_ENV: production
API_KEY: abc123
DEBUG: "true"
Environment File
# .env fayl
DATABASE_URL=postgresql://user:pass@db:5432/myapp
REDIS_URL=redis://redis:6379
SECRET_KEY=your-secret-key
# docker-compose.yml
services:
app:
image: myapp:latest
env_file:
- .env
- .env.local
Environment Substitution
# Host environment variable'lardan foydalanish
services:
app:
image: myapp:${VERSION:-latest}
environment:
DATABASE_URL: ${DATABASE_URL}
ports:
- "${APP_PORT:-3000}:3000"
4. Ports va Networking
Port Mapping
services:
web:
image: nginx
ports:
- "80:80" # host:container
- "443:443"
- "127.0.0.1:8080:80" # specific interface
- "3000-3005:3000" # port range
Expose (internal networking)
services:
api:
image: myapi:latest
expose:
- "8000" # Faqat boshqa service'lar uchun
worker:
image: myworker:latest
# api:8000 orqali API'ga murojaat qiladi
5. Volumes
Named Volumes
services:
db:
image: postgres:15
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: secret
volumes:
postgres_data:
driver: local
Bind Mounts
services:
web:
image: nginx
volumes:
- ./html:/usr/share/nginx/html:ro # read-only
- ./nginx.conf:/etc/nginx/nginx.conf
- /var/log/nginx:/var/log/nginx
Volume Options
services:
app:
image: myapp:latest
volumes:
- type: bind
source: ./app
target: /app
read_only: true
- type: volume
source: app_data
target: /data
volume:
nocopy: true
- type: tmpfs
target: /tmp
tmpfs:
size: 100M
volumes:
app_data:
driver: local
driver_opts:
type: nfs
o: addr=192.168.1.100,rw
device: ":/path/to/data"
6. Dependencies va Startup Order
depends_on
services:
web:
image: myapp:latest
depends_on:
- db
- redis
db:
image: postgres:15
redis:
image: redis:7-alpine
Healthcheck Dependencies
services:
web:
image: myapp:latest
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
db:
image: postgres:15
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
environment:
POSTGRES_PASSWORD: secret
7. Restart Policies
services:
web:
image: nginx
restart: always # always, unless-stopped, on-failure, no
worker:
image: myworker:latest
restart: on-failure:3 # 3 marta restart qilish
temp_service:
image: temp:latest
restart: "no" # Restart qilmaslik
8. Resource Limits
services:
app:
image: myapp:latest
deploy:
resources:
limits:
cpus: '2.0'
memory: 1G
reservations:
cpus: '1.0'
memory: 512M
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
db:
image: postgres:15
restart: always
environment:
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
secrets:
- db_password
volumes:
- postgres_data:/var/lib/postgresql/data
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
secrets:
db_password:
external: true
volumes:
postgres_data:
driver: local
networks:
default:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/16
2. CI/CD Integration
GitLab CI Pipeline
# .gitlab-ci.yml
stages:
- build
- test
- deploy
variables:
DOCKER_DRIVER: overlay2
COMPOSE_PROJECT_NAME: myapp
build:
stage: build
script:
- docker compose build
- docker compose push
only:
- main
- develop
test:
stage: test
script:
- docker compose -f docker-compose.yml -f docker-compose.test.yml up -d
- docker compose exec -T web npm test
- docker compose exec -T web npm run e2e
after_script:
- docker compose down -v
only:
- main
- develop
deploy_staging:
stage: deploy
script:
- docker compose -f docker-compose.yml -f docker-compose.staging.yml up -d
environment:
name: staging
url: https://staging.myapp.com
only:
- develop
deploy_production:
stage: deploy
script:
- docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
environment:
name: production
url: https://myapp.com
when: manual
only:
- main
GitHub Actions
# .github/workflows/deploy.yml
name: Deploy with Docker Compose
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Run tests
run: |
docker compose -f docker-compose.yml -f docker-compose.test.yml up -d
docker compose exec -T web npm test
docker compose down -v
deploy:
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v3
- name: Deploy to production
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
KEY: ${{ secrets.PRODUCTION_SSH_KEY }}
run: |
echo "$KEY" | ssh-add -
ssh $USER@$HOST "cd /opt/myapp && git pull && docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d"
3. Backup va Recovery
Database Backup
# backup/docker-compose.yml
version: '3.8'
services:
postgres-backup:
image: postgres:15
volumes:
- ./backups:/backups
- postgres_data:/var/lib/postgresql/data:ro
environment:
PGPASSWORD: ${DB_PASSWORD}
command: |
bash -c "
while true; do
pg_dump -h db -U ${DB_USER} -d ${DB_NAME} > /backups/backup_$(date +%Y%m%d_%H%M%S).sql
find /backups -name '*.sql' -mtime +7 -delete
sleep 86400
done
"
depends_on:
- db
restart: always
file-backup:
image: alpine:latest
volumes:
- app_data:/data:ro
- ./backups:/backups
command: |
sh -c "
while true; do
tar -czf /backups/files_$(date +%Y%m%d_%H%M%S).tar.gz -C /data .
find /backups -name 'files_*.tar.gz' -mtime +7 -delete
sleep 86400
done
"
restart: always
volumes:
postgres_data:
external: true
app_data:
external: true
Backup Script
#!/bin/bash
# backup.sh
set -e
PROJECT_NAME="myapp"
BACKUP_DIR="/opt/backups"
DATE=$(date +%Y%m%d_%H%M%S)
# Database backup
docker compose exec -T db pg_dump -U postgres myapp > "${BACKUP_DIR}/db_${DATE}.sql"
# Files backup
docker run --rm \
-v myapp_data:/data:ro \
-v ${BACKUP_DIR}:/backup \
alpine:latest \
tar -czf /backup/files_${DATE}.tar.gz -C /data .
# Volume backup
docker run --rm \
-v myapp_postgres_data:/volume:ro \
-v ${BACKUP_DIR}:/backup \
alpine:latest \
tar -czf /backup/postgres_volume_${DATE}.tar.gz -C /volume .
# Cleanup old backups (keep last 7 days)
find ${BACKUP_DIR} -name "*.sql" -mtime +7 -delete
find ${BACKUP_DIR} -name "*.tar.gz" -mtime +7 -delete
echo "Backup completed: ${DATE}"
Troubleshooting
1. Common Issues
Service Dependencies
# Issue: Service starts before dependencies
# Solution: Use healthcheck conditions
# Muammo
services:
web:
depends_on:
- db # Faqat start order, readiness emas
# Hal qilish
services:
web:
depends_on:
db:
condition: service_healthy
db:
healthcheck:
test: ["CMD-SHELL", "pg_isready"]
interval: 10s
timeout: 5s
retries: 5
Port Conflicts
# Issue: Port already in use
# Error: bind: address already in use
# Tekshirish
sudo netstat -tlnp | grep :80
lsof -i :80
# Hal qilish
# 1. Boshqa port ishlatish
ports:
- "8080:80"
# 2. Service'ni to'xtatish
sudo systemctl stop apache2
Volume Permissions
# Issue: Permission denied in volumes
# Hal qilish
# 1. User mapping
services:
app:
user: "${UID}:${GID}"
# 2. Init container
services:
init:
image: alpine:latest
volumes:
- app_data:/data
command: chown -R 1000:1000 /data
app:
depends_on:
- init
user: "1000:1000"
2. Debugging Commands
Service Investigation
# Service logs batafsil
docker compose logs --details web
# Container ichidagi environment
docker compose exec web env
# Container ichidagi jarayonlar
docker compose exec web ps aux
# Network connectivity test
docker compose exec web ping db
docker compose exec web telnet db 5432
# DNS resolution
docker compose exec web nslookup db
Configuration Debugging
# Configuration validation
docker compose config
# Resolved configuration ko'rish
docker compose config --resolve-envs
# Service definitions
docker compose config --services
# Environment variables
docker compose config --variables
# Debug mode
COMPOSE_LOG_LEVEL=DEBUG docker compose up
3. Performance Issues
Resource Monitoring
# Container resource usage
docker compose exec web cat /proc/meminfo
docker compose exec web cat /proc/cpuinfo
# Docker stats
docker stats $(docker compose ps -q)
# Disk usage
docker compose exec web df -h
docker system df
Network Debugging
# Network inspection
docker network ls
docker network inspect myapp_default
# Port mapping tekshirish
docker compose port web 80
# Traffic monitoring
docker compose exec web tcpdump -i eth0
Advanced Features
1. Profiles
# docker-compose.yml with profiles
version: '3.8'
services:
web:
image: myapp:latest
profiles: ["web"]
api:
image: myapi:latest
profiles: ["api"]
worker:
image: myworker:latest
profiles: ["worker"]
db:
image: postgres:15
# Har doim ishga tushadi
monitoring:
image: grafana/grafana
profiles: ["monitoring", "dev"]
# Usage:
# docker compose --profile web up # Faqat web va db
# docker compose --profile api up # Faqat api va db
# docker compose --profile dev up # web, api, worker, db, monitoring
2. Extensions
Compose Extensions
# docker-compose.yml
version: '3.8'
# Extension fields (reusable configurations)
x-common-variables: &common-variables
NODE_ENV: production
LOG_LEVEL: info
x-restart-policy: &restart-policy
restart: always
x-logging: &logging
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
services:
web:
image: myapp:latest
environment:
<<: *common-variables
PORT: 3000
<<: *restart-policy
<<: *logging
api:
image: myapi:latest
environment:
<<: *common-variables
PORT: 8000
<<: *restart-policy
<<: *logging
3. Service Mesh Integration
Traefik Integration
# docker-compose.yml with Traefik
version: '3.8'
services:
traefik:
image: traefik:v2.10
command:
- "--api.insecure=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.myresolver.acme.tlschallenge=true"
- "--certificatesresolvers.myresolver.acme.email=admin@example.com"
- "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- letsencrypt:/letsencrypt
networks:
- web
web:
image: myapp:latest
labels:
- "traefik.enable=true"
- "traefik.http.routers.web.rule=Host(`myapp.com`)"
- "traefik.http.routers.web.entrypoints=websecure"
- "traefik.http.routers.web.tls.certresolver=myresolver"
- "traefik.http.services.web.loadbalancer.server.port=3000"
networks:
- web
volumes:
letsencrypt:
networks:
web:
external: true
Docker Compose Best Practices
1. File Organization
# Recommended project structure
project/
├── docker-compose.yml # Base configuration
├── docker-compose.override.yml # Local development overrides
├── docker-compose.prod.yml # Production configuration
├── docker-compose.test.yml # Test configuration
├── .env # Environment variables
├── .env.example # Environment template
├── .dockerignore # Docker ignore file
├── Dockerfile # Application Dockerfile
├── docker/ # Docker-related files
│ ├── nginx/
│ │ └── nginx.conf
│ ├── postgres/
│ │ └── init.sql
│ └── scripts/
│ ├── backup.sh
│ └── restore.sh
└── README.md # Project documentation
2. Environment Variables
# Good practices for environment variables
services:
app:
image: myapp:latest
environment:
# Required variables (with defaults)
NODE_ENV: ${NODE_ENV:-development}
PORT: ${PORT:-3000}
# Database configuration
DB_HOST: ${DB_HOST:-db}
DB_PORT: ${DB_PORT:-5432}
DB_NAME: ${DB_NAME:?err} # Required variable
DB_USER: ${DB_USER:?err}
# Optional features
ENABLE_METRICS: ${ENABLE_METRICS:-false}
REDIS_URL: ${REDIS_URL:-redis://redis:6379}
3. Security Practices
# Security-focused configuration
version: '3.8'
services:
app:
image: myapp:latest
# Security configurations
user: "1000:1000" # Non-root user
read_only: true # Read-only filesystem
# Minimal capabilities
cap_drop:
- ALL
cap_add:
- NET_BIND_SERVICE
# Security options
security_opt:
- no-new-privileges:true
- apparmor:docker-default
# Tmpfs for writable directories
tmpfs:
- /tmp:noexec,nosuid,size=100m
- /var/run:noexec,nosuid,size=50m
# Resource limits
deploy:
resources:
limits:
cpus: '1.0'
memory: 512M
reservations:
cpus: '0.5'
memory: 256M
# Health monitoring
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
# Database with security
db:
image: postgres:15
# Secrets instead of environment variables
secrets:
- postgres_password
environment:
POSTGRES_PASSWORD_FILE: /run/secrets/postgres_password
POSTGRES_USER: appuser
POSTGRES_DB: appdb
# Isolated network
networks:
- backend
# No external access
# ports: [] # Don't expose ports externally
secrets:
postgres_password:
file: ./secrets/postgres_password.txt
networks:
backend:
driver: bridge
internal: true # No internet access
4. Performance Optimization
# Performance-optimized configuration
version: '3.8'
services:
app:
image: myapp:latest
# Optimized resource allocation
deploy:
resources:
limits:
cpus: '2.0'
memory: 1G
reservations:
cpus: '1.0'
memory: 512M
# Sysctls for performance
sysctls:
net.core.somaxconn: 65536
net.ipv4.tcp_max_syn_backlog: 65536
# Ulimits
ulimits:
nproc: 65535
nofile:
soft: 65535
hard: 65535
# Volume optimizations
volumes:
- type: tmpfs
target: /tmp
tmpfs:
size: 512M
- type: volume
source: app_cache
target: /app/cache
volume:
nocopy: true
volumes:
app_cache:
driver: local
driver_opts:
type: tmpfs
device: tmpfs
5. Monitoring Integration
# Comprehensive monitoring setup
version: '3.8'
services:
app:
image: myapp:latest
labels:
# Prometheus metrics
- "prometheus.io/scrape=true"
- "prometheus.io/port=3000"
- "prometheus.io/path=/metrics"
# Logging labels
- "logging.driver=fluentd"
- "logging.fluentd.address=localhost:24224"
- "logging.fluentd.tag=app.{{.Name}}"
# Health check
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 10s
timeout: 5s
retries: 3
start_period: 30s
# Logging configuration
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
labels: "service,version"
# Environment for monitoring
environment:
METRICS_ENABLED: "true"
LOG_LEVEL: "info"
TRACE_ENABLED: "true"
# Monitoring stack
prometheus:
image: prom/prometheus:latest
ports:
- "9090:9090"
volumes:
- ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml:ro
- prometheus_data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.console.libraries=/etc/prometheus/console_libraries'
- '--web.console.templates=/etc/prometheus/consoles'
- '--storage.tsdb.retention.time=15d'
grafana:
image: grafana/grafana:latest
ports:
- "3001:3000"
environment:
GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_PASSWORD}
GF_INSTALL_PLUGINS: grafana-piechart-panel
volumes:
- grafana_data:/var/lib/grafana
- ./monitoring/grafana/dashboards:/etc/grafana/provisioning/dashboards:ro
- ./monitoring/grafana/datasources:/etc/grafana/provisioning/datasources:ro
volumes:
prometheus_data:
grafana_data:
Docker Compose bilan ishlaganda bu best practice'larni qo'llash orqali scalable, secure va maintainable applications yaratish mumkin. DevOps engineer sifatida bu bilimlar sizga production-ready containerized solutions yaratishda yordam beradi! memory: 1G reservations: cpus: '0.5' memory: 512M
Legacy format (deprecated)
mem_limit: 1g cpus: 2.0 mem_reservation: 512m
## Networks
### 1. Default Network
```yaml
# Avtomatik yaratiladi: projectname_default
services:
web:
image: nginx
api:
image: myapi:latest
# web va api bir xil networkda
2. Custom Networks
Bridge Network
services:
web:
image: nginx
networks:
- frontend
api:
image: myapi:latest
networks:
- frontend
- backend
db:
image: postgres:15
networks:
- backend
networks:
frontend:
driver: bridge
backend:
driver: bridge
internal: true # Internet'ga chiqish yo'q
Network Aliases
services:
web:
image: nginx
networks:
frontend:
aliases:
- webserver
- www
networks:
frontend:
driver: bridge
3. External Networks
services:
app:
image: myapp:latest
networks:
- existing_network
networks:
existing_network:
external: true
name: my_external_network
Amaliy Misollar
1. LAMP Stack
# LAMP Stack (Linux, Apache, MySQL, PHP)
version: '3.8'
services:
web:
image: php:8.1-apache
ports:
- "80:80"
volumes:
- ./src:/var/www/html
depends_on:
- db
environment:
- APACHE_DOCUMENT_ROOT=/var/www/html
networks:
- lamp
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: rootpassword
MYSQL_DATABASE: myapp
MYSQL_USER: appuser
MYSQL_PASSWORD: apppassword
volumes:
- mysql_data:/var/lib/mysql
networks:
- lamp
phpmyadmin:
image: phpmyadmin:latest
ports:
- "8080:80"
environment:
PMA_HOST: db
PMA_USER: root
PMA_PASSWORD: rootpassword
depends_on:
- db
networks:
- lamp
volumes:
mysql_data:
networks:
lamp:
driver: bridge
2. MEAN Stack
# MEAN Stack (MongoDB, Express, Angular, Node.js)
version: '3.8'
services:
frontend:
build:
context: ./frontend
dockerfile: Dockerfile
ports:
- "4200:4200"
volumes:
- ./frontend:/app
- /app/node_modules
depends_on:
- backend
networks:
- mean
backend:
build:
context: ./backend
dockerfile: Dockerfile
ports:
- "3000:3000"
volumes:
- ./backend:/app
- /app/node_modules
environment:
NODE_ENV: development
MONGODB_URI: mongodb://mongo:27017/meanapp
depends_on:
- mongo
networks:
- mean
mongo:
image: mongo:6
ports:
- "27017:27017"
environment:
MONGO_INITDB_ROOT_USERNAME: admin
MONGO_INITDB_ROOT_PASSWORD: password
MONGO_INITDB_DATABASE: meanapp
volumes:
- mongo_data:/data/db
- ./init-mongo.js:/docker-entrypoint-initdb.d/init-mongo.js:ro
networks:
- mean
mongo-express:
image: mongo-express:latest
ports:
- "8081:8081"
environment:
ME_CONFIG_MONGODB_ADMINUSERNAME: admin
ME_CONFIG_MONGODB_ADMINPASSWORD: password
ME_CONFIG_MONGODB_SERVER: mongo
ME_CONFIG_BASICAUTH_USERNAME: admin
ME_CONFIG_BASICAUTH_PASSWORD: admin
depends_on:
- mongo
networks:
- mean
volumes:
mongo_data:
networks:
mean:
driver: bridge
3. WordPress Stack
# WordPress with MySQL and Redis
version: '3.8'
services:
wordpress:
image: wordpress:6-php8.1-apache
ports:
- "80:80"
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
WORDPRESS_CONFIG_EXTRA: |
define('WP_REDIS_HOST', 'redis');
define('WP_REDIS_PORT', 6379);
volumes:
- wordpress_data:/var/www/html
- ./uploads.ini:/usr/local/etc/php/conf.d/uploads.ini
depends_on:
- db
- redis
networks:
- wordpress
db:
image: mysql:8.0
environment:
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
MYSQL_ROOT_PASSWORD: rootpassword
volumes:
- db_data:/var/lib/mysql
command: '--default-authentication-plugin=mysql_native_password'
networks:
- wordpress
redis:
image: redis:7-alpine
command: redis-server --appendonly yes
volumes:
- redis_data:/data
networks:
- wordpress
phpmyadmin:
image: phpmyadmin:latest
ports:
- "8080:80"
environment:
PMA_HOST: db
PMA_USER: root
PMA_PASSWORD: rootpassword
depends_on:
- db
networks:
- wordpress
volumes:
wordpress_data:
db_data:
redis_data:
networks:
wordpress:
driver: bridge
4. Microservices Architecture
# E-commerce microservices
version: '3.8'
services:
# API Gateway
gateway:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx/ssl:/etc/nginx/ssl
depends_on:
- user-service
- product-service
- order-service
networks:
- frontend
- backend
# User Service
user-service:
build: ./services/user
environment:
DATABASE_URL: postgresql://user:pass@user-db:5432/users
REDIS_URL: redis://redis:6379
JWT_SECRET: your-jwt-secret
depends_on:
- user-db
- redis
networks:
- backend
deploy:
replicas: 2
user-db:
image: postgres:15
environment:
POSTGRES_DB: users
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
volumes:
- user_db_data:/var/lib/postgresql/data
networks:
- backend
# Product Service
product-service:
build: ./services/product
environment:
DATABASE_URL: postgresql://product:pass@product-db:5432/products
ELASTICSEARCH_URL: http://elasticsearch:9200
depends_on:
- product-db
- elasticsearch
networks:
- backend
product-db:
image: postgres:15
environment:
POSTGRES_DB: products
POSTGRES_USER: product
POSTGRES_PASSWORD: pass
volumes:
- product_db_data:/var/lib/postgresql/data
networks:
- backend
# Order Service
order-service:
build: ./services/order
environment:
DATABASE_URL: mongodb://mongo:27017/orders
RABBITMQ_URL: amqp://rabbitmq:5672
depends_on:
- mongo
- rabbitmq
networks:
- backend
# Shared Services
redis:
image: redis:7-alpine
volumes:
- redis_data:/data
networks:
- backend
mongo:
image: mongo:6
volumes:
- mongo_data:/data/db
networks:
- backend
rabbitmq:
image: rabbitmq:3-management
ports:
- "15672:15672" # Management UI
environment:
RABBITMQ_DEFAULT_USER: admin
RABBITMQ_DEFAULT_PASS: admin
volumes:
- rabbitmq_data:/var/lib/rabbitmq
networks:
- backend
elasticsearch:
image: elasticsearch:8.11.0
environment:
- discovery.type=single-node
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
- xpack.security.enabled=false
volumes:
- elasticsearch_data:/usr/share/elasticsearch/data
networks:
- backend
# Monitoring
prometheus:
image: prom/prometheus
ports:
- "9090:9090"
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
networks:
- monitoring
grafana:
image: grafana/grafana
ports:
- "3000:3000"
environment:
GF_SECURITY_ADMIN_PASSWORD: admin
volumes:
- grafana_data:/var/lib/grafana
networks:
- monitoring
volumes:
user_db_data:
product_db_data:
redis_data:
mongo_data:
rabbitmq_data:
elasticsearch_data:
prometheus_data:
grafana_data:
networks:
frontend:
driver: bridge
backend:
driver: bridge
internal: true
monitoring:
driver: bridge
Docker Compose Commands
1. Basic Commands
Lifecycle Management
# Service'larni ishga tushirish
docker compose up
# Background'da ishga tushirish
docker compose up -d
# Ma'lum service'larni ishga tushirish
docker compose up web db
# Service'larni to'xtatish
docker compose down
# Volume'lar bilan birga o'chirish
docker compose down -v
# Image'lar bilan birga o'chirish
docker compose down --rmi all
Build Commands
# Service'larni build qilish
docker compose build
# Cache'siz build qilish
docker compose build --no-cache
# Ma'lum service'ni build qilish
docker compose build web
# Build va up bir vaqtda
docker compose up --build
2. Service Management
Scaling Services
# Service'ni scale qilish
docker compose up --scale web=3
# Multiple service'larni scale qilish
docker compose up --scale web=3 --scale worker=2
# Dynamic scaling
docker compose scale web=5
Service Status
# Ishlaydigan service'lar
docker compose ps
# Barcha service'lar (to'xtagan ham)
docker compose ps -a
# Service'lar haqida batafsil ma'lumot
docker compose ps --services
# Status format
docker compose ps --format json
3. Logs va Debugging
Log Management
# Barcha service'lar log'lari
docker compose logs
# Ma'lum service log'lari
docker compose logs web
# Real-time logs
docker compose logs -f
# Oxirgi N ta log entry
docker compose logs --tail 100
# Timestamp bilan
docker compose logs -t
# Multiple service'lar
docker compose logs web db
Exec va Debug
# Service'ga kirish
docker compose exec web bash
# Command ishga tushirish
docker compose exec web ls -la
# Root user sifatida
docker compose exec --user root web bash
# Index bilan (scaled service'lar uchun)
docker compose exec --index 2 web bash
4. Advanced Commands
Configuration Commands
# Configuration'ni ko'rish
docker compose config
# Environment variables bilan
docker compose config --resolve-envs
# Service'lar ro'yxati
docker compose config --services
# Volume'lar ro'yxati
docker compose config --volumes
# Validate qilish
docker compose config --quiet
Cleanup Commands
# To'xtagan container'larni o'chirish
docker compose rm
# Force remove
docker compose rm -f
# Orphan container'larni o'chirish
docker compose down --remove-orphans
# Volume'larni tozalash
docker compose down -v
Multiple Environment Management
1. Environment-specific Files
File Structure
# Project structure
project/
├── docker-compose.yml # Base configuration
├── docker-compose.dev.yml # Development overrides
├── docker-compose.prod.yml # Production overrides
├── docker-compose.test.yml # Test environment
├── .env # Default environment
├── .env.dev # Development environment
├── .env.prod # Production environment
└── .env.test # Test environment
Base Configuration
# docker-compose.yml
version: '3.8'
services:
web:
build: .
environment:
NODE_ENV: ${NODE_ENV:-development}
volumes:
- ./src:/app/src
db:
image: postgres:15
environment:
POSTGRES_DB: ${DB_NAME}
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASSWORD}
Development Override
# docker-compose.dev.yml
version: '3.8'
services:
web:
ports:
- "3000:3000"
volumes:
- ./src:/app/src:ro
- /app/node_modules
command: npm run dev
environment:
NODE_ENV: development
DEBUG: "app:*"
db:
ports:
- "5432:5432"
volumes:
- postgres_dev_data:/var/lib/postgresql/data
volumes:
postgres_dev_data:
Production Override
# docker-compose.prod.yml
version: '3.8'
services:
web:
restart: always
command: npm start
environment:
NODE_ENV: production
deploy:
resources:
limits:
cpus: '1.0'
memory: 512M
reservations:
cpus: '0.5'
memory: 256M
db:
restart: always
volumes:
- postgres_prod_data:/var/lib/postgresql/data
deploy:
resources:
limits:
cpus: '2.0'
memory: 2G
reservations:
cpus: '1.0'
memory: 1G
volumes:
postgres_prod_data:
driver: local
driver_opts:
type: nfs
o: addr=nfs-server,rw
device: ":/path/to/data"
2. Environment Usage
Development
# Development environment
docker compose -f docker-compose.yml -f docker-compose.dev.yml up
# With environment file
docker compose --env-file .env.dev -f docker-compose.yml -f docker-compose.dev.yml up
Production
# Production environment
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
# With specific environment
export NODE_ENV=production
docker compose --env-file .env.prod -f docker-compose.yml -f docker-compose.prod.yml up -d
Testing
# Test environment
docker compose -f docker-compose.yml -f docker-compose.test.yml run --rm web npm test
3. Environment Variables
.env Files
# .env.dev
NODE_ENV=development
DB_NAME=myapp_dev
DB_USER=dev_user
DB_PASSWORD=dev_password
API_URL=http://localhost:3000
DEBUG=true
# .env.prod
NODE_ENV=production
DB_NAME=myapp_prod
DB_USER=prod_user
DB_PASSWORD=super_secure_password
API_URL=https://api.myapp.com
DEBUG=false
# .env.test
NODE_ENV=test
DB_NAME=myapp_test
DB_USER=test_user
DB_PASSWORD=test_password
API_URL=http://localhost:3001
DEBUG=false
Performance Optimization
1. Build Optimization
Build Context
services:
web:
build:
context: .
dockerfile: Dockerfile
args:
NODE_ENV: production
# .dockerignore file'ni ishlatish muhim
Multi-stage Builds
services:
web:
build:
context: .
target: production
cache_from:
- myapp:builder
- myapp:latest
2. Resource Management
Memory va CPU Limits
services:
web:
image: myapp:latest
deploy:
resources:
limits:
cpus: '2.0'
memory: 1G
reservations:
cpus: '0.5'
memory: 512M
sysctls:
- net.core.somaxconn=1024
ulimits:
nproc: 65535
nofile:
soft: 65535
hard: 65535
3. Volume Optimization
Bind Mount vs Named Volume
services:
web:
image: myapp:latest
volumes:
# Development: bind mount (fast development)
- type: bind
source: ./src
target: /app/src
consistency: delegated # macOS uchun
# Production: named volume (better performance)
- type: volume
source: app_data
target: /app/data
volumes:
app_data:
driver: local
driver_opts:
type: none
device: /opt/myapp/data
o: bind
Monitoring va Debugging
1. Health Checks
services:
web:
image: myapp:latest
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
depends_on:
db:
condition: service_healthy
db:
image: postgres:15
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
interval: 10s
timeout: 5s
retries: 5
2. Monitoring Stack
# monitoring/docker-compose.yml
version: '3.8'
services:
prometheus:
image: prom/prometheus:latest
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.console.libraries=/etc/prometheus/console_libraries'
- '--web.console.templates=/etc/prometheus/consoles'
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
environment:
GF_SECURITY_ADMIN_PASSWORD: admin
volumes:
- grafana_data:/var/lib/grafana
cadvisor:
image: gcr.io/cadvisor/cadvisor:latest
ports:
- "8080:8080"
volumes:
- /:/rootfs:ro
- /var/run:/var/run:rw
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
volumes:
prometheus_data:
grafana_data:
3. Debugging Tools
Container Inspection
# Container ichidagi jarayonlar
docker compose top
# Resource usage
docker compose exec web htop
# Network connectivity
docker compose exec web ping db
# Port listening
docker compose exec web netstat -tlnp
Security Best Practices
1. Secrets Management
Docker Secrets
# secrets.yml
version: '3.8'
services:
app:
image: myapp:latest
secrets:
- db_password
- api_key
environment:
DB_PASSWORD_FILE: /run/secrets/db_password
API_KEY_FILE: /run/secrets/api_key
secrets:
db_password:
file: ./secrets/db_password.txt
api_key:
external: true # Docker secret'dan
Environment Files Security
# .env fayllarini .gitignore'ga qo'shish
echo ".env*" >> .gitignore
# .env.example yaratish
cp .env .env.example
# Sensitive ma'lumotlarni olib tashlab commit qilish
2. Network Security
services:
web:
image: nginx
networks:
- frontend
# Faqat frontend network'ga kirish
api:
image: myapi:latest
networks:
- frontend
- backend
# Frontend va backend'ga kirish
db:
image: postgres:15
networks:
- backend
# Faqat backend network, external access yo'q
networks:
frontend:
driver: bridge
backend:
driver: bridge
internal: true # Internet'ga chiqish yo'q
3. User Security
services:
app:
image: myapp:latest
user: "1000:1000" # Non-root user
read_only: true # Read-only file system
tmpfs:
- /tmp
- /var/run
cap_drop:
- ALL
cap_add:
- NET_BIND_SERVICE
security_opt:
- no-new-privileges:true
Production Deployment
1. Production Configuration
# docker-compose.prod.yml
version: '3.8'
services:
web:
image: myapp:${VERSION}
restart: always
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
deploy:
resources:
limits:
cpus: '2.0'