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.
Ingat: Docker Compose cocok untuk aplikasi skala kecil-menengah. Untuk aplikasi berskala besar dengan banyak layanan, pertimbangkan Docker Swarm atau Kubernetes. Docker Compose adalah fondasi yang baik untuk memahami containerisasi sebelum beralih ke orkestrasi yang lebih kompleks.
Dipublikasikan untuk membantu para pengembang dan administrator server dalam mendeploy aplikasi container secara profesional di production.