TeknoTUT

Belajar Docker Compose: Menjalankan Multi-Container dengan Mudah

Belajar Docker Compose dari nol: install di Ubuntu, tulis compose.yaml, lalu jalankan WordPress + MariaDB hanya dengan satu perintah. Lengkap dan praktis!

Ditulis oleh 13 menit bacaEnglish
Ilustrasi beberapa container yang saling terhubung dan diatur dari satu file konfigurasi
Daftar Isi

Jika anda sudah pernah mencoba Docker, tentu anda sudah tidak asing dengan perintah docker run yang panjang: lengkap dengan opsi -p, -v, -e, --name, dan --network. Untuk satu container, perintah seperti ini masih bisa diingat. Tetapi bagaimana jika aplikasi anda terdiri dari tiga, empat, atau lima container yang saling bergantung?

Bayangkan anda ingin menjalankan WordPress. Anda butuh satu container untuk WordPress, satu lagi untuk database, sebuah network agar keduanya bisa saling bicara, dan volume agar datanya tidak hilang. Semua itu harus dijalankan dengan urutan yang benar, dan harus diulang setiap kali anda pindah server. Sedikit saja salah ketik, aplikasinya tidak jalan.

Di sinilah Docker Compose berperan. Dengan Docker Compose, seluruh susunan container itu cukup ditulis di satu file YAML, lalu dijalankan dengan satu perintah.

Dalam artikel kali ini, kita akan membahas tuntas tentang Docker Compose, mulai dari pengertiannya, cara meng-install-nya di Ubuntu, struktur file compose.yaml, praktik menjalankan WordPress + MariaDB, perintah-perintah yang paling sering dipakai, hingga jebakan firewall yang sering terlewat di VPS. Mari kita mulai!

Apa itu Docker Compose?

Docker Compose adalah alat untuk mendefinisikan dan menjalankan aplikasi yang terdiri dari banyak container (multi-container). Semua konfigurasi, mulai dari image yang dipakai, port, volume, network, hingga variabel lingkungan, ditulis dalam sebuah file YAML yang biasanya bernama compose.yaml.

Analogi sederhananya begini: jika docker run adalah memesan menu satu per satu ke pelayan, maka Docker Compose adalah menyerahkan daftar pesanan lengkap sekaligus. Dapur (Docker) yang akan menyiapkan semuanya dalam urutan yang benar.

Docker Compose punya sedikit sejarah yang perlu anda ketahui, karena masih banyak tutorial lama yang beredar:

  • Compose V1 ditulis dengan Python dan dijalankan dengan perintah docker-compose (pakai tanda hubung). Versi ini sudah lama tidak dikembangkan lagi.
  • Compose V2 dan seterusnya ditulis ulang dengan Go dan menjadi plugin Docker CLI, sehingga perintahnya menjadi docker compose (pakai spasi). Saat artikel ini ditulis, versi terbarunya sudah mencapai v5.x.

Catatan: jika anda menemukan tutorial yang memakai docker-compose up, cukup ganti menjadi docker compose up. Sebagian besar isi file YAML-nya tetap kompatibel.

Ada satu perubahan lagi yang sering membingungkan: baris version: "3.8" di bagian atas file. Menurut dokumentasi resmi Compose, field version kini sudah usang dan hanya bersifat informatif. Compose selalu memakai skema terbaru, dan justru akan menampilkan peringatan bila baris itu masih ada. Jadi, di file baru, baris tersebut tidak perlu ditulis lagi.

Bila anda masih baru dengan konsep container, image, dan volume, sebaiknya baca dulu artikel Mengenal Docker Container sebelum melanjutkan.

Mengapa Harus Menggunakan Docker Compose?

Berikut beberapa alasan kenapa Docker Compose layak menjadi alat wajib anda:

  • Satu file, satu sumber kebenaran: seluruh konfigurasi aplikasi tersimpan di compose.yaml. Anda tidak perlu lagi mencatat perintah docker run yang panjang di catatan terpisah.
  • Satu perintah untuk semuanya: docker compose up -d menyalakan seluruh container, docker compose down mematikannya.
  • Network otomatis: Compose membuat network khusus untuk setiap project, sehingga antar-container bisa saling memanggil cukup dengan nama service, misalnya db.
  • Mudah dipindahkan: cukup salin folder project ke server lain, lalu jalankan perintah yang sama. Hasilnya identik.
  • Bisa disimpan di Git: karena berupa file teks, perubahan konfigurasi bisa dilacak, di-review, dan dikembalikan bila ada masalah.

Kekurangan Docker Compose

Supaya adil, Docker Compose juga punya keterbatasan:

  • Dirancang untuk satu host: Compose mengatur container di satu mesin. Untuk mengatur banyak server sekaligus, anda butuh orchestrator seperti Kubernetes atau Docker Swarm.
  • Tidak ada failover otomatis antar-server: jika server mati, semua container di dalamnya ikut mati.
  • Butuh pemahaman YAML: YAML sangat sensitif terhadap indentasi. Salah satu spasi saja bisa membuat file tidak valid.

Untuk kebutuhan blog pribadi, aplikasi internal, lingkungan development, atau self-hosting di satu VPS, keterbatasan ini hampir tidak terasa.

Persiapan

Sebelum memulai, pastikan anda sudah memiliki:

  • Server atau komputer dengan Ubuntu 24.04 LTS atau 26.04 LTS (64 bit). Perintah di artikel ini ditujukan untuk kedua versi tersebut. Menurut dokumentasi Docker, Ubuntu 22.04 LTS juga didukung.
  • User dengan akses sudo.
  • RAM minimal 1 GB untuk contoh WordPress + MariaDB. Bila RAM anda pas-pasan, pertimbangkan untuk menambah swap seperti di artikel Memahami Swap Memory di Linux.

Tips: jika anda memakai VPS yang baru disewa, amankan dulu servernya dengan mengikuti panduan Cara Mengamankan VPS Linux Baru. Kita juga akan membahas hubungan Docker dengan firewall UFW di bagian akhir artikel ini.

Cara Install Docker dan Docker Compose di Ubuntu

Di Ubuntu, cara yang direkomendasikan adalah memakai repositori resmi Docker. Paket Compose sudah tersedia di sana dengan nama docker-compose-plugin, sehingga kita bisa meng-install Docker Engine dan Compose sekaligus.

Langkah #1: Hapus Paket Docker Lama

Ubuntu punya paket Docker versi tidak resmi (docker.io, docker-compose, dan sebagainya) yang bisa bentrok dengan paket resmi. Hapus dulu paket-paket tersebut dengan perintah berikut;

sudo apt remove docker.io docker-compose docker-compose-v2 docker-doc podman-docker containerd runc

Jika muncul pesan bahwa paket-paket tersebut tidak ter-install, itu normal. Artinya server anda memang masih bersih.

Langkah #2: Tambahkan Repositori Resmi Docker

Pertama, install paket pendukung lalu unduh kunci GPG milik Docker:

sudo apt update
sudo apt install ca-certificates curl -y
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

Selanjutnya, daftarkan repositori Docker. Perintah ini otomatis menyesuaikan dengan versi Ubuntu dan arsitektur prosesor anda, jadi bisa disalin apa adanya:

sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF

Lalu perbarui daftar paket:

sudo apt update

Langkah #3: Install Docker Engine dan Compose Plugin

Sekarang install Docker Engine beserta plugin Compose dengan perintah berikut;

sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y

Setelah selesai, pastikan Compose sudah terpasang:

docker compose version

Outputnya kira-kira seperti ini:

Docker Compose version v5.7.0

Angka versinya bisa berbeda, tergantung kapan anda meng-install-nya. Yang penting, perintah docker compose (dengan spasi) sudah dikenali.

Langkah #4: Jalankan Docker Tanpa sudo (Opsional)

Secara default, perintah docker harus dijalankan dengan sudo. Agar user anda bisa menjalankannya langsung, tambahkan user tersebut ke grup docker:

sudo usermod -aG docker $USER

Logout lalu login kembali (atau tutup lalu buka lagi sesi SSH anda) agar perubahan grup ini berlaku. Uji dengan menjalankan container percobaan:

docker run --rm hello-world

Jika muncul pesan Hello from Docker!, berarti Docker sudah berjalan dengan benar.

Peringatan: anggota grup docker pada praktiknya punya hak setara root di server tersebut. Hanya tambahkan user yang benar-benar anda percaya. Jika ragu, lewati langkah ini dan tetap gunakan sudo di depan setiap perintah docker.

Memahami Struktur File compose.yaml

Sebelum praktik, mari kita kenali dulu bagian-bagian utama file Compose. Menurut dokumentasi model aplikasi Compose, nama file yang disarankan adalah compose.yaml. Nama lama seperti docker-compose.yml masih didukung demi kompatibilitas.

Berikut contoh file Compose yang paling sederhana:

services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80"
    volumes:
      - ./html:/usr/share/nginx/html:ro
    restart: unless-stopped

Penjelasan setiap bagiannya:

Kunci Fungsi Padanan di docker run
services Daftar container (service) yang membentuk aplikasi —
web Nama service, sekaligus nama host di network internal --name
image Image yang dipakai argumen image
ports Memetakan port host:container -p
volumes Menghubungkan folder atau volume ke container -v
environment Variabel lingkungan untuk container -e
restart Kebijakan restart otomatis --restart
depends_on Urutan start antar-service —

Selain services, ada dua kunci tingkat atas yang akan sering anda temui:

  • volumes: mendefinisikan named volume, yaitu penyimpanan permanen yang dikelola Docker. Data di dalamnya tetap ada meskipun container dihapus.
  • networks: mendefinisikan network khusus. Bila tidak ditulis, Compose otomatis membuat satu network default untuk project anda.

Nah, sekarang saatnya praktik!

Praktik: Menjalankan WordPress dan MariaDB dengan Docker Compose

Kita akan menjalankan WordPress dengan database MariaDB, contoh klasik aplikasi multi-container. Kalau anda pernah membaca Cara Membuat Blog dengan WordPress, kali ini kita menjalankannya sendiri di server, tanpa panel hosting.

Langkah #1: Buat Folder Project

Setiap project Compose sebaiknya punya foldernya sendiri. Nama folder ini secara default juga menjadi nama project. Buat folder baru lalu masuk ke dalamnya:

mkdir -p ~/wordpress-compose
cd ~/wordpress-compose

Langkah #2: Simpan Password di File .env

Jangan menulis password langsung di compose.yaml, apalagi jika file itu akan disimpan di Git. Compose otomatis membaca file bernama .env di folder project dan memakai isinya untuk mengganti variabel ${...} di file Compose.

Buat file .env dengan editor nano:

nano .env

Isi dengan konfigurasi berikut, lalu ganti kedua password dengan password acak yang kuat:

DB_NAME=wordpress
DB_USER=wpuser
DB_PASSWORD=ganti-dengan-password-kuat

Simpan dengan Ctrl+O, tekan Enter, lalu keluar dengan Ctrl+X. Setelah itu, batasi agar file ini hanya bisa dibaca oleh user anda:

chmod 600 .env

Penting: bila folder project ini anda simpan di Git, tambahkan .env ke file .gitignore agar password tidak ikut ter-commit.

Langkah #3: Tulis File compose.yaml

Sekarang buat file Compose-nya:

nano compose.yaml

Salin konfigurasi berikut:

services:
  db:
    image: mariadb:lts
    restart: unless-stopped
    environment:
      MARIADB_DATABASE: ${DB_NAME}
      MARIADB_USER: ${DB_USER}
      MARIADB_PASSWORD: ${DB_PASSWORD:?DB_PASSWORD belum diisi di .env}
      MARIADB_RANDOM_ROOT_PASSWORD: "1"
    volumes:
      - db_data:/var/lib/mysql
    healthcheck:
      test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
      start_period: 10s
      interval: 10s
      timeout: 5s
      retries: 3
 
  wordpress:
    image: wordpress:latest
    restart: unless-stopped
    depends_on:
      db:
        condition: service_healthy
    ports:
      - "8080:80"
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_NAME: ${DB_NAME}
      WORDPRESS_DB_USER: ${DB_USER}
      WORDPRESS_DB_PASSWORD: ${DB_PASSWORD:?DB_PASSWORD belum diisi di .env}
    volumes:
      - wp_data:/var/www/html
 
volumes:
  db_data:
  wp_data:

Ada beberapa hal menarik di file ini:

  • WORDPRESS_DB_HOST: db: WordPress cukup memanggil database dengan nama service db. Compose yang mengurus alamat IP-nya lewat network internal.
  • ${DB_PASSWORD:?...}: nilai diambil dari .env. Tanda :? membuat Compose langsung berhenti dengan pesan error bila variabelnya kosong, jadi anda tidak akan tanpa sengaja menjalankan database tanpa password.
  • MARIADB_RANDOM_ROOT_PASSWORD: password root MariaDB dibuat acak, karena WordPress cukup memakai user wpuser.
  • healthcheck dan condition: service_healthy: WordPress baru dinyalakan setelah MariaDB benar-benar siap menerima koneksi. Skrip healthcheck.sh sudah tersedia di dalam image resmi MariaDB, sesuai dokumentasi MariaDB.
  • db_data dan wp_data: named volume untuk menyimpan database dan file WordPress (tema, plugin, upload) secara permanen.

Sebelum menjalankan, ada baiknya mengecek apakah file sudah valid. Perintah berikut menampilkan konfigurasi akhir setelah variabel dari .env dimasukkan:

docker compose config

Jika ada kesalahan indentasi atau variabel yang kosong, perintah ini akan langsung menampilkan error-nya.

Catatan: output docker compose config ikut menampilkan password dari .env. Jangan menyalin output ini ke forum atau grup chat saat meminta bantuan.

Langkah #4: Jalankan Semua Container

Inilah bagian yang paling menyenangkan. Jalankan seluruh aplikasi di background dengan satu perintah:

docker compose up -d

Compose akan mengunduh image, membuat network dan volume, menyalakan MariaDB, menunggu sampai sehat, lalu menyalakan WordPress. Outputnya kira-kira seperti ini:

[+] Running 5/5
 ✔ Network wordpress-compose_default        Created
 ✔ Volume wordpress-compose_db_data         Created
 ✔ Volume wordpress-compose_wp_data         Created
 ✔ Container wordpress-compose-db-1         Healthy
 ✔ Container wordpress-compose-wordpress-1  Started

Perhatikan bahwa nama network, volume, dan container diawali wordpress-compose, yaitu nama folder project kita. Inilah cara Compose memisahkan satu project dari project lain di server yang sama.

Langkah #5: Cek Status dan Buka WordPress

Lihat status container dengan perintah berikut;

docker compose ps

Jika kolom STATUS menampilkan Up untuk kedua service, dan db bertanda (healthy), berarti semuanya sudah berjalan. Sekarang buka browser dan akses http://IP-SERVER-ANDA:8080. Halaman instalasi WordPress akan muncul. Selesai!

Perintah Docker Compose yang Sering Dipakai

Semua perintah di bawah ini dijalankan dari dalam folder project (folder yang berisi compose.yaml).

Perintah Fungsi
docker compose up -d Membuat dan menjalankan semua service di background
docker compose ps Melihat status container di project
docker compose logs -f wordpress Melihat log service secara real-time (Ctrl+C untuk keluar)
docker compose exec db bash Masuk ke shell di dalam container yang sedang berjalan
docker compose restart wordpress Me-restart satu service
docker compose stop Menghentikan container tanpa menghapusnya
docker compose down Menghentikan dan menghapus container serta network
docker compose pull Mengunduh versi terbaru image yang dipakai
docker compose config Memvalidasi dan menampilkan konfigurasi akhir
docker compose ls Melihat daftar semua project Compose yang berjalan

Cara Update Aplikasi

Salah satu keuntungan terbesar Compose adalah proses update yang sangat singkat. Untuk memperbarui WordPress dan MariaDB ke image terbaru, jalankan dua perintah berikut;

docker compose pull
docker compose up -d

Compose hanya akan membuat ulang container yang image-nya berubah. Data tetap aman karena tersimpan di volume. Meski begitu, tetap biasakan untuk mem-backup data sebelum update besar.

Hati-Hati dengan down -v

Perintah docker compose down menghapus container dan network, tetapi tidak menghapus named volume. Data anda tetap aman.

Lain halnya bila anda menambahkan opsi -v:

docker compose down -v

Menurut dokumentasi docker compose down, opsi ini ikut menghapus named volume yang didefinisikan di file Compose. Artinya, database dan seluruh file WordPress anda akan hilang permanen. Pakai opsi ini hanya bila anda memang ingin mulai dari nol.

Docker Compose dan Firewall UFW di VPS

Nah, ini bagian yang sering terlewat dan bisa berbahaya. Jika anda sudah mengaktifkan firewall UFW di VPS (misalnya mengikuti artikel Cara Mengamankan VPS Linux Baru), mungkin anda mengira port 8080 tidak bisa diakses dari luar karena belum anda izinkan di UFW.

Kenyataannya, port yang di-publish oleh Docker bisa melewati aturan UFW. Menurut dokumentasi Docker tentang firewall, Docker mengarahkan lalu lintas container lewat tabel nat di iptables, yang diproses sebelum aturan filter milik UFW. Akibatnya, aturan UFW untuk port tersebut praktis diabaikan.

Peringatan: jangan menganggap sudo ufw status sebagai jaminan bahwa port container anda tertutup. Port seperti 8080:80 di compose.yaml akan terbuka ke seluruh internet, meskipun UFW tidak mengizinkannya.

Solusi paling sederhana adalah mem-publish port hanya ke localhost. Ubah bagian ports pada service wordpress menjadi:

    ports:
      - "127.0.0.1:8080:80"

Dengan begitu, sesuai dokumentasi port publishing, port 8080 hanya bisa diakses dari server itu sendiri. Untuk membukanya ke publik, letakkan reverse proxy (misalnya Nginx, Caddy, atau Traefik) di depannya yang menangani domain dan HTTPS, lalu buka port 80 dan 443 saja di UFW.

Terapkan perubahan dengan menjalankan ulang:

docker compose up -d

Bila anda hanya ingin mengakses WordPress dari komputer sendiri untuk sementara, anda juga bisa memakai SSH tunnel dari komputer lokal:

ssh -L 8080:127.0.0.1:8080 user@IP-SERVER-ANDA

Selama sesi SSH tersebut terbuka, buka http://localhost:8080 di browser komputer anda.

Satu catatan lagi: service yang tidak memiliki bagian ports, seperti db di contoh kita, sama sekali tidak terbuka ke luar. Database hanya bisa diakses oleh container lain di network project yang sama. Inilah alasan kenapa sebaiknya anda tidak mem-publish port database kecuali benar-benar perlu.

Tips Menggunakan Docker Compose

Tip #1: Kunci Versi Image untuk Produksi

Tag latest praktis untuk belajar, tetapi bisa membawa perubahan besar tanpa anda sadari saat menjalankan docker compose pull. Untuk server produksi, tulis versi yang lebih spesifik, misalnya wordpress:6-apache, lalu naikkan versinya secara sadar setelah membaca catatan rilis.

Tip #2: Selalu Pakai Kebijakan restart

Opsi restart: unless-stopped membuat container otomatis menyala kembali setelah server di-reboot atau setelah container crash, kecuali anda sendiri yang menghentikannya. Tanpa opsi ini, aplikasi anda akan tetap mati setelah server restart.

Tip #3: Satu Folder untuk Satu Project

Simpan setiap aplikasi di foldernya sendiri, misalnya ~/apps/wordpress, ~/apps/uptime-kuma, dan seterusnya. Selain rapi, cara ini membuat nama network dan volume tidak saling bentrok, serta memudahkan backup per aplikasi.

Tip #4: Butuh Antarmuka Grafis? Coba CapRover

Jika anda lebih nyaman mengelola aplikasi lewat dashboard web lengkap dengan HTTPS otomatis, platform seperti CapRover bisa menjadi alternatif. Panduannya ada di artikel Cara Install CapRover di VPS.

Kesimpulan

Dari artikel ini, kita dapat menyimpulkan bahwa Docker Compose adalah cara paling praktis untuk menjalankan aplikasi multi-container di satu server. Seluruh konfigurasi cukup ditulis sekali di compose.yaml, lalu dijalankan, diperbarui, dan dipindahkan dengan beberapa perintah singkat.

Yang Perlu Diingat

  • Gunakan perintah docker compose (dengan spasi), bukan docker-compose versi lama.
  • Baris version: di file Compose sudah usang dan tidak perlu ditulis lagi.
  • Simpan password di file .env, bukan langsung di compose.yaml.
  • Gunakan healthcheck dan depends_on dengan condition: service_healthy agar urutan start benar.
  • docker compose down -v menghapus data di volume secara permanen.
  • Di VPS, port Docker bisa melewati UFW. Publish ke 127.0.0.1 dan pakai reverse proxy.

Langkah Selanjutnya

Setelah WordPress berjalan, langkah logis berikutnya adalah memasang reverse proxy dengan HTTPS di depannya, lalu menyiapkan backup rutin untuk volume db_data dan wp_data. Setelah itu, anda bisa mencoba menjalankan aplikasi self-hosted lain dengan pola yang sama.

Punya pertanyaan atau kendala saat mencoba? Jangan ragu untuk bertanya. Tetap pantau terus web Teknotut!


Semoga artikel ini membantu.

Bacaan Selanjutnya

Artikel lain yang mungkin menarik buatmu.