Pertama kali saya menjalankan aplikasi yang butuh database, perintah docker run saya panjangnya seperti kereta api. -p sana, -e sini, -v situ, --network ini, --name itu. Sekali salah ketik satu flag, container-nya jalan tapi aplikasinya bengong tidak jelas.
Docker Compose lahir untuk mengakhiri penderitaan itu. Satu file YAML berisi seluruh definisi aplikasimu, dan satu perintah untuk menyalakan semuanya. Kalau Docker mengubah cara kita menjalankan aplikasi, Compose mengubah cara kita mendefinisikan aplikasi — tertulis, rapi, dan bisa diulang siapa pun.
Panduan ini membawamu dari nol sampai benar-benar punya web app + database PostgreSQL yang jalan di container. Tidak ada teori melangit; semua yang ditulis di sini bisa kamu ketik dan jalankan langsung.
Docker Compose Itu Apa, Sih?
Bayangkan kamu mau bikin kopi susu. Tanpa resep, kamu harus ingat takaran kopi, susu, gula, es, urutan campurannya — setiap kali bikin, setiap kali menghafal ulang. Docker Compose itu resepnya: semua takaran dan langkah ditulis sekali, setelah itu tinggal ikuti.
Secara teknis, Compose adalah tool untuk mendefinisikan dan menjalankan aplikasi multi-container lewat satu file bernama docker-compose.yml (atau compose.yml — keduanya dikenali). Di dalamnya kamu deklarasikan services, networks, dan volumes. Lalu:
docker compose up
Satu perintah. Semua container nyala sesuai definisi. Mau matikan semuanya? docker compose down. Selesai.
Satu hal yang sering bikin bingung pemula: ada docker-compose (pakai strip) dan docker compose (pakai spasi). Yang pakai strip itu versi lama (v1, sudah tidak dikembangkan). Yang pakai spasi adalah Compose v2 — plugin resmi Docker CLI modern. Panduan ini memakai docker compose (spasi).
Kapan Pakai Compose — dan Kapan Jangan
Jujur saja: tidak semua project butuh Compose. Kalau aplikasimu cuma satu container tanpa database, docker run biasa sudah cukup. Compose bersinar saat kamu punya dua container atau lebih yang saling tergantung: web + database, API + Redis + worker. Untuk production skala raksasa memang ada Kubernetes, tapi untuk project pribadi atau startup kecil? Kubernetes itu overkill.
Cek Instalasi Dulu
Kalau kamu menginstal Docker Desktop atau Docker Engine versi baru, Compose v2 biasanya sudah ikut. Cek dengan:
docker compose version
Kalau keluar sesuatu seperti Docker Compose version v2.24.0, kamu aman.
Project Pertama: Web + PostgreSQL
Teori cukup. Kita bikin project nyata: aplikasi web Python (Flask) kecil yang terhubung ke PostgreSQL. Buat folder project dan isi dengan struktur ini:
compose-demo/
├── app.py
├── requirements.txt
├── Dockerfile
└── docker-compose.yml
Pertama, aplikasi web-nya — sengaja dibuat minimal:
import os
import psycopg2
from flask import Flask
app = Flask(__name__)
def cek_db():
conn = psycopg2.connect(os.environ["DATABASE_URL"])
cur = conn.cursor()
cur.execute("SELECT version();")
versi = cur.fetchone()[0]
cur.close()
conn.close()
return versi
@app.route("/")
def index():
try:
versi = cek_db()
return "Web jalan! Database terhubung: " + versi[:40] + "..."
except Exception as e:
return "Web jalan, tapi DB bermasalah: " + str(e), 500
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
Perhatikan: os.environ["DATABASE_URL"] — aplikasi tidak tahu di mana database berada, ia cuma baca dari environment variable. Nanti Compose yang mengisinya. Konfigurasi lewat environment, bukan hardcode di kode.
Isi requirements.txt:
flask
psycopg2-binary
Lalu Dockerfile:
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app.py .
CMD ["python", "app.py"]
Dan inilah bintangnya — docker-compose.yml:
services:
web:
build: .
ports:
- "5000:5000"
environment:
- DATABASE_URL=postgresql://postgres:rahasia123@db:5432/aplikasiku
depends_on:
db:
condition: service_healthy
restart: unless-stopped
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: rahasia123
POSTGRES_DB: aplikasiku
volumes:
- data-postgres:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5
volumes:
data-postgres:
Catatan: tutorial lama menulis version: "3.8" di baris pertama — sudah tidak diperlukan di Compose modern. Langsung mulai dari services: saja.
Bedah docker-compose.yml Baris per Baris
services: daftar semua container. Nama service jadi nama host — aplikasi terhubung ke db:5432, bukan IP. Compose membuat network internal dan DNS otomatis.
build: . vs image: build untuk kodemu sendiri, image untuk software jadi dari Docker Hub.
ports: - "5000:5000" format HOST:KONTAINER — kebalik menulisnya kesalahan klasik pemula.
environment: suntikan variabel ke container. Peringatan: password rahasia123 cuma untuk belajar — untuk project serius taruh di file .env dan masukkan ke .gitignore.
volumes: named volume tetap ada walau container dihapus. Tanpa ini, setiap down berarti database kembali kosong.
depends_on + healthcheck: depends_on saja hanya mengatur urutan start. Dengan condition: service_healthy, web baru jalan setelah database benar-benar siap.
Jalankan!
Dari folder project:
docker compose up --build -d
Flag --build memastikan image dibangun ulang, -d artinya detached (background).
docker compose ps
Buka browser ke http://localhost:5000. Kalau muncul "Web jalan! Database terhubung: PostgreSQL 16...", selamat!
docker compose logs -f web
Flag -f = follow, log mengalir terus. Tekan Ctrl+C untuk berhenti mengintip (container tetap jalan).
Perintah yang Wajib Hafal
| Perintah | Gunanya |
|---|---|
docker compose up -d | Nyalakan semua service di background |
docker compose up --build | Nyalakan + bangun ulang image |
docker compose ps | Lihat status semua service |
docker compose logs -f [service] | Intip log |
docker compose exec [service] [perintah] | Jalankan perintah di container |
docker compose down | Matikan & hapus container (volume AMAN) |
docker compose config | Validasi file YAML |
Peringatan tentang docker compose down -v: flag -v ikut menghapus volumes — seluruh data database lenyap. Pastikan itu keputusan sadar.
Volumes & Networks: Seperlunya Saja
Volume itu gudang, bind mount itu meja kerja. Named volume dikelola Docker dan tetap ada walau container dihapus. Bind mount menautkan folder laptopmu langsung ke container — cocok untuk development.
Network itu gang komplek. Compose otomatis membuatkan network per project; service saling sapa cukup dengan nama. Kamu hampir tidak pernah perlu mendefinisikan networks: eksplisit.
Kalau Error, Jangan Panik
1. "port is already allocated". Port 5000 sudah dipakai aplikasi lain. Solusi: ganti sisi kiri mapping, misal "5001:5000".
2. Web crash "connection refused" ke database. Pastikan condition: service_healthy tidak terlewat.
3. Perubahan kode tidak berpengaruh. Solusi: docker compose up --build -d.
Kalau menemui error lain — panduan 7 Error Docker Paling Sering Muncul & Cara Mengatasinya membahas pola-pola error Docker satu per satu. Simpan sebagai contekan.
Kesimpulan
Docker Compose mengubah belasan flag docker run yang rapuh jadi satu file YAML yang bisa dibaca, di-review, dan di-version-control. Alur kerjanya: tulis compose file → up --build -d → cek dengan ps dan logs → down kalau selesai.
Langkah selanjutnya: coba tambahkan service ketiga — misalnya Redis untuk cache, atau Adminer untuk melihat database lewat browser. Tambah satu blok di bawah services:, jalankan docker compose up -d lagi. Compose hanya membuat yang baru; yang sudah jalan tidak diganggu.
Komentar
Posting Komentar