Stack Docker all-in-one yang menyediakan dependency infrastructure untuk pengembangan backend: PostgreSQL 17, Redis 7, dan Apache Kafka 3.9. Stack hanya menyediakan service infrastructure, sedangkan runtime aplikasi dijalankan di host machine dan terhubung via connection string standar.
Stack bersifat generic sehingga cocok dipakai sebagai backend infra untuk project apapun, termasuk RESTForge.
- Ikhtisar (Overview)
- Prasyarat (Prerequisites)
- Struktur File (File Structure)
- Konfigurasi (Configuration)
- Cara Penggunaan (How to Use)
- Endpoint Service
- Pengaturan Memori (Memory Settings)
- Menghubungkan Aplikasi ke Stack (Connecting Applications)
- Pemecahan Masalah (Troubleshooting)
- Catatan Keamanan (Security Notes)
- Referensi (Reference)
Stack rf-stack terdiri dari tiga service infrastructure yang umum dibutuhkan untuk pengembangan backend:
| Service | Image | Fungsi |
|---|---|---|
rf-postgres |
Custom build dari postgres:17 |
Database utama dengan tuning profil Multi-App Dev |
rf-redis |
redis:7-alpine |
Cache, distributed lock, idempotency, dan job scheduler |
rf-kafka |
apache/kafka:3.9.0 |
Message broker (KRaft mode, tanpa Zookeeper) untuk consumer/producer |
Seluruh resource Docker (container, volume, image, network) di-prefix dengan rf- untuk mencegah konflik dengan setup container existing di host yang sama.
Pendekatan yang digunakan adalah "containerized infrastructure, host runtime": service infrastructure berjalan di dalam Docker, sedangkan aplikasi berjalan di host machine dan terhubung via port forwarding.
┌─────────────────────── Host (Windows / macOS / Linux) ──────┐
│ │
│ Aplikasi backend (di host machine) │
│ ├── dependencies / node_modules │
│ └── konfigurasi koneksi (DB_HOST=127.0.0.1) │
│ │
│ Eksekusi: aplikasi / CLI di host │
│ ↓ TCP via port forwarding │
│ │
│ ┌─── Docker (rf-stack) ───────────────────────┐ │
│ │ rf-postgres rf-redis rf-kafka │ │
│ └─────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘
Alasan pemilihan pendekatan ini:
- IDE debugging full support tanpa setup remote debugger
- Hot-reload natural saat development
- Pattern industry standard untuk dev workflow
| Software | Versi Minimum | Keterangan |
|---|---|---|
| Docker Desktop | 4.20+ | Untuk Windows, macOS, atau Docker Engine untuk Linux |
| Docker Compose | v2.x | Sudah include dalam Docker Desktop |
| Node.js | 20.x atau lebih baru | Hanya jika ingin menjalankan runtime aplikasi (Node.js) di host |
psql client (opsional) |
12+ | Untuk eksekusi SQL script ke rf-postgres |
| Resource | Rekomendasi |
|---|---|
| RAM | 8 GB (4 GB untuk stack + sisa untuk OS dan IDE) |
| Disk | 5 GB free space (untuk image dan volume data) |
| CPU | 2 core minimum |
Sebelum melanjutkan, pastikan Docker daemon berjalan:
docker --version
docker compose version
docker inforestforge-stack/
├── docker-compose.yml # Definisi stack (3 service)
├── .env # Konfigurasi lokal (password, port) — gitignored
├── .env.example # Template untuk .env
├── .gitignore # Exclude .env dari version control
├── .gitattributes # Paksa line ending LF untuk script .sh
├── README.md # File ini
├── rf-stack-start.bat # Start stack (Windows)
├── rf-stack-start.sh # Start stack (macOS/Linux)
├── rf-stack-stop.bat # Stop stack (Windows)
├── rf-stack-stop.sh # Stop stack (macOS/Linux)
├── rf-stack-rebuild.bat # Rebuild image rf-postgres17 (Windows)
├── rf-stack-rebuild.sh # Rebuild image rf-postgres17 (macOS/Linux)
├── rf-stack-drop.bat # Destructive: hapus resource (Windows)
├── rf-stack-drop.sh # Destructive: hapus resource (macOS/Linux)
└── postgres-config/
├── Dockerfile # Build postgres:17 + custom config
├── postgresql.conf # Tuning profil Multi-App Dev (2GB)
└── pg_hba.conf # Authentication (scram-sha-256)
Seluruh konfigurasi sensitif (password, port) dikelola via file .env. Template tersedia di .env.example:
# PostgreSQL 17
POSTGRES_PORT=5432
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres1234
POSTGRES_DB=postgres
# Redis 7
REDIS_PORT=6380
REDIS_PASSWORD=redis1234
# Apache Kafka 3.9
KAFKA_INTERNAL_PORT=9092
KAFKA_EXTERNAL_PORT=9094
KAFKA_CLUSTER_ID=MkU3OEVBNTcwNTJENDM2Qk| Service | Container Port | Host Port | Bind |
|---|---|---|---|
| PostgreSQL | 5432 | 5432 | 0.0.0.0 |
| Redis | 6379 | 6380 | 127.0.0.1 (localhost only) |
| Kafka (internal listener) | 9092 | 9092 | 0.0.0.0 |
| Kafka (external listener) | 9094 | 9094 | 0.0.0.0 |
Catatan: Redis sengaja dipetakan ke port 6380 (bukan 6379) untuk menghindari konflik dengan instance Redis lain yang umumnya pakai port default 6379.
Pilih salah satu cara untuk mendapatkan folder restforge-stack.
Opsi A: Clone via git (disarankan).
git clone https://github.com/restforge/restforge-stack.git
cd restforge-stackOpsi B: Download arsip ZIP.
- Buka halaman repository di GitHub
- Klik tombol Code, lalu Download ZIP
- Extract arsip, kemudian masuk ke folder hasil extract:
cd restforge-stackCopy template .env.example menjadi .env, lalu sesuaikan password/port:
# Windows (PowerShell)
copy .env.example .env
notepad .env
# macOS / Linux
cp .env.example .env
nano .envPerintah kanonik, berlaku lintas platform:
docker compose up -dPada eksekusi pertama, Docker akan build image rf-postgres17 (sekitar 30 detik), lalu menjalankan ketiga service. Tunggu hingga seluruh container berstatus healthy (lihat Langkah 4).
Sebagai alternatif, tersedia helper script yang membungkus perintah di atas plus menunggu container ready dan menampilkan ringkasan endpoint:
# Windows
rf-stack-start.bat
# macOS / Linux
chmod +x rf-stack-start.sh # cukup sekali
./rf-stack-start.shdocker ps --filter "name=rf-" --format "table {{.Names}}\t{{.Status}}"Output yang diharapkan:
NAMES STATUS
rf-postgres Up 30 seconds (healthy)
rf-redis Up 30 seconds (healthy)
rf-kafka Up 30 seconds (healthy)
Seluruh container harus dalam status healthy. Jika belum, tunggu beberapa saat dan cek ulang (Kafka biasanya butuh start_period 60 detik).
Database default postgres sudah dibuat otomatis. Jika aplikasi memerlukan database spesifik (misal dbinv atau myapp):
docker exec -it rf-postgres psql -U postgres -c "CREATE DATABASE dbinv;"# PostgreSQL
docker exec -it rf-postgres psql -U postgres -c "SELECT version();"
# Redis
docker exec -it rf-redis redis-cli -a redis1234 --no-auth-warning ping
# Kafka
docker exec -it rf-kafka /opt/kafka/bin/kafka-broker-api-versions.sh --bootstrap-server localhost:9092Seluruh operasi dapat dijalankan langsung dengan docker compose (lintas platform):
docker compose up -d # Mulai stack
docker compose down # Hentikan stack (data tetap aman di volume)
docker compose ps # Cek status service
docker compose logs -f # Pantau log seluruh service
docker compose build --no-cache postgres # Rebuild image PostgreSQL (lanjutkan dengan up -d)
docker compose down -v # Hapus container + volume (DESTRUCTIVE)Untuk kenyamanan tersedia helper script yang menambahkan konfirmasi keamanan, penundaan tunggu container ready, dan ringkasan status:
| Operasi | Windows | macOS / Linux |
|---|---|---|
| Mulai stack | rf-stack-start.bat |
./rf-stack-start.sh |
| Hentikan stack | rf-stack-stop.bat |
./rf-stack-stop.sh |
| Rebuild image PostgreSQL | rf-stack-rebuild.bat |
./rf-stack-rebuild.sh |
| Hapus seluruh resource (DESTRUCTIVE) | rf-stack-drop.bat |
./rf-stack-drop.sh |
Script drop juga menghapus image rf-postgres17 dan network rf-network, yang tidak ikut terhapus oleh docker compose down -v.
docker exec rf-postgres pg_dump -U postgres dbinv > backup-dbinv.sqltype backup-dbinv.sql | docker exec -i rf-postgres psql -U postgres -d dbinvdocker exec rf-redis redis-cli -a redis1234 --no-auth-warning SAVE
docker cp rf-redis:/data/dump.rdb ./redis-backup.rdbSetelah stack berjalan, service dapat diakses dari host machine via port berikut:
Host : 127.0.0.1
Port : 5432
User : postgres
Password : postgres1234 (atau sesuai .env)
Database : postgres (default), atau buat custom
Connection string (untuk client GUI seperti DBeaver, pgAdmin):
postgresql://postgres:postgres1234@127.0.0.1:5432/postgres
Host : 127.0.0.1
Port : 6380
Password : redis1234 (atau sesuai .env)
DB Index : 0 (default)
Connection string:
redis://:redis1234@127.0.0.1:6380/0
Bootstrap Server (dari host) : localhost:9094
Bootstrap Server (dari container) : kafka:9092
Untuk client di host machine (misal aplikasi runtime di host), gunakan endpoint localhost:9094 (external listener). Untuk service yang berjalan di network Docker yang sama, gunakan kafka:9092 (internal listener).
Setiap service memiliki konfigurasi memory yang dikalibrasi untuk dev workflow di laptop dengan RAM 8 GB+.
| Layer | Setting | Nilai |
|---|---|---|
| Container | deploy.resources.limits.memory |
2 GB |
| Container | deploy.resources.reservations.memory |
512 MB |
| Container | shm_size (shared memory) |
256 MB |
| Internal | shared_buffers |
512 MB |
| Internal | effective_cache_size |
1536 MB |
| Internal | work_mem (per operation) |
16 MB |
| Internal | maintenance_work_mem |
256 MB |
Profil yang digunakan: Multi-App Dev. Cocok untuk 5+ aplikasi yang connect bersamaan.
| Layer | Setting | Nilai |
|---|---|---|
| Container | deploy.resources.limits.memory |
768 MB |
| Container | deploy.resources.limits.cpus |
1.0 core |
| Internal | --maxmemory |
512 MB |
| Internal | --maxmemory-policy |
noeviction |
Kebijakan noeviction berarti Redis akan return error saat memory penuh, bukan menghapus data lama. Cocok untuk job scheduler dan distributed lock yang tidak boleh kehilangan data.
| Layer | Setting | Nilai |
|---|---|---|
| Container | deploy.resources.limits.memory |
1 GB |
| Container | deploy.resources.reservations.memory |
512 MB |
| Internal | KAFKA_HEAP_OPTS |
-Xmx512M -Xms512M |
Profil yang digunakan: Standard. Heap 512 MB cukup untuk dev karena workload Kafka sebagian besar adalah I/O via OS page cache, bukan heap JVM.
| Service | Memory Limit |
|---|---|
rf-postgres |
2 GB |
rf-redis |
768 MB |
rf-kafka |
1 GB |
| Total maksimal | ±3.8 GB |
Konsumsi aktual umumnya jauh di bawah limit. Cek konsumsi real-time dengan:
docker stats rf-postgres rf-redis rf-kafkaUntuk laptop dengan RAM lebih kecil (4 GB), turunkan limit dengan edit docker-compose.yml:
| Profil | PostgreSQL | Redis | Kafka |
|---|---|---|---|
| Minimal Dev (RAM host 4 GB) | 1 GB + shared_buffers 256 MB | 512 MB + maxmemory 256 MB | 512 MB + heap 256 MB |
| Standard (saat ini) | 2 GB + shared_buffers 512 MB | 768 MB + maxmemory 512 MB | 1 GB + heap 512 MB |
| Heavy (RAM host 16 GB+) | 4 GB + shared_buffers 1 GB | 1 GB + maxmemory 768 MB | 2 GB + heap 1 GB |
Setelah ubah docker-compose.yml (untuk Redis dan Kafka) atau postgresql.conf (untuk PostgreSQL), jalankan:
rf-stack-rebuild.batStack hanya menyediakan service infrastructure. Aplikasi backend dijalankan di host machine dan terhubung via connection string standar (lihat Endpoint Service).
Contoh konfigurasi koneksi pada file environment aplikasi:
# Database — PostgreSQL (rf-postgres)
DB_HOST=127.0.0.1
DB_PORT=5432
DB_USER=postgres
DB_PASSWORD=postgres1234
DB_NAME=myapp
# Redis — rf-redis
REDIS_HOST=127.0.0.1
REDIS_PORT=6380
REDIS_PASSWORD=redis1234
REDIS_DB=0
# Kafka — rf-kafka
KAFKA_BOOTSTRAP=localhost:9094Stack bersifat generic dan dapat dipakai sebagai backend infra untuk project apapun. Untuk project RESTForge, nilai di atas dipakai pada file config/db-connection.env milik project tersebut.
Untuk menjalankan SQL file (misal schema initialization) ke rf-postgres:
psql -h 127.0.0.1 -p 5432 -U postgres -d dbinv -f path/to/schema.sql# Copy file ke container
docker cp path/to/schema.sql rf-postgres:/tmp/schema.sql
# Eksekusi di database tertentu
docker exec -it rf-postgres psql -U postgres -d dbinv -f /tmp/schema.sqldocker exec -i rf-postgres psql -U postgres -d dbinv < path/to/schema.sqlPenyebab: Port 5432, 6380, 9092, atau 9094 sudah dipakai container atau service lain.
Solusi:
# Cek container yang dipakai port konflik
docker ps --format "table {{.Names}}\t{{.Ports}}"
# Stop container yang konflik
docker stop <nama_container>
# Coba start ulang rf-stack
rf-stack-start.batAlternatif: ubah port di .env (misal POSTGRES_PORT=5532), tetapi konsekuensinya konfigurasi koneksi di aplikasi juga perlu disesuaikan.
Diagnosa:
docker logs rf-postgres --tail 50
docker logs rf-redis --tail 50
docker logs rf-kafka --tail 50Penyebab umum:
| Error | Solusi |
|---|---|
out of memory saat startup |
Naikkan memory limit di docker-compose.yml atau turunkan tuning postgresql.conf |
could not bind IPv4 address |
Stop container lain yang pakai port sama |
Kafka cluster id mismatch |
Hapus volume rf-kafka-data dan restart (data hilang) |
| Permission denied pada volume | Drop dengan rf-stack-drop.bat, lalu start ulang |
Penyebab: File postgres-config/pg_hba.conf tidak ada saat build.
Solusi: Pastikan struktur folder lengkap:
postgres-config/
├── Dockerfile
├── postgresql.conf
└── pg_hba.conf
Solusi: Password tersimpan di file .env. Jika file .env hilang, ada dua pilihan:
-
Reset dengan drop dan recreate (data hilang):
rf-stack-drop.bat # Edit .env dengan password baru rf-stack-start.bat
-
Reset password tanpa hapus data (PostgreSQL only):
# Login dengan trust (local socket) docker exec -it rf-postgres psql -U postgres -c "ALTER USER postgres WITH PASSWORD 'newpassword';" # Update .env dengan password baru
Penyebab: Docker Desktop kadang reset volume saat major update.
Pencegahan: Selalu backup data sebelum update Docker Desktop.
# Backup PostgreSQL
docker exec rf-postgres pg_dumpall -U postgres > backup-all.sql
# Backup Redis
docker exec rf-redis redis-cli -a redis1234 --no-auth-warning SAVE
docker cp rf-redis:/data/dump.rdb ./redis-backup.rdbKonfigurasi default optimized untuk dev workflow di laptop personal. Beberapa aspek yang perlu diperhatikan:
- File
.envmengandung password dan tidak boleh di-commit ke git (sudah masuk.gitignore) - Password default (
postgres1234,redis1234) hanya cocok untuk dev, JANGAN dipakai di production pg_hba.confmengizinkan koneksi dari0.0.0.0/0dengan password authentication
Ubah konfigurasi berikut sebelum di-share:
-
Ganti password default di
.envdengan password yang kuat:POSTGRES_PASSWORD=<password_minimal_16_karakter> REDIS_PASSWORD=<password_minimal_16_karakter>
-
Batasi network exposure di
docker-compose.yml. Saat inirf-postgresdanrf-kafkadi-bind ke0.0.0.0. Ubah ke127.0.0.1jika hanya untuk local:ports: - "127.0.0.1:5432:5432" # bukan "5432:5432"
-
Restrict pg_hba.conf untuk subnet spesifik:
host all all 192.168.1.0/24 scram-sha-256(Bukan
0.0.0.0/0yang permissive)
Stack ini bukan production-ready. Untuk production, pertimbangkan:
- Tambahkan PgBouncer di depan PostgreSQL (connection pooling)
- Setup TLS/SSL untuk seluruh koneksi
- Implementasi automated backup (pgbackrest, pg_basebackup)
- Setup monitoring (Prometheus, Grafana)
- Pakai Kafka cluster multi-broker (saat ini single-broker)
- Streaming replication PostgreSQL untuk high availability
Detail tuning production dapat merujuk ke dokumentasi resmi PostgreSQL, Redis, dan Kafka.
- PostgreSQL 17 Documentation
- Redis 7 Documentation
- Apache Kafka 3.9 Documentation
- Docker Compose Documentation
| Komponen | Versi |
|---|---|
| PostgreSQL | 17.x (Debian) |
| Redis | 7.x (Alpine) |
| Apache Kafka | 3.9.0 (KRaft mode) |
| Docker Compose Schema | v3+ |
Versi Dokumen: 1.0 Tanggal: 2026-05-09