Docker Swarm Lab: Hands-On Guide Membangun Kluster High Availability
8 min read

Setelah di artikel sebelumnya kita membahas filosofi "kenapa harus Docker Swarm", sekarang saatnya kita berhenti berteori dan mulai get our hands dirty. Di artikel ini, kita akan melakukan Step-by-Step Deployment untuk merakit kluster yang tangguh, dari nol sampai aplikasi Anda berjalan di banyak server sekaligus.
1. Persiapan Environment
Sebelum kita masuk ke konfigurasi masing-masing server, pastikan kamu sudah menyiapkan "bahan-bahan" berikut:
Virtualization Tool: Saya menggunakan Oracle VM VirtualBox.
Sistem Operasi: Image Ubuntu 24.04 LTS (Noble Numbat) untuk semua node server.
Spesifikasi Server:
Docker Manager 4 GB RAM dan 15 GB Hardisk.
Docker Worker 2 GB RAM dan 15 GB Hardisk.
Networking: Setiap VM dikonfigurasi dengan 2 Network Adapter:
Adapter 1 (NAT): Untuk akses internet (update package, install HAProxy, dll).
Adapter 2 (Host-Only): Digunakan untuk jaringan LAN antar VM (komunikasi internal agar IP
192.168.20.xbisa saling ping).
Source Code: Kita akan menggunakan API sederhana berbasis Go sebagai backend dan Frontend berbasis Nextjs. Kamu bisa melakukan clone dari repository ini:
Backend → https://github.com/mdrdani/GoDocAPI
frontend → https://github.com/mdrdani/frontend-GoDocAPI.
Docker: Dengan Docker, kita dapat dengan mudah mengatur dan mengelola environment yang diperlukan untuk menguji arsitektur yang telah dirancang.
DBeaver: Tambahkan DBeaver untuk akses dan manajemen database.
Koneksi Internet: Dibutuhkan selama proses instalasi dependency.
2. Persiapan Infrastruktur: The Blueprint

Sebelum mengetik perintah, kita butuh fondasi yang jelas.
Server A (Manager): Otak dari operasi kita.
Server B (Worker): Pasukan yang siap menjalankan beban kerja.
Server C (Database & Storage): Rumah bagi data kita agar tetap aman jika kluster aplikasi di-reset.
Catatan : Jangan pernah mencampur Database di dalam kluster Swarm aplikasi jika Anda masih awam dengan shared storage. Biarkan DB berdiri di server sendiri agar data Anda tidak "hilang" saat kontainer berpindah-pindah.
3. Install Docker
Langkah pertama adalah memastikan Docker terpasang di semua server (A, B, dan C). Gunakan skrip otomatis agar standar versinya sama di setiap mesin:
sudo apt install apt-transport-https ca-certificates curl software-properties-common -y
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
sudo usermod -aG docker $user
4. Setup Server C — PostgreSQL Database & RustFS Object Storage
Pada tahap ini, kita akan menyiapkan Server C (192.168.20.104) sebagai pusat penyimpanan data untuk kluster.
Server ini berperan sebagai:
Database server menggunakan PostgreSQL
Object storage menggunakan RustFS untuk menyimpan file aplikasi (assets, upload, dll)
Pastikan Anda sudah dapat mengakses server melalui SSH:
ssh user@192.168.20.104
Docker Compose
Selanjutnya, buat file docker-compose.yaml untuk menjalankan PostgreSQL dan RustFS dalam satu host.
services:
postgres:
image: postgres:16
container_name: postgres
restart: unless-stopped
environment:
POSTGRES_USER: app_user
POSTGRES_PASSWORD: app_password
POSTGRES_DB: app_db
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U app_user -d app_db"]
interval: 10s
timeout: 5s
retries: 5
rustfs:
image: rustfs/rustfs:latest
container_name: rustfs
restart: unless-stopped
ports:
- "9000:9000"
- "9001:9001"
environment:
RUSTFS_VOLUMES: /data/rustfs{0..3}
RUSTFS_ADDRESS: 0.0.0.0:9000
RUSTFS_CONSOLE_ADDRESS: 0.0.0.0:9001
RUSTFS_CONSOLE_ENABLE: "true"
RUSTFS_ACCESS_KEY: rustfsadmin
RUSTFS_SECRET_KEY: rustfsadmin
volumes:
- rustfs_data:/data
- rustfs_logs:/logs
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/"]
interval: 15s
timeout: 5s
retries: 5
start_period: 20s
volumes:
postgres_data:
rustfs_data:
rustfs_logs:
Jalankan service
Setelah file dibuat:
mkdir -p data/rustfs0 data/rustfs1 data/rustfs2 data/rustfs3 logs
docker compose up -d
Cek container:
docker ps
Akses service:
PostgreSQL →
192.168.20.104:5432RustFS API →
http://192.168.20.104:9000RustFS Console →
http://192.168.20.104:9001
Server C kini siap menjadi storage layer untuk cluster Docker Swarm pada tahap berikutnya.
Test Akses PostgreSQL

jangan lupa untuk inisialisasi Database schema dahulu:
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE TABLE IF NOT EXISTS documents (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
filename TEXT NOT NULL,
storage_path TEXT NOT NULL UNIQUE,
size BIGINT NOT NULL CHECK (size >= 0),
content_type TEXT NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_documents_filename ON documents (filename);
Test Akses RustFS


jika ingin melihat logs dari docker container yang telah kita jalankan jalankan perintah
docker compose logs -f

5. Setup Server A & B — Docker Swarm Manager dan Worker Node
Pada bagian ini kita akan menyiapkan Server A dan Server B sebagai node utama dalam kluster Docker Swarm. Pastikan kedua server sudah terinstall Docker Engine versi terbaru.
Inisialisasi Docker Swarm (Server A — Manager)
Masuk ke Server A lalu jalankan:
docker swarm init --advertise-addr 192.168.20.101
Output akan menampilkan join token worker, contoh:
docker swarm join \
--token SWMTKN-1-xxxxx \
192.168.20.101:2377

Simpan token tersebut untuk Server B.
Cek status swarm:
docker node ls
Server A akan berstatus:
Leader
Join Worker ke Cluster (Server B)
Masuk ke Server B, lalu jalankan token join dari Server A:
docker swarm join \
--token SWMTKN-1-xxxxx \
192.168.20.101:2377
Jika berhasil:
This node joined a swarm as a worker.
Verifikasi dari Server A:
docker node ls
Output seharusnya:

Manager → Server A
Worker → Server B
6. Deploy Aplikasi GoDocAPI & Frontend ke Docker Swarm
Setelah Server B berhasil join ke Server A (Manager), tahap berikutnya adalah build image aplikasi dan melakukan deployment menggunakan docker stack.
Semua proses build dan deployment dilakukan dari Server A (Manager). Alternatifnya, build dapat dilakukan melalui Github Actions atau Jenkins.
Clone Repository
Masuk ke Server A:
ssh user@192.168.20.101
Clone kedua repository:
git clone https://github.com/mdrdani/GoDocAPI.git
git clone https://github.com/mdrdani/frontend-GoDocAPI.git
Konfigurasi Environment Backend (GoDocAPI)
Masuk ke folder backend:
cd GoDocAPI
Copy file .env.example Edit file .env dan sesuaikan dengan Server C (192.168.20.104):
SERVER_PORT=:8080
DB_URL=postgres://swarmuser:swarmpassword@192.168.20.104:5432/swarmdb?sslmode=disable
RUSTFS_ENDPOINT=http://192.168.20.104:9000
RUSTFS_ACCESS_KEY=admin
RUSTFS_SECRET_KEY=password123
RUSTFS_BUCKET=godoc-bucket
RUSTFS_REGION=us-east-1
⚠️ Penting:
Jangan gunakan
localhost, karena backend berjalan di node berbeda.Gunakan IP Server C atau domain internal.
Build Image Backend (Golang)
Masih di folder GoDocAPI:
docker build -t godocapi:latest .
Verifikasi:
docker images | grep godocapi
Konfigurasi Environment Frontend (Next.js)
Masuk ke folder frontend:
cd ../frontend-GoDocAPI
Edit file .env:
API_URL=http://backend:8080
Penjelasan:
- Karena menggunakan Docker Swarm overlay network, service backend dapat diakses melalui service name (
backend), bukan IP.
Build Image Frontend (Next.js)
docker build -t frontendgodocapi:latest .
Cek image:
docker images | grep frontendgodocapi
Login ke Docker Hub
docker login

Tag Image
docker tag godocapi:latest cehamot/godocapi:latest
docker tag fegodocapi:latest cehamot/fegodocapi:latest
Push ke Docker Hub
docker push cehamot/godocapi:latest
docker push cehamot/fegodocapi:latest

Buat File docker-stack.yaml
Kembali ke direktori utama (misalnya buat folder khusus deploy):
mkdir swarm-deploy
cd swarm-deploy
Buat file docker-stack.yaml:
version: '3.8'
services:
frontend:
image: cehamot/fegodocapi:latest
ports:
# Publish port menggunakan routing mesh (akses dari semua node)
- "3000:3000"
environment:
# Mengakses backend via service name (internal DNS swarm)
- API_URL=http://backend:8080
deploy:
# Menjalankan 2 instance container untuk high availability
replicas: 2
# Restart hanya jika container error
restart_policy:
condition: on-failure
update_config:
# Rolling update 1 container per batch
parallelism: 1
# Delay 10 detik antar update container
delay: 10s
networks:
# Menggunakan overlay network antar node
- app-net
backend:
image: cehamot/godocapi:latest
ports:
# Publish API via routing mesh swarm
- "8080:8080"
env_file:
# File environment berisi DB & RustFS config (Server C)
- ../GoDocAPI/.env
deploy:
# 2 instance backend untuk redundancy
replicas: 2
restart_policy:
condition: on-failure
update_config:
# Rolling update satu per satu
parallelism: 1
delay: 10s
networks:
# Terhubung ke overlay network yang sama
- app-net
networks:
app-net:
# Network multi-host (wajib untuk komunikasi antar node swarm)
driver: overlay
Deploy ke Docker Swarm
Jalankan dari Manager:
docker stack deploy -c docker-stack.yaml godocapi
Cek service:
docker service ls

Cek detail task:
docker service ps godocapi_backend
docker service ps godocapi_frontend


cek detail logs:
docker service logs -f godocapi_backend
docker service logs -f godocapi_frontend


6.8 Verifikasi High Availability
Akses aplikasi melalui:
http://192.168.20.101:3000
atau
http://192.168.20.102:3000


Karena menggunakan:
Replicas: 2
Overlay network
Routing mesh
Swarm akan mendistribusikan container ke Manager dan Worker secara otomatis.
Kesimpulan
Secara keseluruhan, pada Part 1 ini kita telah berhasil membangun fondasi arsitektur High Availability menggunakan Docker Swarm dengan pendekatan yang menyerupai lingkungan produksi nyata. Dimulai dari inisialisasi cluster dengan pemisahan peran Manager dan Worker, kemudian memisahkan application layer (frontend dan backend) dari data layer (PostgreSQL dan RustFS di Server C), hingga melakukan deployment menggunakan docker-stack.yaml dengan konfigurasi replication, overlay network, dan rolling update. Aplikasi yang bersumber dari repository GoDocAPI dan frontend-GoDocAPI kini berjalan secara terdistribusi, memiliki kemampuan self-healing, load balancing internal melalui routing mesh, serta siap untuk scaling horizontal. Dengan fondasi ini, cluster sudah memenuhi prinsip dasar sistem terdistribusi yang resilien dan siap dikembangkan lebih lanjut pada tahap optimasi dan hardening di bagian berikutnya.
selanjutnya kita akan membahas "Maintenance & Scaling: Ketika User Meledak"
1. Scaling Up vs Scaling Out: Kapan harus tambah replika, kapan harus tambah server Worker. 2. Zero Downtime Deployment: Cara update image aplikasi tanpa memutus koneksi user.
3. Integrasi HAProxy sebagai reverse proxy layer
