Mdr{dani} Notes

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

·

8 min read

Cover Image for Docker Swarm Lab: Hands-On Guide Membangun Kluster High Availability

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:

  1. Virtualization Tool: Saya menggunakan Oracle VM VirtualBox.

  2. Sistem Operasi: Image Ubuntu 24.04 LTS (Noble Numbat) untuk semua node server.

  3. Spesifikasi Server:

    Docker Manager 4 GB RAM dan 15 GB Hardisk.

    Docker Worker 2 GB RAM dan 15 GB Hardisk.

  4. 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.x bisa saling ping).

  5. 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.

  6. Docker: Dengan Docker, kita dapat dengan mudah mengatur dan mengelola environment yang diperlukan untuk menguji arsitektur yang telah dirancang.

  7. DBeaver: Tambahkan DBeaver untuk akses dan manajemen database.

  8. 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:5432

  • RustFS API → http://192.168.20.104:9000

  • RustFS 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

Mdr{dani} Notes

A digital garden where I plant ideas, share thoughts on DevOps, cloud infrastructure, open-source, and my journey in tech. Keep exploring and happy automating!

Explore Topics

Web DevelopmentReactNext.jsGolangOpen SourceTutorials

Supported By

Codeathome
LampungDev

Made with© 2026 Muhamad Dani Ramanda

Powered by HashnodeHosted on Vercel