On Premise

Docker Compose v2

Runbook instalasi AlurKerja on-premises di mesin lokal menggunakan CLI build-alurkerja. Dua fase otomatis dan idempoten — Setup (5 step, +1 di Windows) lalu Install yang dirakit sesuai konfigurasi, dari download code sampai semua container jalan di domain lokal ber-HTTPS.

A. Ringkasan & Definition of Done

Panduan ini menjalankan AlurKerja on-premises di mesin lokal menggunakan alurkerja-cli — CLI untuk operasional AlurKerja dengan command utama build-alurkerja. Command ini berjalan dua fase: Setup (5 step tetap, +1 khusus Windows) lalu Install yang dirakit sesuai konfigurasi — step yang tidak relevan (mis. Start postgres saat memakai database eksternal) tidak muncul sama sekali. Pipeline idempoten: step yang sudah selesai otomatis di-SKIP, jadi kalau gagal di tengah cukup jalankan ulang setelah masalahnya diatasi — tidak ada yang dikerjakan dua kali.

Halaman ini berlaku untuk CLI versi terbaru. Pastikan yang terpasang memang versi itu: alurkerja --version mencetak Alurkerja CLI v… beserta commit dan tanggal build. Kalau perintah tersebut ditolak — atau summary build menutup dengan NOTICE deprecation — yang terpasang masih CLI generasi lama; pasang ulang lewat Step 5.1, yang otomatis menyingkirkan binary lama dari PATH.

Daftar semua command CLI — termasuk jalur cepat --update-* dan server database terpisah (--db-server) — ada di Referensi Command CLI.

Definition of Done (DoD) — instalasi dianggap selesai bila:

  • Pipeline build-alurkerja selesai sampai step Summary dan menampilkan daftar URL akses.
  • Semua container dalam state running (docker compose ps tanpa Exited/Restarting).
  • Aplikasi dapat diakses di https://alurkerja.local:8100 dan Keycloak di https://alurkerja.local:8100/sso (skema domain lokal bawaan — lihat Section J).

Estimasi waktu eksekusi: ±20 menit untuk build pertama, paling lama di pull image (tergantung kecepatan internet). CLI menampilkan estimasi total di awal, estimasi per step di header-nya, dan durasi aktual tiap step selesai.

Sebelum mulai, download template logbook: alurkerja-install-docker-checklist-v2.xlsx. File ini sinkron 1:1 dengan nomor langkah di halaman ini — isi sambil eksekusi sebagai bukti audit dan referensi untuk instalasi berikutnya.

B. Prasyarat

Langkah 1–4 memastikan environment siap. Hentikan dan perbaiki bila ada langkah yang gagal — jangan lanjut sebelum prasyarat terpenuhi.

1. Verifikasi Docker Desktop berjalan

Aksi

docker version --format '{{.Server.Version}}'
docker compose version

Expected output

Versi Docker Engine dan Docker Compose version v2.x tampil tanpa error.

Jika gagal: pastikan Docker Desktop sudah terinstall dan dalam keadaan berjalan (ikon whale aktif). Di Linux, Docker Engine + plugin docker-compose-plugin juga bisa dipakai. Pipeline membutuhkan docker compose (V2, plugin) — bawaan Docker Desktop terbaru.

2. Verifikasi Git terpasang — opsional

Aksi

git --version

Expected output

git version 2.x.x atau lebih baru.

Perhatian: pipeline instalasi tidak membutuhkan git — code diunduh sebagai zip dan CLI hanya memeriksa docker beserta plugin compose. Git tetap berguna untuk command lain (mis. alurkerja deployment init, yang meng-clone template deployment), jadi langkah ini aman dilewati kalau tujuannya hanya instalasi.

Jika gagal: install Git dari git-scm.com (Windows) atau xcode-select --install / Homebrew (macOS).

3. Verifikasi akun Harbor

Aksi

Pastikan kamu punya username + password Harbor yang valid (dipakai CLI untuk docker login dan pull image).

Expected output

Credential Harbor tersedia.

Jika gagal: minta credential Harbor ke tim Javan — registry image AlurKerja terpusat di harbor.merapi.javan.id. Calon pengguna dari luar bisa mengajukannya sendiri lewat Request Access.

4. Verifikasi free storage minimal 8 GB

Aksi

Pastikan drive tempat folder download punya minimal 8 GB free — image docker ±5 GB (29 image: postgres, keycloak, nginx, minio, mailpit, service AlurKerja, dll.) + ruang ekstrak saat pull + volume + code.

Get-PSDrive C   # lihat kolom Free — sesuaikan huruf drive tujuan
df -h ~   # lihat kolom Avail

Expected output

Free space drive tujuan minimal 8 GB.

Perhatian: CLI juga menampilkan kebutuhan ini di awal dan memberi warning kalau drive folder download kurang dari 8 GB.

Catatan: storage bawaan memakai RustFS (S3-compatible, Apache-2.0) yang di-pull tanpa login dan tidak butuh lisensi. Instalasi yang dulu memakai MinIO dipindahkan otomatis saat CLI dijalankan ulang — lihat Section K.

C. Instalasi & Jalankan CLI

Langkah 5 punya dua cabang — pilih salah satu: 5.1 instalasi cepat (otomatis) atau 5.2 download manual. Keduanya berakhir sama: CLI terpasang dan pipeline build-alurkerja berjalan.

Perhatian: pipeline idempoten — aman dijalankan ulang kapan pun. Step yang sudah selesai ditandai SKIP.

5.1. Instalasi cepat (otomatis)

Aksi

Jalankan installer satu baris sesuai OS. Installer mendeteksi OS & arsitektur, mengunduh binary yang cocok, memasangnya ke PATH sebagai alurkerja, lalu langsung menjalankan build-alurkerja — tidak perlu Step 5.2, langsung lanjut ke Step 6:

irm https://cli.alurkerja.com/install.ps1 | iex
curl -fsSL https://cli.alurkerja.com/install.sh | bash

Expected output

Baris Platform & Install Dir tampil, checksum binary diverifikasi (Checksum verified.), lalu Installed: <path> — CLI mendarat di ~/.alurkerja/bin (Windows: %USERPROFILE%\.alurkerja\bin) dan pipeline build-alurkerja langsung berjalan.

Perhatian: installer menolak melanjutkan kalau checksum tidak bisa diambil atau tidak cocok — binary yang belum terverifikasi tidak pernah mendarat di PATH. Binary alurkerja lain yang sudah ada di PATH (mis. shim npm atau CLI generasi lama) dihapus supaya tidak menutupi yang baru.

Perhatian: perlu menjalankan ulang nanti? CLI sudah terpasang di PATH — cukup jalankan alurkerja build-alurkerja. Pipeline idempoten — aman dijalankan ulang kapan pun; step yang sudah selesai ditandai SKIP. Untuk naik ke versi CLI terbaru, jalankan lagi one-liner di atas: installer membandingkan checksum dan melewati download kalau binary sudah paling baru.

5.2. Download manual & jalankan binary

Aksi

Alternatif bila tidak memakai instalasi cepat (Step 5.1). Klik binary sesuai OS — semuanya dari distribusi resmi CLI:

OS / arsitekturBinary
Windows 64-bitalurkerja-windows-amd64.exe
macOS (Intel)alurkerja-darwin-amd64
macOS (Apple Silicon)alurkerja-darwin-arm64
Linux 64-bitalurkerja-linux-amd64
Linux ARM64alurkerja-linux-arm64

Windows 32-bit tidak lagi didukung. Checksum resminya ada di checksums.txt — cocokkan sebelum menjalankan binary, karena jalur manual ini tidak memverifikasinya untuk kamu:

(Get-FileHash -Algorithm SHA256 .\alurkerja-windows-amd64.exe).Hash.ToLower()
sha256sum ./alurkerja-linux-amd64      # macOS: shasum -a 256 ./alurkerja-darwin-arm64

Bandingkan hasilnya dengan baris file yang bersangkutan di checksums.txt; kalau berbeda, jangan dijalankan — download ulang.

Di macOS/Linux, beri permission executable (dan lepas quarantine di macOS):

chmod +x ./alurkerja-darwin-arm64
xattr -d com.apple.quarantine ./alurkerja-darwin-arm64   # macOS saja

Lalu jalankan command build-alurkerja dari binary yang di-download:

.\alurkerja-windows-amd64.exe build-alurkerja
./alurkerja-darwin-arm64 build-alurkerja

Sesuaikan nama binary dengan yang di-download (mis. alurkerja-darwin-amd64, alurkerja-linux-amd64).

Expected output

File binary ter-download, lalu pipeline mulai berjalan dan menampilkan fase Setup.

D. Eksekusi Pipeline build-alurkerja

6. Isi input yang diminta

Aksi

Semua kredensial bisa lewat prompt interaktif (password tersembunyi) atau flag. Input utama:

FlagPromptKegunaan
--harbor-userHarbor usernamedocker login
--harbor-passwordHarbor passworddocker login
--dirFolder downloadLokasi code. Tanpa flag: muncul prompt — enter kosong memakai folder saat ini. Kalau folder saat ini bermasalah (folder sistem seperti C:\Windows/Program Files, OneDrive, atau non-kosong yang bukan hasil download lama), muncul warning tanpa menghentikan CLI — cukup ketik lokasi lain di prompt yang sama. Folder ketikan dipakai apa adanya (tanpa subfolder) dengan validasi yang sama; folder tujuan dites tulis sebelum download.

Lalu di Setup features (Setup step 3) muncul satu layar toggle untuk 5 resource: panah atas/bawah pindah baris, enter/spasi mengganti local↔external, enter di Continue melanjutkan (terminal non-interaktif: menu bernomor per fitur). Default semua local (container bawaan) — untuk instalasi standar cukup langsung Continue. Resource yang di-set external ditanya detail koneksinya (langsung dites, fail-fast) dan container bawaannya tidak dijalankan:

ResourceToggle flagFlag detail (mode external)Catatan mode external
Storage--storage--s3-endpoint, --s3-access-key, --s3-secret-key, --s3-bucketServer MinIO/S3 sendiri — bucket harus sudah ada. Mode ini tidak menjalankan container storage bawaan (RustFS).
Database--database--db-host, --db-port, --db-user, --db-password, --db-name, --db-keycloak-nameServer PostgreSQL sendiri — user butuh hak CREATE DATABASE; server wajib punya extension pgvector. Belum punya server-nya? Siapkan dengan alurkerja build-alurkerja --db-server di mesin database (Referensi Command CLI).
Keycloak--keycloak--keycloak-url, --keycloak-setup (script/manual) + kredensial admin atau 5 nilai realm/clientSatu URL publik yang terjangkau browser & container.
SMTP--smtp--smtp-host, --smtp-port, --smtp-user, --smtp-password, --smtp-fromKosongkan username untuk relay tanpa auth.
Redis--redis--redis-host, --redis-port, --redis-password, --redis-dbKosongkan password untuk Redis tanpa auth.

Di akhir wizard ada pertanyaan Application secrets: generate otomatis (default) atau masukkan 4 secret existing — --tenant-encryption-key, --tenant-encryption-iv, --jwt-secret, --jwt-refresh-secret (base64, input tersembunyi). Wajib memakai secret yang sama saat memakai database bekas instalasi sebelumnya, karena data terenkripsi butuh kunci yang sama. All-or-nothing: isi keempatnya atau tidak sama sekali (parsial = error).

Referensi lengkap semua variabel .env — termasuk mana yang di-generate otomatis oleh installer dan mana yang diisi user — ada di Section H.

Expected output

Semua prompt terisi dan layar fitur dikonfirmasi — pipeline lanjut ke fase Install dengan estimasi total dan daftar step hasil rakitan.

Perhatian: fitur yang sudah ditentukan lewat flag tidak muncul lagi di layar toggle. Pada instalasi existing (.env sudah ada), CLI menawarkan tiga pilihan: Do nothing (konfigurasi saat ini dipertahankan), Reconfigure features, atau Update the public domain — yang terakhir keluar dari pipeline install dan menjalankan jalur ganti domain (Section J). Kembali ke mode local kapan pun — nilai .env terkait dikembalikan ke bawaan lokal otomatis. Detail lengkap tiap mode external (nilai .env yang ditulis, perilaku container) ada di README repo alurkerja-cli.

7. Pantau pipeline sampai selesai

Aksi

Biarkan pipeline berjalan. Fase Setup 5 step — 6 di Windows. Semua interaksi dengan user (prompt, wizard, dialog UAC) sengaja dikumpulkan di fase ini supaya fase Install bisa berjalan tanpa ditunggui:

#StepKeterangan
1Cek prasyarat (docker, harbor login)Pastikan docker (daemon jalan) dan docker compose tersedia, lalu login Harbor — kredensial diminta di sini, tidak di tengah pipeline. SKIP kalau semua sudah siap.
2Download release-alurkerja-localDownload code (zip) ke folder pilihan (lihat Step 6). Kalau code sudah ada: hanya refresh config/*.sql — file lain termasuk .env tidak disentuh, supaya update schema selalu terbawa.
3Setup featuresLayar toggle 5 resource + pertanyaan Application secrets di akhir (lihat Step 6). Instalasi existing: Do nothing, Reconfigure features, atau Update the public domain.
4Register local domains in hosts fileDomain yang masih bawaan .env.example (alurkerja.local, microsite-alurkerja.local, minio-alurkerja.local) didaftarkan ke 127.0.0.1 — butuh admin/root (UAC di Windows, sudo di macOS/Linux). Entri yang sudah ada → SKIP tanpa prompt; domain kustom dilewati (DNS urusan operator). Gagal = warning + baris manual, pipeline lanjut.
5Setup local HTTPS (mkcert)Unduh mkcert (versi ter-pin, checksum diverifikasi), pasang root CA ke trust store OS, terbitkan sertifikat untuk ketiga domain di atas, tulis nginx/tls/tls.conf + docker-compose.override.yml (bundle CA untuk container), lalu antre PUBLIC_SCHEME=https, WS_SCHEME=wss, NGINX_PUBLIC_TARGET=443 ke .env. Code lama tanpa NGINX_PUBLIC_TARGET di .env.example → dilewati, instalasi tetap http.
6Reserve ports 8100–8109Windows saja. netsh ... add excludedportrange lewat PowerShell elevated supaya Hyper-V/WSL tidak mencaplok rentang port setelah reboot. Sudah terreservasi → SKIP; UAC ditolak/gagal → warning, pipeline lanjut.

Fase Install dirakit dari hasil Setup — jumlah step menyesuaikan konfigurasi:

StepKapan adaKeterangan
Stop stack lamaSelaluDown project compose bernama sama dari folder lain — sisa download lama. Volume tidak dihapus. SKIP kalau tidak ada.
Copy .env.example → .envHanya kalau .env belum adaEditan manual tidak pernah ditimpa.
Apply features ke .envHanya kalau ada nilai fitur untuk ditulisMenulis env hasil Setup features (Do nothing = step ini tidak ada).
Migrate MinIO data to RustFSHanya kalau storage local, volume alurkerja_minio_data ada, dan migrasi belum pernah berhasil — instalasi baru tidak pernah melihat step iniMenyalin bucket dari volume MinIO lama ke RustFS (Section K).
Cek port bentrokSelaluFail-fast dengan pesan siapa pemegang portnya; stack ini sendiri tidak dihitung.
Start postgresHanya mode DB localdocker compose up -d postgres + tunggu ready.
Init databaseSelaluMembuat database + schema. SKIP kalau keycloak_db sudah ada.
Setup pgvectorHanya mode DB eksternalVerifikasi paket extension vector tersedia di server — fail-fast dengan petunjuk instalasi kalau belum.
Load public schema, lalu Load camunda schemaSelalu (dua step terpisah)SQL idempoten — update schema terpasang di run ulang tanpa kehilangan data.
Pull ImageSelaluDownload semua image (bagian terlama); service yang di-exclude tidak di-pull.
Start nginx(, keycloak), toolsSelaluKeycloak eksternal: step-nya tanpa keycloak.
Setup KeycloakKecuali Keycloak eksternal + manualMenjalankan scripts/setup-keycloak.sh di container tools.
Generate secretsSelaluopenssl rand -base64 di container tools untuk TENANT_SETTINGS_ENCRYPTION_KEY, TENANT_SETTINGS_ENCRYPTION_IV, JWT_SECRET, JWT_REFRESH_SECRET. Hanya nilai kosong / masih placeholder yang diganti — nilai hasil generate sebelumnya tidak pernah di-rotate.
Update .envSelaluMenulis nilai keycloak (dari script atau input manual).
Start AllSelaludocker compose up -d --force-recreate dengan .env final; service excluded di-stop.
SummarySelaluMenampilkan daftar URL akses.

Alur untuk mode default (semua resource local):

Expected output

Step Summary tampil dengan daftar URL akses.

Jika gagal: baca pesan errornya, perbaiki penyebabnya (mis. Docker belum jalan), lalu jalankan ulang command yang sama — step yang sudah beres di-SKIP. Lihat juga Section F.

E. Verifikasi & Akses Pertama Kali

8. Validasi semua container running

Aksi

Dari folder download (lihat lokasi yang dipilih di Step 6):

docker compose ps

Expected output

Semua container berstatus running/healthy — tidak ada Exited atau Restarting.

Jika gagal: kalau ada container yang crash loop, cek log: docker compose logs --tail=50 <service>.

9. Akses aplikasi

Aksi

Buka URL berikut di browser (sesuai output Summary). Port diambil dari .env: AK_PORT_NGINX untuk semua URL web (default 8100) dan AK_PORT_POSTGRES untuk database (default 8101) — resource yang di-set eksternal tampil dengan alamat eksternalnya.

Instalasi bawaan memakai domain lokal + HTTPS: CLI mendaftarkan ketiga domain ke hosts file dan menerbitkan sertifikat mkcert, jadi semua URL memakai https dan modul-modul utama berbagi satu domain sebagai subpath.

ServiceURLCredential
Databaselocalhost:8101postgres / JelasAlurnya
Apphttps://alurkerja.local:8100—
Studiohttps://alurkerja.local:8100/studio—
Comprohttps://alurkerja.local:8100/compro—
Simulationhttps://alurkerja.local:8100/simulation—
BE (API)https://alurkerja.local:8100/api/v1—
API Docshttps://alurkerja.local:8100/studio/apidocs—
Keycloak (SSO)https://alurkerja.local:8100/ssoadmin-keycloak / JelasAlurnya
Camundahttps://alurkerja.local:8100/camundaadmin-camunda / JelasAlurnya
Mailpithttps://alurkerja.local:8100/mailpit—
Micrositehttps://microsite-alurkerja.local:8100—
Minio (API)https://minio-alurkerja.local:8100—
Minio (Console)https://minio-alurkerja.local:8100/rustfs/console/admin-minio / JelasAlurnya

Kredensial di atas adalah default .env.example — sengaja seragam (JelasAlurnya) supaya instalasi lokal gampang. Begitu instance-nya bisa dijangkau orang lain, ganti dulu di .env (POSTGRES_PASSWORD, KEYCLOAK_ADMIN_PASSWORD, MINIO_SECRET_KEY, CAMUNDA_PASSWORD) sebelum dipakai.

Nilai domain dibaca dari .env (NGINX_DOMAIN, MICROSITE_DOMAIN, MINIO_DOMAIN) — kalau diubah, seluruh URL di atas ikut. Keycloak tidak punya host sendiri: ia subroute /sso di domain utama (SSO_DOMAIN=${NGINX_DOMAIN}${PUBLIC_PORT_SUFFIX}/sso).

Expected output

Halaman App ter-render di https://alurkerja.local:8100 tanpa peringatan sertifikat (root CA mkcert sudah dipercaya) dan admin console Keycloak terbuka di https://alurkerja.local:8100/sso.

Perhatian: mau memakai domain sendiri (mis. alurkerja.dev) alih-alih domain lokal? Prosedur dan peta URL-nya ada di Section J.

Perhatian: operasi setelah instalasi — menghidupkan/mematikan stack, mengosongkan data, sampai menghapus tuntas service dan CLI — ada di Section I. Lifecycle Service.

F. Troubleshooting

  • Gagal di tengah? Baca pesan errornya, perbaiki penyebabnya (mis. Docker belum jalan), lalu jalankan ulang — step yang sudah beres di-SKIP.
  • Port bentrok? Step Cek port bentrok menyebutkan pemegang portnya. Stack AlurKerja lama dengan nama berbeda: matikan dengan docker compose -p <nama-project> down; proses non-Docker: tutup aplikasinya dulu.
  • Proses terputus saat init database? Cukup jalankan ulang — step Load public & camunda schema selalu diulang dan idempoten. Kasus sangat jarang: init_db terputus tepat setelah membuat keycloak_db tapi sebelum schema camunda dibuat → drop database keycloak_db lalu jalankan ulang.
  • unauthorized: access to the requested resource is not authorized saat pull image MinIO: folder instalasi masih memakai docker-compose.yml lama yang menunjuk quay.io/minio/minio / quay.io/minio/mc. Kedua repo itu tidak lagi melayani pull anonim — jalankan ulang build-alurkerja supaya code terbaru (storage RustFS) terunduh dan datanya dipindahkan (Section K).
  • Console storage kosong atau 404? Console RustFS ada di /rustfs/console/ (mis. https://minio-alurkerja.local:8100/rustfs/console/); /console hanya mengalihkan ke sana. Reverse proxy atau tunnel di depan nginx harus meneruskan path /rustfs/console/ ke nginx juga.
  • Step Migrate MinIO data to RustFS gagal (tidak ada image yang bisa membuka volume lama, lisensi AIStor ditolak, atau server lama tidak siap dalam 2 menit)? Lihat K.2.
  • Login berputar di /callback dan log auth berisi jwks unavailable ... no key for kid pada domain bersertifikat CA internal perusahaan? Lihat J.3.
  • Error $'\r': command not found saat setup Keycloak: folder download warisan lama masih ber-CRLF. Hapus folder itu lalu jalankan ulang — download baru selalu LF.

Lihat juga Handbook Troubleshooting untuk daftar lebih luas.

G. Logbook Instalasi

Template berikut sinkron 1:1 dengan nomor langkah di halaman ini.

NoSectionAksiHasilBuktiPICCatatan
1PrasyaratVerifikasi Docker Desktop berjalan
2PrasyaratVerifikasi Git terpasang
3PrasyaratVerifikasi akun Harbor
4PrasyaratVerifikasi free storage minimal 8 GB
5.1InstalasiInstalasi cepat (otomatis: install + jalankan build-alurkerja)
5.2InstalasiDownload manual & jalankan binary build-alurkerja
6EksekusiIsi input yang diminta
7EksekusiPantau pipeline sampai selesai (step Summary)
8VerifikasiValidasi semua container running
9VerifikasiAkses aplikasi

H. Variabel Environment

Referensi status semua variabel .env (file tunggal di root folder download). Status ditentukan bukan sekadar "ada isinya di .env" — tapi dari nalar: apakah service benar-benar berhenti/rusak tanpanya, atau tetap jalan dengan fallback/fitur nonaktif. Variabel alias (mis. DB_USER=${POSTGRES_USER}) mengikuti status sumbernya dan ditandai (alias, otomatis) — tidak perlu diisi manual terpisah.

  • Wajib — tanpa nilai yang benar, service terkait gagal start atau fitur intinya patah.
  • Optional — sudah ada default yang aman, atau memang integrasi/fitur tambahan yang boleh dikosongkan (fitur terkait nonaktif secara aman, bukan error).
  • Tanda (installer: …) — nilai ini di-generate/ditulis otomatis oleh installer alurkerja-cli (build-alurkerja): nilai Keycloak dari setup-keycloak.sh dan application secrets dari step Generate secrets. Jangan diisi manual duluan — installer hanya mengisi nilai yang masih kosong/placeholder dan tidak pernah me-rotate nilai yang sudah ada. Variabel tanpa tanda ini diisi user (langsung di .env, atau lewat wizard/flag installer untuk mode eksternal). Instalasi manual tanpa CLI: semua diisi sendiri.

1. Database Configuration (PostgreSQL)

VariabelDeskripsiStatusDefault/Contoh
POSTGRES_USERUser Postgres untuk container internalWajibpostgres
POSTGRES_PASSWORDPassword Postgres container internalWajibJelasAlurnya (default lokal — ganti untuk instance yang bisa dijangkau orang lain)
POSTGRES_DBNama database aplikasi utamaWajibalurkerja_db
POSTGRES_PORTPort Postgres di hostOptional5432 (ubah hanya kalau bentrok port lain)
DB_HOSTHost yang dipakai semua service utk connect DBWajibpostgres (nama container)
DB_PORTPort yang dipakai service utk connect DBWajib5432
DB_USERUsername DB dipakai serviceWajib (alias POSTGRES_USER, otomatis)-
DB_PASSWORDPassword DB dipakai serviceWajib (alias POSTGRES_PASSWORD, otomatis)-
DB_NAMENama DB dipakai serviceWajib (alias POSTGRES_DB, otomatis)-
DB_SCHEMASchema defaultOptionalpublic (sudah sesuai public.sql)
DB_SSLMODEMode SSL koneksi DBOptionaldisable (ubah ke require/verify-full kalau Postgres eksternal mewajibkan SSL)
DB_MAX_OPEN / DB_MAX_IDLE / DB_LIFETIMETuning connection poolOptionalsudah ada default aman
CAMUNDA_DB_USERNAME / CAMUNDA_DB_PASSWORDKredensial DB khusus CamundaWajib-
CAMUNDA_DB_URLJDBC URL Camunda ke PostgresWajib-
KEYCLOAK_DB_NAMENama database terpisah untuk KeycloakWajibkeycloak_db (dibuat otomatis oleh init_db.sql)
DB_ADDRDSN format Go untuk tool migrationWajib-

Prasyarat Schema Database (public.sql) — Extension pgvector

config/public.sql (schema utama) butuh extension pgvector (vector) dan pg_trgm aktif di server PostgreSQL sebelum dijalankan — dipakai untuk kolom embedding (knowledge_chunks) dan pencarian trigram. Script ini sudah punya pre-flight check di baris awal yang akan gagal dengan pesan jelas kalau extension belum tersedia, daripada error samar di tengah jalan.

Postgres internal (docker-compose bawaan): sudah otomatis tersedia — service postgres di docker-compose.yml memakai image pgvector/pgvector:pg16 (bukan postgres:16-alpine polos). Tidak perlu langkah tambahan.

Postgres eksternal (mode --database external / managed sendiri): pgvector harus sudah terpasang/aktif di server tersebut sebelum menjalankan public.sql:

  • Managed cloud Postgres (AWS RDS/Aurora, Supabase, Neon, Google Cloud SQL, Azure Database for PostgreSQL Flexible Server, dll) — pgvector biasanya sudah tersedia dari provider, cukup pastikan bisa CREATE EXTENSION vector; (script ini sudah melakukannya otomatis).
  • Server self-managed (VM/bare metal sendiri) — install manual dulu mengikuti dokumentasi resmi pgvector.

2. Keycloak Configuration

VariabelDeskripsiStatusDefault/Contoh
KEYCLOAK_URLURL server KeycloakWajib (turunan, otomatis)${SSO_ORIGIN} → https://alurkerja.local:8100/sso. Jangan diedit langsung — pindahkan SSO lewat SSO_DOMAIN (grup #19).
KEYCLOAK_REALMNama realm KeycloakWajib (installer: hasil setup-keycloak.sh)alurkerja
KEYCLOAK_CLIENTClient ID Keycloak (confidential)Wajib (installer: hasil setup-keycloak.sh)onprem
KEYCLOAK_CLIENT_SECRETClient secret, dipakai backend validasi tokenWajib (installer: hasil setup-keycloak.sh; mode Keycloak eksternal + manual: diisi user)-
KEYCLOAK_ADMIN_USER / KEYCLOAK_ADMIN_PASSWORDKredensial admin, dipakai provisioning realm otomatis (setup-keycloak.sh)Wajibadmin-keycloak / JelasAlurnya (default lokal — ganti untuk instance yang bisa dijangkau orang lain)
KEYCLOAK_BASE_URLAlias KEYCLOAK_URL utk service lainWajib (alias, otomatis)-
KEYCLOAK_CLIENT_IDAlias KEYCLOAK_CLIENTWajib (alias, otomatis)-
KEYCLOAK_USE_JWKS_URLPaksa pakai JWKS URL manualOptionalfalse (biarkan false agar dibentuk otomatis dari BASE_URL+REALM)
KEYCLOAK_ISSUER / KEYCLOAK_JWKS_URLOverride issuer/JWKS manualOptionalkosong = otomatis

3. MinIO / Storage Configuration

Service minio menjalankan image RustFS (rustfs/rustfs, volume rustfs_data). Namanya sengaja tetap minio, jadi semua variabel MINIO_* di bawah tetap berlaku apa adanya; RustFS membaca kredensialnya dari MINIO_ACCESS_KEY/MINIO_SECRET_KEY dan region dari STORAGE_REGION. Container minio-init (pembuat bucket) memakai klien quay.io/minio/aistor/mc, yang bisa di-pull tanpa login dan tidak memerlukan lisensi.

VariabelDeskripsiStatusDefault/Contoh
MINIO_ENDPOINTEndpoint MinIO (host:port publik, tanpa scheme)Wajib (turunan, otomatis)${MINIO_DOMAIN}${PUBLIC_PORT_SUFFIX} → minio-alurkerja.local:8100
MINIO_ACCESS_KEY / MINIO_SECRET_KEYKredensial MinIOWajibadmin-minio / JelasAlurnya (default lokal — ganti untuk instance yang bisa dijangkau orang lain)
MINIO_BUCKET_NAMENama bucket utamaWajibalurkerja
MINIO_USE_SSLEndpoint pakai HTTPSOptionalfalse (wajib true kalau endpoint eksternal HTTPS)
MINIO_BROWSER_REDIRECT_URLURL publik console MinIO. Tidak dibaca RustFS (console-nya di /rustfs/console/); tetap ada untuk instalasi yang memakai MinIO sendiriOptional (turunan, otomatis)${MINIO_ORIGIN}/console/
STORAGE_PROVIDERProvider storage aktifOptionalminio (sudah sesuai stack ini)
STORAGE_BUCKET / STORAGE_KEY / STORAGE_SECRET / STORAGE_HOST / STORAGE_PORT / STORAGE_USE_SSL / STORAGE_URL_PREFIXAlias MINIO_* untuk service dgn naming bedaWajib (alias, otomatis)-
STORAGE_REGIONRegion utk signing S3 SDKOptionalap-southeast-3 (MinIO tidak validasi region asli)
STORAGE_LOCAL_PATHPath fallback storage lokalOptionaltidak dipakai selama STORAGE_PROVIDER=minio
AWS_REGIONAlias STORAGE_REGION utk library S3-compatible tertentuOptional (alias, otomatis)-
MINIO_BUCKET_LOOKUPGaya alamat bucket S3 client. Kosongkan untuk MinIO — kosong = perilaku lama, instalasi MinIO yang sudah jalan tidak perlu diubah. Isi dns hanya untuk storage S3-compatible yang mewajibkan alamat virtual-host, mis. Tencent COS. Berlaku di bpm-service, integration-service, report-service, notification-service, tenant-management-service, company-profile-service, helpdesk-reactOptionalkosong
STORAGE_BUCKET_LOOKUPAlias fungsional MINIO_BUCKET_LOOKUP untuk go-simulation dan generate-test-serviceOptionalkosong = perilaku lama

4. Redis / Cache Configuration

VariabelDeskripsiStatusDefault/Contoh
REDIS_HOST / REDIS_PORTHost & port RedisWajibredis / 6379 — caching enabled default (CACHE_ENABLED=true)
REDIS_PASSWORDPassword RedisOptionalkosong = tanpa auth (default lokal); isi kalau Redis eksternal butuh auth
REDIS_DBIndex database RedisOptional0
CACHE_PROVIDERProvider cache aktifOptionalredis
CACHE_ENABLEDAktifkan cachingOptionaltrue (tidak disarankan dimatikan di produksi, tapi tidak fatal)
CACHE_TTL / CACHE_MAX_SIZETuning cacheOptionalsudah ada default

Redis untuk antrean (REDIS_QUEUE_*, container redis-queue) adalah instance terpisah dan tidak tercakup tabel di atas — lihat Env Konsolidasi Antrean (asynq).

5. Sentry Configuration

VariabelDeskripsiStatusDefault/Contoh
SENTRY_DSNDSN error trackingOptionalkosong = tracking nonaktif meski SENTRY_ENABLED=true
SENTRY_TOKEN / SENTRY_ORG / SENTRY_PROJECTSKredensial otomasi release/source-map uploadOptionalhanya relevan utk CI/CD Sentry
SENTRY_ENVIRONMENTLabel environment di SentryOptionalproduction
SENTRY_ENABLED / SENTRY_DEBUG / SENTRY_SEND_DEFAULT_PII / SENTRY_ENABLE_TRACING / SENTRY_TRACES_SAMPLE_RATE / SENTRY_ENABLE_LOGSTuning SDK SentryOptionalhanya relevan kalau SENTRY_DSN diisi

6. OpenAI Configuration

VariabelDeskripsiStatusDefault/Contoh
OPENAI_API_KEYAPI key OpenAIOptionalkosong = fitur AI (generate BPMN, dll) nonaktif, bukan blocker core app
OPENAI_BPMN_MODEL / OPENAI_BPMN_TIMEOUT / OPENAI_BPMN_MAX_TOKENS / OPENAI_BPMN_TEMPERATURETuning model BPMN generationOptionalhanya relevan kalau API key diisi
OPEN_AI_API_KEYAlias OPENAI_API_KEYOptional (alias, otomatis)-
OPEN_AI_PURPOSE_MODEL / OPEN_AI_PURPOSE_TEMPERATURE / OPEN_AI_PURPOSE_MAX_TOKENS / OPEN_AI_PURPOSE_TIMEOUTTuning model utk use-case lainOptionalsama alasan
NORA_MODELModel yang dipakai NORA untuk membuat SOPOptionalgpt-5.6-sol
NORA_MAX_TOKENSBatas token jawaban NORA. Naikkan bila proses yang digambar sangat panjang dan diagramnya terpotongOptional16000; nilai non-angka atau ≤ 0 diabaikan dan default dipakai
AI_GATEWAY_API_KEYKey AI gateway untuk Generate di Company Profile (company-profile-service) dan chat AI Helpdesk (helpdesk-react). Bila diisi, permintaan dikirim ke gateway lebih dulu. OpenAI langsung dipakai sebagai cadangan bila gateway menjawab 401, 429, 5xx, atau tidak bisa dihubungiOptionalkosong = gateway nonaktif, permintaan langsung ke OpenAI
AI_GATEWAY_BASE_URLAlamat AI gateway (OpenAI-compatible)Optionalhttps://ai.merapi.javan.id/v1

NORA memakai OPENAI_API_KEY yang sama dengan fitur AI lainnya. Tanpa key tersebut, menu Create SOP with NORA akan gagal saat dijalankan — sisa aplikasi tetap berjalan normal.

AI gateway tidak menggantikan key OpenAI. Key OpenAI tetap dipakai sebagai cadangan, dan embedding knowledge base Helpdesk selalu dikirim ke OpenAI.

7. Email Configuration (Notification & Tenant Management)

VariabelDeskripsiStatusDefault/Contoh
EMAIL_HOST / EMAIL_PORTHost & port SMTPWajibmailpit / 1025 (SMTP dev bawaan docker-compose)
EMAIL_USER / EMAIL_PASSKredensial SMTPOptionalkosong valid utk mailpit (tanpa auth); wajib diisi kalau SMTP eksternal butuh auth
EMAIL_FROMAlamat pengirimWajibno-reply@alurkerja.com
MAIL_HOST / MAIL_PORT / MAIL_USERNAME / MAIL_PASSWORDAlias EMAIL_* utk service dgn naming bedaMengikuti status EMAIL_* (alias, otomatis)-

8. JWT Configuration

VariabelDeskripsiStatusDefault/Contoh
JWT_SECRETSecret signing token aksesWajib (installer: generate otomatis — step Generate secrets, atau flag --jwt-secret)-
JWT_REFRESH_SECRETSecret signing refresh tokenWajib (installer: generate otomatis — step Generate secrets, atau flag --jwt-refresh-secret)-
JWT_EXPIRATION / JWT_EXPIRES_IN_HOURS / JWT_SESSION_DAYS / JWT_REFRESH_EXPIRATIONMasa berlaku tokenOptionalsudah ada default aman

9. Encryption Configuration (Tenant Settings)

VariabelDeskripsiStatusDefault/Contoh
TENANT_SETTINGS_ENCRYPTION_KEYKey enkripsi tenant settings (Base64)Wajib (installer: generate otomatis — step Generate secrets; database bekas: wajib pakai key lama via flag --tenant-encryption-key)kalau berubah setelah data tersimpan, data lama tidak bisa didekripsi lagi
TENANT_SETTINGS_ENCRYPTION_IVIV enkripsi (Base64)Wajib (installer: generate otomatis — step Generate secrets; database bekas: wajib pakai IV lama via flag --tenant-encryption-iv)sama alasan
AES_KEY / AES_IVAlias TENANT_SETTINGS_ENCRYPTION_KEY/IVWajib (alias, otomatis)sama alasan

10. Camunda Configuration (Migration Service)

VariabelDeskripsiStatusDefault/Contoh
CAMUNDA_URLURL Camunda engine-restWajib-
CAMUNDA_LOGINAktifkan auth loginOptionaltrue (tidak disarankan false/tanpa auth)
CAMUNDA_USERNAME / CAMUNDA_PASSWORDKredensial CamundaWajib selama CAMUNDA_LOGIN=true (default)admin-camunda / JelasAlurnya (default lokal — ganti untuk instance yang bisa dijangkau orang lain)

11. GitLab Configuration (fitur tambahan — incident tracking)

VariabelDeskripsiStatusDefault/Contoh
GITLAB_BASE_URL / GITLAB_TOKEN / GITLAB_PROJECT_IDKredensial & target project GitLabOptionalkosong = integrasi nonaktif
GITLAB_INCIDENT_TAGLabel tag incidentOptionalincident

12. Laravel Passport Configuration

VariabelDeskripsiStatusDefault/Contoh
LARAVEL_PASSPORT_ENABLEDAktifkan Laravel Passport authOptionalfalse (fitur nonaktif)
LARAVEL_PASSPORT_PRIVATE_KEY_PATHPath private keyOptionalhanya relevan kalau ENABLED=true

13. Website / Application URL

VariabelDeskripsiStatusDefault/Contoh
WEBSITE_URLBase URL aplikasi (dipakai callback, link email, dll)Wajib (turunan, otomatis)${APP_ORIGIN} → https://alurkerja.local:8100
COMPANY_PROFILE_SERVICE_URLURL internal service company profileWajibhttp://compro-be:3004

14. Service Port Configuration

VariabelDeskripsiStatusDefault/Contoh
AUTH_API_PORT / BPM_API_PORT / TENANT_API_PORT / COMPRO_API_PORT / NOTIFICATION_API_PORT / NOTIFICATION_WS_PORT / INTEGRATION_API_PORT / REPORT_API_PORT / GENERATE_TEST_PORT / PROXY_API_PORT / MIGRATION_API_PORT / SIMULATION_HTTP_PORTPort internal tiap serviceWajibharus konsisten dgn docker-compose.yml & nginx/default.conf.docker
NOTIFICATION_SERVICE_URLURL internal notification serviceWajib (alias, otomatis dari NOTIFICATION_API_PORT)-

15. HTTP / Server Configuration

VariabelDeskripsiStatusDefault/Contoh
HTTP_READ_TIMEOUT / HTTP_WRITE_TIMEOUT / HTTP_SHUTDOWN_TIMEOUTTimeout HTTP serverOptionalsudah ada default aman
HTTP_CORS_ENABLED / HTTP_CORS_ORIGINS / HTTP_CORS_MAX_AGE / HTTP_ALLOW_CREDENTIALSKebijakan CORSOptionaldefault HTTP_CORS_ORIGINS=* longgar — disarankan dipersempit di produksi, tapi tidak fatal
HTTP_ENABLE_PREFORKMode prefork serverOptionalfalse
SERVER_READ_TIMEOUT / SERVER_WRITE_TIMEOUT / SERVER_IDLE_TIMEOUTTimeout tambahanOptionalsudah ada default

16. Report Service — Queue Processor

VariabelDeskripsiStatusDefault/Contoh
ENABLE_QUEUE_PROCESSORAktifkan pemrosesan report asyncOptionaltrue
QUEUE_POLLING_INTERVAL / QUEUE_BATCH_SIZE / QUEUE_WORKER_COUNTTuning worker queueOptionalsudah ada default

Flag rollout asynq (QUEUE_PROCESSOR_CONSUMER dan padanannya di integration/notification) serta env container relay ada di Env Konsolidasi Antrean (asynq).

17. Generate Test Service Specific

VariabelDeskripsiStatusDefault/Contoh
APP_NAMELabel nama serviceOptionalgenerate-test-service
APP_ENVMode environmentOptionallocal — disarankan production saat deploy, tidak fatal kalau lupa
APP_DEBUGMode debugOptionaltrue — disarankan false di produksi (risiko verbosity/keamanan, bukan blocker)
APP_TIMEZONETimezone serviceOptionalAsia/Jakarta
LOCAL_USER_IDFallback user id utk testing lokalOptional4
API_PREFIXPrefix routing internalWajib/api/v1/generate-test — harus konsisten dgn nginx
SWAGGER_HOSTOverride host Swagger UIOptionalkosong = pakai host request

18. Upload Configuration

VariabelDeskripsiStatusDefault/Contoh
UPLOAD_MAX_SIZEBatas ukuran upload, ditulis dengan satuan (10MiB, 10MB, 512KB, 1GB; berbasis 1024)Optional10MiB. bpm-service menolak angka tanpa satuan dan berhenti saat start. Simulation menerima keduanya, jadi satu nilai bersatuan bisa dipakai untuk semua service.
UPLOAD_ALLOWED_TYPESWhitelist MIME typeOptionalimage/pdf umum sudah tercakup
UPLOAD_PATHPath storage lokalOptionalhanya relevan utk fallback non-MinIO

19. Public Domain & Origin

Blok ini ada di paling atas .env karena variabel lain merujuk ke sini lewat ${...} (Compose menginterpolasi .env berurutan). Ubah domain hanya di sini — atau lewat --update-domain (Section J); jangan sunting URL turunannya satu per satu.

VariabelDeskripsiStatusDefault/Contoh
PUBLIC_SCHEME / WS_SCHEMEScheme publik untuk http & websocketWajib.env.example: http/ws; step Setup local HTTPS menaikkannya jadi https/wss
PUBLIC_PORT_SUFFIXSuffix port pada semua originWajib:${AK_PORT_NGINX} → :8100; kosongkan untuk port standar (443)
NGINX_PUBLIC_TARGETPort container yang dilayani nginx sebagai entri publikWajib80 = http polos (TLS diterminasi di depan); HTTPS lokal mkcert menulis 443
NGINX_DOMAINDomain utama — server_name nginxWajibalurkerja.local
MICROSITE_DOMAIN / MINIO_DOMAINHost tersendiri untuk microsite & MinIOWajibmicrosite-alurkerja.local / minio-alurkerja.local
SSO_DOMAINLokasi Keycloak — bukan server_name, isinya host+port+pathWajib${NGINX_DOMAIN}${PUBLIC_PORT_SUFFIX}/sso. Keycloak eksternal: arahkan ke host-nya (mis. sso.company.com) dan jangan jalankan container keycloak
STUDIO_DOMAIN / COMPRO_DOMAIN / SIMULATION_DOMAIN / CAMUNDA_DOMAINSubpath modul di domain utamaWajib (turunan, otomatis)${NGINX_DOMAIN}/studio, /compro, /simulation, /camunda
APP_ORIGIN / SSO_ORIGIN / MICROSITE_ORIGIN / MINIO_ORIGIN / WS_ORIGINOrigin lengkap (scheme + host + port) yang jadi sumber semua URL layanan & frontendWajib (turunan, otomatis)dirakit dari scheme/domain/port di atas — jangan diisi manual

Perhatian: Keycloak menyimpan web-origins & redirect URI di databasenya, jadi setelah mengubah blok ini secara manual jalankan docker compose run --rm tools scripts/update-web-origins.sh (tambah --dry-run untuk mengintip). Lewat --update-domain, sinkronisasi itu sudah jadi salah satu step.

20. MinIO Configuration (Additional)

VariabelDeskripsiStatusDefault/Contoh
MINIO_URLURL MinIO dipakai backend generate presigned URLWajib (alias STORAGE_URL_PREFIX, otomatis)-

21. Telegram Bot Configuration

VariabelDeskripsiStatusDefault/Contoh
TELEGRAM_BOT_TOKENToken bot (dibaca camunda & bot service)Optionalfitur notifikasi tambahan, nonaktif kalau tidak dipakai
TELEGRAM_MODEMode koneksi bot (integration service)Optionalpolling

22. WhatsApp API Configuration

VariabelDeskripsiStatusDefault/Contoh
WHATSAPP_API_KEY / WHATSAPP_API_URL / WHATSAPP_NUMBER_KEY / WHATSAPP_WEBHOOK_URLKredensial & endpoint WhatsApp API (dibaca camunda)Optionalnotifikasi via WhatsApp adalah fitur tambahan

23. Integration Configuration

VariabelDeskripsiStatusDefault/Contoh
INTEGRATION_SYSTEMMode sistem (on-premise vs SaaS)Wajibonpremise
INTEGRATION_EXECUTORFlag internal routingOptionalsaas
INTEGRATION_BASE_URLBase URL API dipanggil balikWajib (turunan, otomatis)${APP_ORIGIN}/api/v1
INTEGRATION_AUTH_TYPEStrategi auth service integrationWajibkeycloak
INTEGRATION_AUTH_URL / INTEGRATION_AUTH_REALMAlias KEYCLOAK_URL/KEYCLOAK_REALMWajib (alias, otomatis)-
INTEGRATION_AUTH_CLIENT_ID / INTEGRATION_AUTH_CLIENT_SECRETClient Keycloak khusus service integrationWajib (installer: hasil setup-keycloak.sh; mode Keycloak eksternal + manual: diisi user)-

24. App Configuration

VariabelDeskripsiStatusDefault/Contoh
APP_INTEGRATION_SYSTEMFlag internal mode sistemWajibONPREMISE
APP_AUTH_SERVICEProvider auth aktifWajibKEYCLOAK
APP_NOTIFICATION_EXTERNALNotifikasi via service eksternalOptionaltrue
APP_NOTIFICATION_URLURL service notifikasiWajib selama APP_NOTIFICATION_EXTERNAL=true (default)http://notification:3005

25. Frontend — Runtime Injection (app-react & studio-react)

Di-inject ke conf.js saat container start via docker-entrypoint.sh.

VariabelDeskripsiStatusDefault/Contoh
VITE_API_BASEURL / VITE_API_TASKLIST_BASEURLBase URL API dipanggil FEWajib (turunan, otomatis)${APP_ORIGIN} → https://alurkerja.local:8100
VITE_AUTH_METHODMetode login FE (keycloak / alurkerja_sso)Wajibkeycloak
VITE_KEYCLOAK_URL / VITE_KEYCLOAK_REALM / VITE_KEYCLOAK_CLIENT_ID / VITE_KEYCLOAK_CLIENT_SECRET / VITE_KEYCLOAK_REDIRECT_URIConfig Keycloak FEWajib selama VITE_AUTH_METHOD=keycloak (default)alias KEYCLOAK_*
VITE_AK_CLIENT_ID / VITE_AK_CLIENT_SECRET / VITE_AK_REDIRECT_URIConfig AlurKerja SSO customOptionalhanya dipakai kalau VITE_AUTH_METHOD=alurkerja_sso (bukan default)
VITE_MINIO_CLOUD / VITE_MINIO_BUCKET / VITE_MINIO_BASE_URLAlias MINIO_* utk FE upload/preview fileWajib (alias, otomatis)-
VITE_MICROSITE_URLLink ke micrositeWajib (turunan, otomatis)${MICROSITE_ORIGIN} → https://microsite-alurkerja.local:8100
VITE_APP_URL / VITE_STUDIO_URL / VITE_COMPRO_URL / VITE_SIMULATION_SERVICE_URLNavigasi antar-modul FE (versi lama)Wajib-
VITE_ALURKERJA_CONTACT_URL / VITE_CONTACT_URLLink kontak/marketingOptionalbukan blocker fungsional
VITE_NEW_APP_URL / VITE_NEW_STUDIO_URL / VITE_NEW_COMPRO_URL / VITE_NEW_SIMULATION_SERVICE_URLNavigasi antar-modul FE (app)Wajib-
VITE_SIMULATION_BE_SERVICE_URLBase URL backend simulasiWajib-
VITE_WS_NOTIFICATION_URLWebSocket notifikasi realtimeWajibtanpa ini notifikasi realtime patah
VITE_WS_COLLABORATION_URLWebSocket kolaborasi realtimeWajibtanpa ini fitur kolaborasi patah
VITE_SENTRY_DSNDSN Sentry sisi FEOptionalsama alasan grup #5
VITE_QUERY_DEBUGDebug query FEOptionalfalse
VITE_PRODUCTIONFlag mode build FEOptionaltrue
VITE_URL_GET_MANAGER / VITE_URL_GET_MANAGER_USERNAME / VITE_URL_GET_MANAGER_PASSWORDIntegrasi n8n manager (app-react only)Optionalfitur spesifik, kosong = nonaktif
VITE_BASIC_AUTH_ALURKERJA_USERNAME / VITE_BASIC_AUTH_ALURKERJA_PASSWORDBasic auth tambahan FEOptionalkosong = basic auth nonaktif
VITE_AZURE_CLIENT_ID / VITE_AZURE_TENANT_ID / VITE_AZURE_REDIRECT_URI / VITE_AZURE_AUTHORITYSSO Azure AD (studio-react only)Optionalkosong di .env = nonaktif
VITE_FEATURE_ERROR_REPORTFlag tombol "Send Error to IT Support" pada toast kegagalan requestOptionalfalse — dengan flag mati, tombolnya tidak muncul sama sekali
VITE_ERROR_REPORT_BASEURLBase URL service helpdesk (helpdesk-react) yang menerima laporan errorWajib selama VITE_FEATURE_ERROR_REPORT=true-
VITE_ERROR_REPORT_ACCESS_KEYKey akses ke endpoint error report; harus sama dengan ERROR_REPORT_ACCESS_KEY di helpdeskWajib selama VITE_FEATURE_ERROR_REPORT=true-

26. Microsite Configuration (Next.js Application)

VariabelDeskripsiStatusDefault/Contoh
MICROSITE_NODE_ENVMode Node.jsOptionalproduction
MICROSITE_APP_DEBUGMode debugOptionalfalse
MICROSITE_REDIS_ENABLEDPakai Redis khusus micrositeOptionalfalse (microsite jalan tanpa ini)
MICROSITE_API_BASE_URLBase URL API utamaWajib (turunan, otomatis)${APP_ORIGIN}/api/v1
KEYCLOAK_HOSTAlias KEYCLOAK_URLWajib (alias, otomatis)-
KEYCLOAK_ADMIN_CLIENT / KEYCLOAK_ADMIN_SECREETService account Keycloak dipakai integration-service memanggil Admin REST API Keycloak (bukan login user biasa)Wajib (default: jatuh ke KEYCLOAK_CLIENT/KEYCLOAK_CLIENT_SECRET kalau kosong)-

Perhatikan ejaannya: KEYCLOAK_ADMIN_SECREET, bukan SECRET — begitu integration-service membacanya (config/env.go); mengisi KEYCLOAK_ADMIN_SECRET (ejaan benar) tidak akan terbaca. Kalau kedua variabel ini kosong, integration-service otomatis memakai KEYCLOAK_CLIENT/KEYCLOAK_CLIENT_SECRET sebagai gantinya — cukup untuk instalasi default karena client itu dibuat confidential oleh setup-keycloak.sh. Isi keduanya secara eksplisit hanya kalau ingin service account terpisah.

Service account ini dipakai untuk dua hal, dan masing-masing butuh role Keycloak sendiri (Clients → client ini → Service accounts roles → Assign role → filter by clients → realm-management):

  • Membuat/reset password user Keycloak saat tenant men-generate auth token integrasi (mis. dipakai addon n8n) → role manage-users.
  • Impersonasi user untuk MCP tool calls (lihat Impersonate User) → role impersonation.

Kalau role ini belum ter-assign: pembuatan auth token integrasi gagal dengan 500 dari Keycloak, atau MCP tool call yang bertindak atas nama user tertentu ditolak. setup-keycloak.sh belum tentu meng-assign kedua role ini secara otomatis — cek langsung di Keycloak Admin Console kalau salah satu fitur di atas tidak jalan.

27. Frontend — Build-time Only (compro-react & simulation-react)

Bukan variabel di .env root. Image compro-react dan simulation-react tidak punya docker-entrypoint.sh untuk runtime injection, jadi VITE_* harus diisi manual di file terpisah sebelum image di-build:

  • builds/compro-react/.env → VITE_API_BASEURL, VITE_API_TASKLIST_BASEURL, VITE_AUTH_METHOD, VITE_KEYCLOAK_*, VITE_SENTRY_DSN — Wajib diisi sebelum build, atau FE ini salah konfigurasi permanen sampai di-build ulang.
  • builds/simulation-react/.env → VITE_KEYCLOAK_*, VITE_API_BASE_URL, VITE_SENTRY_DSN (opsional) — sama alasan.

28. Feature Flag

VariabelDeskripsiStatusDefault/Contoh
FEATURE_FLAG_NORAMengaktifkan fitur Membuat SOP dengan NORAOptionalaktif secara bawaan; isi false untuk mematikan
FEATURE_FLAG_WIZARDMengaktifkan fitur Create SOP from WizardOptionalaktif secara bawaan; isi false untuk mematikan

Kedua flag hanya nonaktif apabila nilainya diisi persis false (huruf kecil). Nilai lain, termasuk dikosongkan atau tidak didefinisikan sama sekali, dianggap aktif. Mematikan FEATURE_FLAG_NORA hanya menonaktifkan pembuatan SOP dengan NORA; fitur lain pada BPMN Editor tidak terpengaruh.

29. Versi Image (AK_VERSION)

VariabelDeskripsiStatusDefault/Contoh
AK_VERSIONVersi image AlurKerja yang ditarik dari Harbor untuk semua service, misalnya 2026.09.4.1. Image tidak lagi memakai tag latest.WajibNilai di .env.example adalah rilis terakhir yang tagnya tersedia di semua image.
AK_VERSION_<SERVICE>Versi khusus satu service, misalnya AK_VERSION_BPM. Kalau kosong, service itu memakai AK_VERSION. Nama service: APP, CAMUNDA, AUTH, BPM, COMPRO_BE, INTEGRATION, RELAY, NOTIFICATION, REPORT, SIMULATION_BE, TENANT, MIGRATION, PROXY, GENERATE_TEST.Optionalkosong

Kalau AK_VERSION kosong, docker compose berhenti dengan galat required variable AK_VERSION is missing a value. Instalasi baru mendapat nilainya dari .env.example. Instalasi lama yang .env-nya dibuat sebelum variabel ini ada wajib menambahkan AK_VERSION ke .env sebelum menjalankan docker compose berikutnya. Untuk naik versi, ubah nilai AK_VERSION, lalu jalankan docker compose pull dan docker compose up -d.

I. Lifecycle Service: Start, Stop, Purge Data, Uninstall

alurkerja-cli hanya mengurus instalasi (build-alurkerja) — belum ada command lifecycle bawaan, jadi operasi setelah instalasi dijalankan langsung dengan docker compose.

Nama project compose diambil dari field name: di docker-compose.yml — bawaan repo: alurkerja (kalau field tidak ada, compose memakai nama folder download dalam huruf kecil). Dengan flag -p alurkerja, command ps, logs, start, stop, restart, dan down bisa dijalankan dari folder mana pun; hanya up yang wajib dari folder download, karena container harus dirakit ulang dari docker-compose.yml + .env.

Empat tingkat operasi — makin ke bawah makin banyak yang hilang:

OperasiCommand intiContainerData (volume)Folder & CLI
Startdocker compose -p alurkerja startjalanutuhutuh
Stopdocker compose -p alurkerja stopberhenti, tetap adautuhutuh
Downdocker compose -p alurkerja downdihapusutuhutuh
Purge datadocker compose -p alurkerja down -vdihapushilang permanenutuh
Uninstalllihat I.4 & I.5dihapushilangdihapus

I.1. Start service

Aksi

Setelah stop — container masih ada, cukup dinyalakan lagi (dari folder mana pun):

docker compose -p alurkerja start

Setelah down atau untuk instalasi yang baru saja di-up pertama kali — container harus dibuat ulang, jadi jalankan dari folder download:

docker compose up -d

Satu service saja: docker compose -p alurkerja start camunda.

Expected output

docker compose -p alurkerja ps

Semua service berstatus running. Boot penuh butuh ±1–2 menit: depends_on hanya mengatur urutan start, bukan kesiapan, jadi beberapa backend bisa restart sekali-dua kali selama postgres masih warm-up dan stabil sendiri karena restart: unless-stopped. Setelah itu aplikasi kembali dapat diakses di URL Step 9.

Perhatian: semua service memakai restart: unless-stopped — stack ikut nyala otomatis setiap Docker Desktop start. Container yang dihentikan manual (stop/down) tidak ikut nyala, jadi keputusan mematikan stack bertahan melewati reboot.

I.2. Stop service

Aksi

Ada dua tingkat, pilih sesuai kebutuhan.

a. stop — jeda harian. Container dihentikan tapi tetap ada; port host 8100–8105 dilepas; data dan konfigurasi utuh. Hidupkan lagi dengan start (I.1).

docker compose -p alurkerja stop

b. down — bongkar container. Container dan network alurkerja-net dihapus, volume tidak disentuh — semua data tetap aman. Dipakai kalau .env atau docker-compose.yml berubah dan container perlu dirakit ulang.

docker compose -p alurkerja down --remove-orphans

--remove-orphans ikut membersihkan container sisa service yang sudah tidak ada lagi di docker-compose.yml versi sekarang.

Expected output

docker compose -p alurkerja ps -a

Setelah stop: semua container berstatus exited. Setelah down: daftar kosong.

Perhatian: Mailpit tidak punya volume — email uji hilang setiap container dibuat ulang lewat down. stop tidak menghapusnya.

I.3. Purge data

Aksi

Stack ini membuat tiga volume (keycloak_data dideklarasikan di docker-compose.yml tapi tidak dipakai service mana pun, jadi tidak pernah terbentuk — Keycloak menyimpan realm-nya di database keycloak_db di dalam postgres):

VolumeIsiEfek kalau dihapus
alurkerja_postgres_datadatabase alurkerja, schema camunda, dan keycloak_dbseluruh workflow, data user, dan realm Keycloak hilang
alurkerja_minio_databucket file uploadsemua file & attachment hilang
alurkerja_redis_datacache Redis (appendonly)aman — terbentuk ulang otomatis

down -v menghapus semua data secara permanen — database, file storage MinIO, dan realm Keycloak. Kalau berencana instal ulang dengan data lama, amankan dulu .env — khususnya 4 application secrets (lihat Section H) — karena database bekas hanya bisa dipakai lagi dengan secret yang sama.

a. Purge total — kosongkan semua data, instalasi tetap terpasang:

docker compose -p alurkerja down -v --remove-orphans

Lalu isi ulang schema dan realm dengan menjalankan pipeline lagi dari folder download:

alurkerja build-alurkerja

Step Init database, Load public & camunda schema, dan Setup Keycloak berjalan lagi; step Generate secrets hanya mengisi nilai yang kosong/masih placeholder, jadi 4 application secrets di .env tidak di-rotate dan instalasi baru memakai kunci yang sama.

b. Purge selektif — buang satu jenis data saja, mis. file storage:

docker compose -p alurkerja down          # container harus dihapus dulu, `stop` saja tidak cukup:
                                          # volume masih dipegang container yang exited
docker volume rm alurkerja_minio_data
docker compose up -d                      # dari folder download; minio-init membuat ulang bucket

Expected output

docker volume ls --filter name=alurkerja_

Volume yang dibuang tidak lagi muncul (setelah purge total: daftar kosong).

I.4. Uninstall service AlurKerja

Urutannya: matikan stack dulu, baru bersihkan jejak di luar Docker, terakhir hapus folder. Jalankan semua langkah agar tidak ada residu.

1. Stop stack & hapus volume

docker compose -p alurkerja down -v --remove-orphans

Expected: docker compose ls --all tidak lagi menampilkan project alurkerja, docker volume ls --filter name=alurkerja_ kosong, dan network alurkerja-net hilang dari docker network ls.

2. Hapus entri hosts yang ditulis CLI

Selama instalasi, CLI menambahkan satu baris ber-komentar # alurkerja-cli ke hosts file supaya domain lokal resolve ke mesin ini — mis. 127.0.0.1 alurkerja.local microsite-alurkerja.local minio-alurkerja.local # alurkerja-cli. Butuh akses admin/root:

Jalankan PowerShell as Administrator:

$hosts = "$env:SystemRoot\System32\drivers\etc\hosts"
Set-Content $hosts -Value ((Get-Content $hosts) -notmatch 'alurkerja-cli')
sudo sed -i.bak '/# alurkerja-cli/d' /etc/hosts

Expected: Select-String alurkerja-cli $hosts (PowerShell) atau grep alurkerja-cli /etc/hosts tidak menghasilkan baris apa pun. Baris domain yang ditulis sendiri (tanpa komentar # alurkerja-cli) tidak ikut terhapus — hapus manual kalau memang tidak dipakai lagi.

3. Lepas root CA mkcert — hanya kalau instalasi memakai HTTPS lokal

Step Setup local HTTPS menjalankan mkcert -install, yang menaruh root CA lokal di trust store OS. Lepas kepercayaan itu sebelum folder ~/.alurkerja dihapus (binary mkcert ada di dalamnya):

& "$env:USERPROFILE\.alurkerja\bin\mkcert.exe" -uninstall
~/.alurkerja/bin/mkcert -uninstall

Perhatian: ini melepas root CA mkcert untuk semua project di mesin ini — lewati kalau ada project lain yang mengandalkannya.

4. Lepas reservasi port — Windows saja

CLI mereservasi 10 port mulai dari AK_PORT_NGINX (default 8100–8109) lewat netsh supaya Hyper-V/WSL tidak mencaploknya setelah reboot. Di terminal admin:

netsh int ipv4 delete excludedportrange protocol=tcp startport=8100 numberofports=10

Expected: netsh int ipv4 show excludedportrange protocol=tcp tidak lagi menampilkan baris 8100–8109. Kalau AK_PORT_NGINX di .env bukan 8100, sesuaikan startport (cek .env sebelum foldernya dihapus di langkah 5).

5. Hapus folder download

Hapus folder yang dipilih di Step 6 (berisi docker-compose.yml, .env, config/, sertifikat nginx/certs/):

Remove-Item -Recurse -Force D:\path\ke\folder-download
rm -rf /path/ke/folder-download

Perhatian: .env (termasuk application secrets) ikut terhapus bersama folder ini dan tidak bisa dipulihkan.

6. Logout Harbor

docker logout harbor.merapi.javan.id

7. Hapus image — opsional, mengosongkan ±5 GB

Image tetap tersimpan setelah down. Hapus image AlurKerja dari Harbor plus alurkerja-tools (image lokal hasil build service tools) — command sama untuk PowerShell maupun bash:

docker rmi $(docker images -q "harbor.merapi.javan.id/alurkerja-v2/*")
docker rmi alurkerja-tools

Image publik pendukung (nginx, keycloak, pgvector, redis, minio, mailpit) bisa dibersihkan dengan docker image prune -a — perhatian: perintah ini menghapus semua image yang tidak dipakai container mana pun, termasuk milik project lain.

I.5. Uninstall AlurKerja CLI

Aksi

Seluruh jejak CLI ada di satu folder: ~/.alurkerja (Windows: %USERPROFILE%\.alurkerja) — binary bin/alurkerja, binary bin/mkcert, config & profile koneksi, token login, serta deployment/. Jalankan mkcert -uninstall (I.4 langkah 3) sebelum folder ini dihapus.

Remove-Item -Recurse -Force "$env:USERPROFILE\.alurkerja"

# Lepas dari user PATH lewat registry — entri %VAR% lain tetap utuh
$dir      = Join-Path $env:USERPROFILE '.alurkerja\bin'
$key      = [Microsoft.Win32.Registry]::CurrentUser.OpenSubKey('Environment', $true)
$noExpand = [Microsoft.Win32.RegistryValueOptions]::DoNotExpandEnvironmentNames
$raw      = $key.GetValue('Path', '', $noExpand)
$kept     = "$raw" -split ';' -ne '' -ne $dir -ne "$dir\"
$key.SetValue('Path', ($kept -join ';'), [Microsoft.Win32.RegistryValueKind]::ExpandString)
$key.Close()
rm -rf ~/.alurkerja

Installer tidak pernah menyunting shell profile — kalau dulu export PATH="$HOME/.alurkerja/bin:$PATH" ditambahkan sendiri ke ~/.zshrc / ~/.bashrc, hapus barisnya.

Expected output

Di terminal baru (PATH lama masih hidup di terminal yang sedang terbuka), alurkerja --version menghasilkan command not found.

Perhatian: installer versi lama memasang binary di lokasi berbeda — %LOCALAPPDATA%\alurkerja (Windows) atau ~/.local/bin / ~/bin (macOS/Linux). Kalau CLI pernah dipasang sebelum pindah ke ~/.alurkerja/bin, cek lokasi itu dan hapus file alurkerja yang tersisa.

I.6. Verifikasi akhir

CekCommandExpected
Project composedocker compose ls --alltanpa baris alurkerja
Volumedocker volume ls --filter name=alurkerja_kosong
Networkdocker network ls --filter name=alurkerja-netkosong
Imagedocker images "harbor.merapi.javan.id/alurkerja-v2/*"kosong
Folder downloadls <folder>tidak ada
Hosts filegrep alurkerja-cli /etc/hosts / Select-String alurkerja-cli $env:SystemRoot\System32\drivers\etc\hoststanpa hasil
Reservasi port (Windows)netsh int ipv4 show excludedportrange protocol=tcptanpa 8100–8109
CLIalurkerja --version di terminal barucommand not found

J. Skema Domain dan Ganti Domain

Ada dua skenario pemakaian:

KS — tanpa domain (default)KD — dengan domain sendiri
Untukmesin lokal, demo, developmentserver yang punya domain & DNS
Domain utamaalurkerja.local (bawaan .env.example)mis. alurkerja.dev
Port publik:8100 (AK_PORT_NGINX)tanpa port — standar 443, kecuali di-override --port
Schemehttps, sertifikat mkcert lokalhttps, TLS diterminasi di depan nginx
Resolusi namahosts file, didaftarkan CLI otomatisDNS — urusan operator
Caraalurkerja build-alurkerjaalurkerja build-alurkerja --update-domain --domain alurkerja.dev

Sumber kebenarannya satu: blok domain di .env (NGINX_DOMAIN, MICROSITE_DOMAIN, MINIO_DOMAIN, PUBLIC_SCHEME, PUBLIC_PORT_SUFFIX). Semua *_ORIGIN dan URL frontend diturunkan dari situ lewat interpolasi ${...}, jadi tidak ada URL yang perlu diedit satu per satu.

J.1. Peta URL kedua skenario

ModulKS (domain lokal)KD (domain sendiri)
Apphttps://alurkerja.local:8100https://alurkerja.dev
Studiohttps://alurkerja.local:8100/studiohttps://alurkerja.dev/studio
Comprohttps://alurkerja.local:8100/comprohttps://alurkerja.dev/compro
Simulationhttps://alurkerja.local:8100/simulationhttps://alurkerja.dev/simulation
BE (API)https://alurkerja.local:8100/api/v1https://alurkerja.dev/api/v1
SSO (Keycloak)https://alurkerja.local:8100/ssohttps://alurkerja.dev/sso
Micrositehttps://microsite-alurkerja.local:8100https://microsite.alurkerja.dev
MinIOhttps://minio-alurkerja.local:8100https://minio.alurkerja.dev

SSO mengikuti domain utama dengan sendirinya (SSO_DOMAIN=${NGINX_DOMAIN}${PUBLIC_PORT_SUFFIX}/sso). Kalau SSO-nya justru harus di host terpisah — mis. Keycloak eksternal di sso.alurkerja.dev — pakai --sso-domain sso.alurkerja.dev: CLI menguji koneksi ke port 443-nya lebih dulu, dan realm + client di sana harus sudah ada.

J.2. Ganti domain pada instalasi existing

Aksi

Jalankan dari folder download (atau tambahkan --dir <folder>):

alurkerja build-alurkerja --update-domain --domain alurkerja.dev

Tanpa flag pun bisa: jalankan alurkerja build-alurkerja di folder instalasi, lalu pilih Update the public domain (app, studio, sso) di menu instalasi existing. Nilai yang tidak diisi diambil dari .env saat ini — enter kosong = biarkan apa adanya.

FlagDefaultKeterangan
--domainnilai NGINX_DOMAIN sekarangBare host — tanpa scheme, port, path, atau spasi (divalidasi).
--portnone (443)Isi angka kalau publiknya bukan port standar.
--microsite-domainmicrosite.<domain>—
--minio-domainminio.<domain>Diabaikan kalau storage eksternal — MINIO_DOMAIN tidak disentuh.
--sso-domaintidak diubahHost SSO terpisah; dites koneksi :443 sebelum ditulis.

Setelah domain diisi, CLI menanyakan sertifikat HTTPS domain itu:

HTTPS certificate for this domain:
> Public (Cloudflare / Let's Encrypt / purchased) -> nothing to install (default)
  Company internal (folder from IT: .cer + .key + root CA)

Public cocok untuk sertifikat dari CA publik (Cloudflare, Let's Encrypt, sertifikat beli) dan tidak memasang apa pun. Company internal untuk sertifikat yang diterbitkan CA privat perusahaan — lihat J.3. Tanpa terminal (pipeline/agen) menu ini tidak muncul dan pilihannya Public. Kalau sudah ada sertifikat terpasang selain mkcert lokal, menunya berganti jadi Keep / Replace / Remove — lihat J.4.

Dengan Public, jalur ini 5 step, di luar pipeline install biasa (dengan Company internal jadi 7 step, lihat J.3):

StepKeterangan
Update .env (domain & origins)Tulis domain baru + PUBLIC_SCHEME=https, WS_SCHEME=wss, PUBLIC_PORT_SUFFIX. TLS lokal mkcert sekaligus dicabut: NGINX_PUBLIC_TARGET kembali 80, nginx/tls/tls.conf dan docker-compose.override.yml milik mkcert di-rename jadi .disabled. Milik sertifikat perusahaan atau yang ditulis tangan dibiarkan.
Remove extra_hosts dari docker-compose.ymlTemplate memetakan domain ke host-gateway — benar untuk instalasi lokal, salah untuk domain nyata (trafik publik dibalikkan ke docker host, bukan lewat DNS).
Restart stackdocker compose up -d --force-recreate dengan .env baru. Volume tidak disentuh — tidak ada data yang hilang.
Sync Keycloak web-originsKeycloak menyimpan redirect URI & web-origins di databasenya, bukan di .env, jadi harus di-push terpisah lewat scripts/update-web-origins.sh di container tools. Gagal → warning + perintah manualnya.
SummaryDaftar URL baru (App, Studio, SSO, Microsite, MinIO) + pengingat DNS dan TLS.

Expected output

Step Summary menampilkan kelima URL di domain baru, dan Domain updated in <durasi>. tampil di akhir.

Setelah ganti domain, nginx kembali melayani HTTP polos di port AK_PORT_NGINX — terminasi TLS jadi tugas load balancer / reverse proxy di depannya. Pastikan juga domain utama beserta turunan microsite & MinIO benar-benar resolve ke mesin ini; CLI tidak mengurus DNS.

Perhatian: entri hosts dari instalasi lokal sebelumnya tidak ikut dihapus. Kalau domain lokal sudah tidak dipakai, bersihkan sesuai Section I.4 langkah 2.

J.3. Sertifikat internal perusahaan (CA privat)

Bagian ini untuk server yang sertifikat domainnya diterbitkan CA internal perusahaan (mis. Active Directory Certificate Services), bukan CA publik. Kalau server memanggil domainnya sendiri lewat port 443 host, dua hal menggagalkan service yang mengambil JWKS Keycloak lewat https://<domain>/sso:

  • Container tidak memercayai CA internal itu, karena trust store host tidak terbawa ke container.
  • Panggilan keluar ke 443 host lalu masuk lagi ke stack (hairpin), dan di sebagian server panggilan ini macet di TLS.

Gejalanya: Keycloak menampilkan Authentication successful, tapi halaman /callback loading terus, dan log auth berisi jwks unavailable ... no key for kid.

Aksi

Siapkan satu folder dari tim IT berisi sertifikat domain, private key, dan root CA (intermediate kalau ada). Nama berkas bebas, format PEM atau DER .cer. Lalu:

alurkerja build-alurkerja --update-domain --domain los.example.co.id

Pilih Company internal dan isi path folder:

Certificate folder: /home/user/SSL_los
✔ los.key · los_example_co_id.cer (los.example.co.id) · root_CA.cer

CLI memilah isi folder dari isi berkasnya, bukan dari nama:

  • root CA = sertifikat self-signed;
  • sertifikat domain = sertifikat yang berlaku untuk domain yang diketik (wildcard ikut);
  • intermediate = sertifikat CA lainnya;
  • private key = blok PRIVATE KEY.

Kalau key atau root CA tidak ditemukan, CLI meminta path berkasnya. Kalau ada lebih dari satu, CLI menampilkan menu pilihan.

Sebelum menulis apa pun, CLI memastikan tiga hal: sertifikat berlaku untuk domain itu, terverifikasi ke root CA, dan cocok dengan private key-nya.

KondisiYang terjadi
Folder untuk domain lain (mis. folder MinIO)Ditolak: no certificate in SSL_los_minio covers los.example.co.id (found: los-minio.example.co.id) - wrong folder?
Key ber-passphrasePassphrase ditanyakan (tersembunyi, maksimal 3 kali). Key disimpan tanpa passphrase dengan permission 600, karena nginx tidak bisa menanyakan passphrase saat start.
Berkas .pfx / .p12Ditolak dengan petunjuk memecahnya pakai openssl pkcs12.

Step tambahan (urutan lengkap: Update .env → Remove extra_hosts → Install company certificate → Restart stack → Sync Keycloak web-origins → Verify JWKS → Summary):

StepKeterangan
Install company certificateMenulis nginx/certs/company.pem (sertifikat + intermediate) dan company-key.pem, nginx/tls/tls.conf (listen 443 ssl), nginx/certs/ca-bundle.pem (CA sistem + root perusahaan), serta docker-compose.override.yml. Override itu membuat service backend memercayai bundle tersebut dan memberi service nginx alias ${NGINX_DOMAIN} di jaringan compose, tanpa extra_hosts: host-gateway. tls.conf atau override yang ditulis tangan disimpan dulu sebagai .backup-*.
Verify JWKS from inside the stackcurl dari container tools ke https://<domain>/sso/realms/<realm>/protocol/openid-connect/certs. Respons 502/503 (Keycloak belum siap) dicoba ulang sampai 3 menit. Hasil selain 200 hanya memunculkan warning beserta perintah cek manualnya.

Karena alias itu, panggilan container ke https://<domain> tetap di dalam stack, sementara issuer token tetap URL publik. TLS untuk browser tetap dipegang komponen di depan stack (nginx host, load balancer): port publik nginx stack tetap HTTP polos, dan 443 di dalam container hanya melayani panggilan antar-service.

Expected output

Step Verify JWKS menampilkan JWKS reachable from inside the stack: https://<domain>/sso/realms/<realm>/protocol/openid-connect/certs. Summary ditutup dengan HTTPS: terminate TLS in front of nginx (port 8100); the company certificate is for in-stack calls only.

Perhatian: --update-domain berikutnya tidak mematikan sertifikat ini tanpa bertanya — lihat J.4. Firewall host (mis. firewalld yang belum membuka 80/443) dan konfigurasi nginx host tetap urusan operator.

J.4. Sertifikat yang sudah terpasang: Keep, Replace, Remove

Kalau nginx stack sudah melayani sertifikat selain mkcert lokal — sertifikat perusahaan dari J.3, atau nginx/tls/tls.conf yang ditulis tangan — --update-domain tidak menampilkan menu Public / Company internal, melainkan:

Installed HTTPS certificate: company certificate for los.example.co.id, expires <tanggal>
> Keep it (default)
  Replace it (folder from IT: .cer + .key + root CA)
  Remove it (public certificate in front of the stack)

Untuk tls.conf tulisan tangan, judulnya Installed HTTPS certificate: nginx/tls/tls.conf written by hand.

PilihanYang terjadi
Keep (bawaan)Sertifikat tidak disentuh. Tanpa terminal (pipeline/agen) pilihannya ini. Kalau domain baru tidak tercakup sertifikat perusahaan yang terpasang, CLI memberi warning. Diikuti step Verify JWKS.
ReplaceMeminta folder sertifikat baru, lalu berjalan seperti Company internal di J.3 (Install company certificate + Verify JWKS).
RemoveStep Remove installed certificate: tls.conf dan docker-compose.override.yml di-rename jadi .disabled, company.pem/company-key.pem dihapus. Berkas sertifikat yang dirujuk tls.conf tulisan tangan tidak dihapus. nginx stack kembali HTTP polos; pakai ini kalau domain beralih ke sertifikat publik.

HTTPS lokal mkcert tidak ditanyakan: tetap dimatikan otomatis seperti di J.2.

K. Migrasi Storage MinIO ke RustFS

Sejak September 2026 MinIO tidak lagi melayani pull anonim untuk image community-nya, dan image AIStor penggantinya butuh lisensi per instalasi. Storage bawaan karena itu pindah ke RustFS. Service-nya tetap bernama minio, jadi .env tidak berubah. Yang berubah: data disimpan di volume baru alurkerja_rustfs_data, dan console pindah ke /rustfs/console/.

Data MinIO lama di volume alurkerja_minio_data tersimpan dalam format internal MinIO dan tidak bisa dibaca langsung oleh RustFS. Isinya harus disalin lewat server MinIO lama. Bagian ini hanya berlaku untuk storage bawaan; instalasi dengan storage eksternal (S3/MinIO sendiri) tidak terpengaruh.

K.1. Otomatis lewat CLI

Aksi

Dari folder instalasi, jalankan ulang build (atau --update-image):

alurkerja build-alurkerja

Step Migrate MinIO data to RustFS berjalan sebelum container dibuat ulang:

  1. Memilih image yang bisa membuka volume lama, berurutan: image container MinIO yang sedang berjalan → AIStor, kalau config/minio/minio.license ada → quay.io/minio/minio / minio/minio di cache lokal. Lisensi didahulukan karena volume yang dibuat AIStor tidak bisa dibuka image community, sedangkan AIStor berlisensi bisa membuka keduanya. Kalau tidak ada satu pun, step berhenti sebelum stack disentuh.
  2. Membuat ulang service minio sebagai RustFS (container MinIO lama otomatis berhenti) dan menjalankan minio-init untuk membuat bucket.
  3. Menjalankan MinIO lama sementara sebagai alurkerja-minio-old di atas volume lama, menunggunya siap (hingga 2 menit, progres dicetak tiap 10 detik), lalu mc mirror --preserve menyalin bucket (Content-Type dan metadata ikut). Selama menunggu, log server lama dipantau; lisensi yang ditolak atau volume AIStor yang tidak terbaca menghentikan step dalam hitungan detik (lihat K.2).
  4. mc diff memastikan setiap objek lama ada di RustFS dengan ukuran yang sama. Objek yang hanya ada di RustFS (upload setelah percobaan sebelumnya) dibolehkan.
  5. Menghapus container alurkerja-minio-old dan menulis berkas .rustfs-migrated di folder instalasi, sehingga step ini tidak muncul lagi di run berikutnya. Kalau gagal di tengah, cukup jalankan ulang.

Expected output

Bucket alurkerja copied into RustFS and verified., disusul perintah untuk menghapus volume lama.

Perhatian: volume alurkerja_minio_data tidak pernah dihapus oleh CLI. Setelah upload, download, dan thumbnail di aplikasi dicek, hapus manual dengan docker volume rm alurkerja_minio_data.

K.2. Kalau migrasi gagal

  • no MinIO server image can open the old volume — container MinIO lama sudah terhapus dan tidak ada image MinIO di cache. Pilihannya: taruh lisensi AIStor di config/minio/minio.license lalu jalankan ulang (CLI memakai image AIStor), atau, kalau data lama memang tidak dibutuhkan, buat berkas kosong .rustfs-migrated di folder instalasi supaya RustFS mulai kosong. Volume lama tetap ada.
  • the old volume was created by MinIO AIStor, which the community MinIO image cannot open — instalasi lama dipasang di era AIStor, tetapi config/minio/minio.license tidak ada, jadi CLI mencoba image community yang tidak bisa membaca volume itu. Taruh lisensi AIStor di path tersebut lalu jalankan ulang, atau buat .rustfs-migrated kalau data lama tidak dibutuhkan.
  • the old MinIO server rejects the AIStor license — lisensi di config/minio/minio.license sudah kedaluwarsa atau milik deployment lain; AIStor berjalan tetapi menolak semua operasi S3. Ganti dengan lisensi yang valid lalu jalankan ulang, atau buat .rustfs-migrated.
  • the old MinIO server did not answer within 2 minutes — pesan error memuat image yang dipakai, status container, dan 10 baris log terakhir server lama; penyebabnya terbaca di sana. Volume lama tidak tersentuh, jadi aman dijalankan ulang setelah penyebabnya dibereskan.
  • RustFS does not match the old bucket after the copy atau penyalinan terputus — jalankan ulang; mc mirror hanya menyalin objek yang belum ada.

On this page

A. Ringkasan & Definition of DoneB. Prasyarat1. Verifikasi Docker Desktop berjalan2. Verifikasi Git terpasang — opsional3. Verifikasi akun Harbor4. Verifikasi free storage minimal 8 GBC. Instalasi & Jalankan CLI5.1. Instalasi cepat (otomatis)5.2. Download manual & jalankan binaryD. Eksekusi Pipeline build-alurkerja6. Isi input yang diminta7. Pantau pipeline sampai selesaiE. Verifikasi & Akses Pertama Kali8. Validasi semua container running9. Akses aplikasiF. TroubleshootingG. Logbook InstalasiH. Variabel Environment1. Database Configuration (PostgreSQL)Prasyarat Schema Database (public.sql) — Extension pgvector2. Keycloak Configuration3. MinIO / Storage Configuration4. Redis / Cache Configuration5. Sentry Configuration6. OpenAI Configuration7. Email Configuration (Notification & Tenant Management)8. JWT Configuration9. Encryption Configuration (Tenant Settings)10. Camunda Configuration (Migration Service)11. GitLab Configuration (fitur tambahan — incident tracking)12. Laravel Passport Configuration13. Website / Application URL14. Service Port Configuration15. HTTP / Server Configuration16. Report Service — Queue Processor17. Generate Test Service Specific18. Upload Configuration19. Public Domain & Origin20. MinIO Configuration (Additional)21. Telegram Bot Configuration22. WhatsApp API Configuration23. Integration Configuration24. App Configuration25. Frontend — Runtime Injection (app-react & studio-react)26. Microsite Configuration (Next.js Application)27. Frontend — Build-time Only (compro-react & simulation-react)28. Feature Flag29. Versi Image (AK_VERSION)I. Lifecycle Service: Start, Stop, Purge Data, UninstallI.1. Start serviceI.2. Stop serviceI.3. Purge dataI.4. Uninstall service AlurKerjaI.5. Uninstall AlurKerja CLII.6. Verifikasi akhirJ. Skema Domain dan Ganti DomainJ.1. Peta URL kedua skenarioJ.2. Ganti domain pada instalasi existingJ.3. Sertifikat internal perusahaan (CA privat)J.4. Sertifikat yang sudah terpasang: Keep, Replace, RemoveK. Migrasi Storage MinIO ke RustFSK.1. Otomatis lewat CLIK.2. Kalau migrasi gagal