Docker Compose adalah tool untuk menjalankan aplikasi multi-container Docker dengan satu perintah. Dalam production, Docker Compose memungkinkan Anda mendefinisikan seluruh arsitektur aplikasi dalam satu file YAML dan menjalankannya dengan mudah. Artikel ini membahas cara deploy aplikasi multi-container di environment production.
Pengertian Docker Compose
Docker Compose memungkinkan Anda mendefinisikan beberapa container, jaringan, dan volume dalam satu file docker-compose.yml. Alih-alih menjalankan perintah Docker untuk setiap container, Anda cukup satu perintah docker-compose up -d untuk menjalankan semuanya.
Kapan Menggunakan Docker Compose?
- Aplikasi web + database + cache
- Microservices architecture
- Lingkungan staging dan production
- Development dan testing
Arsitektur Umum Production
Contoh Arsitektur Website
┌─────────────────┐
│ Nginx │ (Reverse Proxy / Load Balancer)
├─────────────────┤
│ Aplikasi │ (Node.js / Python / PHP)
│ Web App │
├─────────────────┤
│ Database │ (PostgreSQL / MySQL / MariaDB)
├─────────────────┤
│ Cache │ (Redis)
├─────────────────┤
│ Storage │ (Volume untuk file/upload)
└─────────────────┘Alat yang Dibutuhkan
- Server Debian 13 dengan Docker dan Docker Compose
- Akses SSH sebagai root atau sudo
- Aplikasi web siap dikontainerisasi
- Domain (opsional)
Instalasi Docker dan Docker Compose
1. Instal Docker
curl -fsSL https://get.docker.com | bash
systemctl enable docker
systemctl start docker2. Instal Docker Compose
apt install docker-compose-plugin -y
# Atau versi standalone
curl -SL https://github.com/docker/compose/releases/download/v2.27.0/docker-compose-linux-amd64 -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose3. Verifikasi
docker --version
docker compose versionMembuat File Docker Compose
Struktur Project
/opt/myapp/
├── docker-compose.yml
├── app/
│ ├── Dockerfile
│ ├── package.json
│ └── src/
├── nginx/
│ └── nginx.conf
├── db/
│ └── init.sql
└── data/ # Volume dataContoh 1: Aplikasi Node.js + PostgreSQL + Redis
version: '3.8'
services:
# Aplikasi Web
app:
build: ./app
container_name: web-app
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- DATABASE_URL=postgresql://user:password@db:5432/mydb
- REDIS_URL=redis://redis:6379
depends_on:
- db
- redis
restart: always
volumes:
- ./app:/app
- /app/node_modules # Volume untuk dependencies
# Database PostgreSQL
db:
image: postgres:16-alpine
container_name: database
environment:
POSTGRES_DB: mydb
POSTGRES_USER: user
POSTGRES_PASSWORD: password
volumes:
- postgres_data:/var/lib/postgresql/data
- ./db/init.sql:/docker-entrypoint-initdb.d/init.sql
ports:
- "5432:5432"
restart: always
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user"]
interval: 30s
timeout: 10s
retries: 5
# Redis Cache
redis:
image: redis:7-alpine
container_name: cache
ports:
- "6379:6379"
volumes:
- redis_data:/data
restart: always
command: redis-server --appendonly yes --requirepass YourRedisPassword123!
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 30s
timeout: 10s
retries: 5
# Nginx Reverse Proxy
nginx:
image: nginx:alpine
container_name: reverse-proxy
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ./nginx/ssl:/etc/nginx/ssl:ro
depends_on:
- app
restart: always
# Volume untuk persistensi data
volumes:
postgres_data:
redis_data:Contoh 2: WordPress + MySQL + Nginx
version: '3.8'
services:
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d:ro
- ./nginx/ssl:/etc/nginx/ssl:ro
depends_on:
- wordpress
restart: always
wordpress:
image: wordpress:php8.2-nginx
container_name: wordpress
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: securepassword123!
WORDPRESS_DB_NAME: wordpress
volumes:
- wordpress_data:/var/www/html
- ./wp-config.php:/var/www/html/wp-config.php:ro
depends_on:
- db
restart: always
db:
image: mysql:8.0
container_name: mysql_db
environment:
MYSQL_ROOT_PASSWORD: rootpassword123!
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: securepassword123!
volumes:
- mysql_data:/var/lib/mysql
restart: always
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 30s
timeout: 10s
retries: 5
volumes:
wordpress_data:
mysql_data:Menjalankan Docker Compose
1. Deploy Semua Layanan
cd /opt/myapp
docker compose up -d2. Lihat Status
docker compose ps
docker compose logs -f app3. Hentikan Semua
docker compose down4. Hentikan dan Hapus Volume
docker compose down -v5. Restart Layanan Spesifik
docker compose restart app
docker compose restart db redis6. Scale Layanan (Load Balancing)
# Jalankan 3 instance aplikasi
docker compose up -d --scale app=3
# Cek status
docker compose psVolume dan Persistensi
Jenis Volume
volumes:
# Named volume — dikelola Docker
db_data:
driver: local
# Bind mount — folder host
- ./app:/app
# Anonymous volume
- /dataBackup Volume
# Backup named volume
docker run --rm -v postgres_data:/data -v $(pwd):/backup alpine tar czf /backup/db-backup.tar.gz -C /data .
# Restore volume
docker run --rm -v postgres_data:/data -v $(pwd):/backup alpine tar xzf /backup/db-backup.tar.gz -C /dataNetwork Configuration
Membuat Network Kustom
networks:
backend:
driver: bridge
frontend:
driver: bridge
services:
app:
networks:
- backend
nginx:
networks:
- frontend
- backend
db:
networks:
- backendHealth Checks dan Monitoring
Health Check di Docker Compose
services:
app:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40sMonitoring dengan Prometheus dan cAdvisor
Tambahkan ke docker-compose.yml:
cadvisor:
image: gcr.io/cadvisor/cadvisor:latest
container_name: cadvisor
ports:
- "8080:8080"
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
restart: alwaysScaling Production
1. Multi-Container dengan Swarm
# Inisialisasi swarm
docker swarm init
# Deploy stack
docker stack deploy -c docker-compose.yml myapp
# Scale service
docker service scale myapp_app=52. Load Balancing Otomatis
services:
app:
deploy:
replicas: 3
update_config:
parallelism: 1
delay: 10s
restart_policy:
condition: on-failureSecurity Production
1. Non-Root Container
services:
app:
security_opt:
- no-new-privileges:true
read_only: true
tmpfs:
- /tmp2. Resource Limits
services:
app:
deploy:
resources:
limits:
cpus: '2'
memory: 1G
reservations:
cpus: '0.5'
memory: 512M3. Environment Variables dari File
services:
app:
env_file:
- .env.productionBuat .env.production:
DATABASE_URL=postgresql://user:password@db:5432/mydb
SECRET_KEY=your-secret-key
NODE_ENV=productionCI/CD Integration
GitHub Actions untuk Auto Deploy
Buat .github/workflows/deploy.yml:
name: Deploy Production
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy to Server
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.SERVER_IP }}
username: ${{ secrets.SSH_USER }}
key: ${{ secrets.SSH_KEY }}
script: |
cd /opt/myapp
docker compose pull
docker compose up -d
docker image prune -fTroubleshooting
1. Container Tidak Bisa Start
Penyebab: Konfigurasi salah atau port conflict. Solusi:
# Cek log
docker compose logs app
# Cek apakah port sudah digunakan
ss -tlnp | grep 3000
# Fix dan restart
docker compose up -d --build2. Database Tidak Terhubung
Penyebab: Service belum siap atau credential salah. Solusi:
# Cek status database
docker compose ps db
# Cek log
docker compose logs db
# Pastikan depends_on benar3. Data Hilang Setelah Restart
Penyebab: Volume tidak dikonfigurasi. Solusi:
# Cek volume
docker volume ls
# Pastikan volume ada di compose file4. Aplikasi Lambat
Penyebab: Resource limit terlalu rendah atau database belum dioptimasi. Solusi:
# Cek resource usage
docker stats
# Naikkan resource limit di compose file5. Network Error
Penyebab: Network tidak dikonfigurasi atau service di network salah. Solusi:
# Cek network
docker network ls
docker network inspect myapp_backend
# Pastikan service di network yang benarKesimpulan
Docker Compose menyederhanakan deploy aplikasi multi-container dalam satu file konfigurasi. Dengan volume untuk persistensi, health checks untuk ketersediaan, dan resource limits untuk keamanan, aplikasi Anda akan berjalan stabil di production. Otomatisasi dengan CI/CD membuat proses deployment menjadi lebih efisien dan minim kesalahan.
Kunci utama:
- Gunakan volume untuk semua data yang perlu persisten
- Atur health check agar layanan yang mati otomatis restart
- Batasi resource untuk mencegah satu service membebani server
- Backup volume secara rutin
- Gunakan
.envfile untuk mengelola secret dan konfigurasi - Otomatiskan deployment dengan CI/CD
Catatan penting: Jangan pernah menjalankan container sebagai root di production. Gunakansecurity_optdanread_onlyuntuk meminimalkan risiko keamanan. Selalu backup volume data sebelum melakukan update compose file. Jangan lupa hapus image Docker yang tidak terpakai secara berkala agar disk server tidak penuh.