On Premise Kubernetes
Runbook instalasi AlurKerja di cluster Kubernetes on-premise. Berurutan 1..47, satu nomor satu aksi, setiap langkah memiliki validasi observable.
A. Ringkasan & Definition of Done
Panduan ini membantu tim ops menginstal AlurKerja di cluster Kubernetes on-premise milik pelanggan. Runbook ini sudah teruji pada deployment Linknet (PoC LPP) dan dirancang ulang sebagai dokumen one-shot read: satu kali baca dan langsung dapat dieksekusi tanpa perlu sumber tambahan.
Definition of Done — instalasi dianggap selesai bila:
- Semua deployment AlurKerja (17 workload) dalam state
Availabledan pod-nyaReady. - Endpoint frontend (App, Studio, Compro, Simulation), Camunda web, dan API gateway merespons dengan HTTP 200 / 30x sesuai konvensi.
- Pengguna admin pertama berhasil login dan membuat tenant.
- Logbook instalasi terisi lengkap dan ditandatangani implementor + reviewer.
Estimasi waktu eksekusi: 4–6 jam untuk tim ops yang akrab dengan kubectl (di luar waktu siapkan data prasyarat).
Sebelum mulai, download template logbook: alurkerja-install-k8s-checklist.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–7 memastikan environment siap. Hentikan dan perbaiki bila ada langkah yang gagal — jangan lanjut sebelum prasyarat terpenuhi.
1. Verifikasi kubectl terpasang
Aksi
kubectl version --client --output=yamlExpected output
Menampilkan clientVersion dengan gitVersion: v1.27.x atau lebih baru.
Jika gagal: jika
kubectltidak terpasang, install dulu sesuai distro (brew install kubectl,apt install kubectl, dll).
2. Verifikasi context cluster aktif
Aksi
kubectl config current-contextExpected output
Nama context yang menunjuk ke cluster target pelanggan (bukan docker-desktop atau cluster development pribadi).
nama context mengandung identifier cluster pelanggan (contoh linknet-prod, acme-staging).
Jika gagal: jika salah, pindah context dengan
kubectl config use-context <NAMA_CONTEXT>.
3. Verifikasi permission namespace
Aksi
kubectl auth can-i create namespace
kubectl auth can-i create deployment --namespace <CALON_NAMESPACE>
kubectl auth can-i create secret --namespace <CALON_NAMESPACE>Expected output
Tiga baris yes.
Jika gagal: jika ada
no, minta cluster-admin untuk grant role (cluster-adminatau RBAC custom yang setara).
4. Verifikasi Ingress Controller tersedia
Aksi
kubectl get pods --all-namespaces \
-l app.kubernetes.io/name=ingress-nginxExpected output
Minimal satu pod controller dalam state Running.
kolom STATUS = Running, READY = 1/1.
Jika gagal: jika Ingress Controller belum ada, install Nginx Ingress Controller sebelum lanjut. AlurKerja saat ini diuji dengan
ingress-nginx; controller lain (Traefik, HAProxy) belum divalidasi.
5. Verifikasi konektivitas PostgreSQL
Aksi
Dari mesin yang akan dipakai eksekusi (atau pod debug di cluster):
psql "postgresql://<DB_USER>:<DB_PASSWORD>@<DB_HOST>:<DB_PORT>/<DB_NAME>" \
-c "SELECT version();"Expected output
Banner PostgreSQL versi 13 atau lebih baru.
Jika gagal: jika koneksi gagal, cek firewall, security group, atau routing dari cluster ke host database. PostgreSQL boleh di luar cluster (managed service, VM terpisah) atau di dalam cluster.
6. Verifikasi DNS mengarah ke Ingress
Aksi
Dari mesin di luar cluster:
dig +short <APP_FE_HOST>
dig +short <API_HOST>Expected output
IP yang sama dengan address Ingress Controller (cek kubectl -n ingress-nginx get svc).
IP hasil dig cocok dengan EXTERNAL-IP dari LoadBalancer Ingress, atau NodePort yang ter-publish.
Jika gagal: jika DNS belum mengarah, koordinasi dengan tim network pelanggan. DNS boleh belum siap saat eksekusi langkah ini — tapi harus siap sebelum smoke test (Step 39–41).
7. Verifikasi akses Harbor registry
Aksi
docker login harbor.merapi.javan.idExpected output
Login Succeeded.
Jika gagal: kalau gagal, minta credential Harbor ke tim Javan (registry image AlurKerja terpusat di
harbor.merapi.javan.id). Credential ini akan dipakai untuk Step 10.
C. Arsitektur Ringkas
AlurKerja terdiri dari 17 workload yang berjalan di Kubernetes:
- 1 cache —
redis(in-cluster, untuk session + cache aplikasi). - 11 backend Go —
onprem-auth,onprem-bpm,onprem-tenant,onprem-compro-be,onprem-notification,onprem-integration,onprem-report,onprem-generate-test,onprem-proxy,onprem-migration,onprem-simulation-be. - 1 backend Java (Camunda) —
onprem-camunda, mesin BPMN/workflow engine. - 4 frontend —
onprem-app-fe,onprem-studio-fe,onprem-compro-fe,onprem-simulation-fe.
Jika diagram di atas tidak ter-render (masih tampak sebagai code block atau pesan error), build belum punya mermaid di dependency atau wrapper <Mermaid> belum terdaftar di mdx-components.tsx. Versi statik PNG tersedia di Lotus /architecture.
D. Persiapan Cluster
Langkah 8–12 menyiapkan namespace dan secret registry untuk pull image dari Harbor.
8. Set variabel instalasi
Aksi
export NAMESPACE="alurkerja"
export KUSTOMIZE_DIR="k8s"Sesuaikan NAMESPACE dengan konvensi pelanggan (alurkerja-prod, acme-staging, dst). KUSTOMIZE_DIR mengikuti path manifest di repo alurkerja/on-premises.
Override namespace di manifest. Manifest di branch feat/k8s-poc-manifests meng-hardcode namespace: poc-lpp di setiap file (warisan PoC Linknet). kustomization.yaml belum punya directive namespace: global. Sebelum lanjut ke Step 9, tambahkan baris berikut di k8s/kustomization.yaml:
namespace: ${NAMESPACE}(Atau alternatif manual: find k8s/ -name "*.yaml" -exec sed -i.bak "s/namespace: poc-lpp/namespace: ${NAMESPACE}/g" {} \;.)
Expected output
Tidak ada — assignment env var.
echo $NAMESPACE $KUSTOMIZE_DIR menampilkan nilai yang baru di-set. grep -c 'namespace: poc-lpp' k8s/**/*.yaml = 0.
Perhatian: jangan lanjut ke step 9 sebelum kedua env var ter-set dan namespace di manifest sudah di-override, karena semua command berikutnya bergantung pada keduanya.
9. Buat namespace target
Aksi
kubectl create namespace ${NAMESPACE} \
--dry-run=client -o yaml | kubectl apply -f -Expected output
namespace/<NAMESPACE> createdatau, jika sudah ada:
namespace/<NAMESPACE> configuredkubectl get namespace ${NAMESPACE} menampilkan namespace dengan status Active.
Perhatian: pakai pattern
--dry-run=client -o yaml | kubectl apply -f -supaya idempoten — boleh dijalankan ulang tanpa error.
10. Buat secret registry Harbor
Aksi
kubectl -n ${NAMESPACE} create secret docker-registry harbor-regcred \
--docker-server=harbor.merapi.javan.id \
--docker-username='<HARBOR_USERNAME>' \
--docker-password='<HARBOR_PASSWORD>' \
--dry-run=client -o yaml | kubectl apply -f -Expected output
secret/harbor-regcred createdkubectl -n ${NAMESPACE} get secret harbor-regcred menampilkan secret dengan TYPE kubernetes.io/dockerconfigjson.
Perhatian: jangan ketik password di shell history yang ter-save. Gunakan variabel env atau read dari file
.envlokal denganchmod 600.
11. Validasi secret registry dapat dipakai
Aksi
kubectl -n ${NAMESPACE} get secret harbor-regcred -o jsonpath='{.data.\.dockerconfigjson}' \
| base64 -d \
| jq -r '.auths | keys[]'Expected output
harbor.merapi.javan.idserver registry sesuai (bukan registry lain).
Jika gagal: jika output kosong atau salah server, hapus secret (
kubectl -n ${NAMESPACE} delete secret harbor-regcred) dan ulang Step 10.
12. Verifikasi clone repo manifest
Aksi
git clone git@gitlab.javan.co.id:alurkerja/on-premises.git
cd on-premises
git checkout feat/k8s-poc-manifestsExpected output
Repo terdownload dan branch feat/k8s-poc-manifests aktif. Working directory berisi folder k8s/, config/, nginx/, dsb.
ls k8s/config/ menampilkan configmap.yaml, secrets.yaml, camunda-configmap.yaml. ls k8s/apps/ menampilkan 17 file deployment (redis.yaml + 11 onprem-*-be/-auth/... + onprem-camunda.yaml + 4 onprem-*-fe.yaml).
Jika gagal: jika tidak ada akses, minta read access ke tim Javan melalui
helpdesk.alurkerja.com. Branchfeat/k8s-poc-manifestsadalah snapshot manifest hasil PoC Linknet — jadi referensi proven untuk instalasi pertama.
E. ConfigMap & Secret
Langkah 13–22 mengisi semua placeholder konfigurasi. Bagian ini paling rawan kesalahan — patuhi urutan dan validasi tiap langkah.
Jangan commit nilai rahasia asli. Edit file k8s/config/secrets.yaml di working copy lokal, tapi jangan git add setelah diisi nilai produksi. Pakai branch lokal sementara atau template .env di-mount sebagai secret.
13. Edit alurkerja-config
Aksi
$EDITOR k8s/config/configmap.yamlIsi seluruh placeholder <YOUR_*> mengikuti tabel berikut. Daftar key di bawah cocok dengan manifest feat/k8s-poc-manifests di repo alurkerja/on-premises (22 key total):
| Key | Nilai | Catatan |
|---|---|---|
DB_HOST | hostname PostgreSQL | Wajib |
DB_PORT | 5432 | Default PostgreSQL |
DB_USER | user database AlurKerja | Wajib |
DB_NAME | nama database | Wajib |
DB_SCHEMA | public | Default; jangan ubah kecuali ada keperluan khusus |
KEYCLOAK_URL | URL Keycloak SSO | Kosongkan kalau SSO belum aktif |
KEYCLOAK_REALM | realm Keycloak | Contoh: alurkerja-prod |
KEYCLOAK_CLIENT | client ID Keycloak | Default: onprem-client |
MINIO_ENDPOINT | endpoint MinIO | Contoh: minio.acme.local:9000 |
MINIO_BUCKET_NAME | bucket untuk file tenant | Default: tenant-uploads |
MINIO_USE_SSL | true / false | false jika MinIO tanpa TLS |
STORAGE_PROVIDER | minio | Default; alternatif: s3 |
REDIS_HOST | redis | Jangan ubah jika pakai Redis dari manifest |
REDIS_PORT | 6379 | Default Redis |
REDIS_PASSWORD | (kosong) | Isi kalau Redis butuh auth |
REDIS_DB | 0 | Database Redis untuk session |
CACHE_PROVIDER | redis | Default |
CACHE_ENABLED | true | |
CACHE_HOST | redis | Sama dengan REDIS_HOST |
CACHE_PORT | 6379 | Sama dengan REDIS_PORT |
CACHE_PASSWORD | (kosong) | |
CACHE_DB | 0 | Database Redis untuk cache (boleh sama dengan REDIS_DB) |
URL frontend publik (app.{domain}, studio.{domain}, compro.{domain}, simulation.{domain}, api.{domain}, camunda.{domain}) tidak di-config di sini — host publik di-set di Ingress (Step 16). Setiap service backend tahu host-nya sendiri via routing Nginx Ingress Controller. Frontend service mendapat URL via env build-time mereka sendiri (.env.onprem-*-fe).
Expected output
File tersimpan tanpa placeholder <YOUR_*> tersisa.
grep -n '<YOUR_' k8s/config/configmap.yaml tidak menemukan baris (exit code 1).
Perhatian: ConfigMap visible di cluster — pastikan nilai yang ditaruh di sini bukan rahasia. Rahasia masuk ke
alurkerja-secrets(Step 14).
14. Edit alurkerja-secrets
Aksi
$EDITOR k8s/config/secrets.yamlIsi placeholder mengikuti tabel (8 key dari manifest feat/k8s-poc-manifests):
| Key | Nilai | Catatan |
|---|---|---|
DB_PASSWORD | password user database | Wajib |
DB_PASS | password user database | Duplikat dari DB_PASSWORD — diperlukan oleh sebagian service yang masih pakai nama lama |
KEYCLOAK_CLIENT_SECRET | client secret Keycloak | Wajib jika SSO aktif |
MINIO_ACCESS_KEY | access key MinIO | Wajib |
MINIO_SECRET_KEY | secret key MinIO | Wajib |
JWT_SECRET | random string ≥ 64 char | Generate dengan openssl rand -hex 64 |
JWT_REFRESH_TOKEN_SECRET | random string ≥ 64 char | Berbeda dari JWT_SECRET |
TENANT_SETTINGS_ENCRYPTION_KEY | 32-byte key | Generate dengan openssl rand -hex 32 |
TENANT_SETTINGS_ENCRYPTION_IV | 16-byte IV | Generate dengan openssl rand -hex 16 |
Expected output
File tersimpan tanpa placeholder <YOUR_*> tersisa.
grep -n '<YOUR_' k8s/config/secrets.yaml tidak menemukan baris.
Perhatian: wajib
git update-index --assume-unchanged k8s/config/secrets.yamlatau pakai branch lokal.gitignored supaya nilai asli tidak ter-commit. GenerateJWT_*danTENANT_SETTINGS_*denganopenssl rand— jangan reuse string yang pernah dipakai di environment lain.
15. Edit camunda-config
Aksi
$EDITOR k8s/config/camunda-configmap.yamlBerbeda dengan alurkerja-config yang berbentuk key-value pairs, camunda-config berisi satu key application.yaml yang isinya konfigurasi Spring Boot multi-line. Edit field di dalam blob tersebut, bukan menambah top-level key baru.
Field yang wajib di-override (jangan biarkan default placeholder Linknet):
spring:
minio:
url: <MINIO_URL> # contoh: http://minio.acme.local:9000
accessKey: <MINIO_ACCESS_KEY>
secretKey: <MINIO_SECRET_KEY>
datasource:
hikari:
schema: camunda # jangan ubah
url: jdbc:postgresql://<DB_HOST>:<DB_PORT>/<DB_NAME>?autoReconnect=true
username: <DB_USER>
password: <DB_PASSWORD>
camunda.bpm.admin-user:
id: admin
password: <CAMUNDA_ADMIN_PASSWORD> # JANGAN biarkan "admin" di productionManifest default repo mencantumkan beberapa kredensial development dengan literal string (Telegram bot token, FreeIPA password, dst) sebagai default ${VAR:default}. Override semua default dengan env yang benar atau hapus default sebelum apply ke production.
Expected output
File tersimpan dengan field datasource.url, datasource.username, datasource.password, minio.* sudah berisi nilai environment target.
grep -nE 'admin|asdf1234|J4v4nDev|dummy\.local|merapi\.javan\.id' k8s/config/camunda-configmap.yaml tidak menampilkan baris yang berisi nilai default Linknet/dev.
Perhatian: schema database Camunda harus
camunda(matching Step 24 schema init). Kalau di-override ke schema lain, schema SQL Step 24 perlu disesuaikan.
16. Sesuaikan host Ingress
Aksi
$EDITOR k8s/ingress/ingress.yaml # backend + Camunda (api., simulation., camunda.)
$EDITOR k8s/ingress/ingress-fe.yaml # frontend (app., studio., compro., simulation.)Ganti seluruh *-lpp.merapi.javan.id (host Linknet) dengan host pelanggan. Total 7 host yang perlu diganti:
api-lpp.merapi.javan.id→api.{domain}(diingress.yaml)simulation-lpp.merapi.javan.id→simulation.{domain}(diingress.yaml, untuk simulation-be)camunda-lpp.merapi.javan.id→camunda.{domain}(diingress.yaml)app-lpp.merapi.javan.id→app.{domain}(diingress-fe.yaml)studio-lpp.merapi.javan.id→studio.{domain}(diingress-fe.yaml)compro-lpp.merapi.javan.id→compro.{domain}(diingress-fe.yaml)simulation-lpp.merapi.javan.id→simulation.{domain}(diingress-fe.yaml, frontend)
Expected output
Semua host di kedua file Ingress sudah mengarah ke domain pelanggan.
grep -rE 'lpp\.merapi\.javan\.id|dummy\.local' k8s/ingress/ tidak menemukan baris.
Perhatian: kalau pelanggan pakai sub-path (bukan sub-domain), Ingress butuh anotasi
nginx.ingress.kubernetes.io/rewrite-targetdan struktur path-based — koordinasi dengan tim AlurKerja sebelum custom. Annotationnginx.ingress.kubernetes.io/proxy-body-size: 50msudah di-set di template untuk file upload tenant.
17. Validasi kelengkapan key alurkerja-config
Aksi
kubectl kustomize ${KUSTOMIZE_DIR} \
| yq 'select(.kind == "ConfigMap" and .metadata.name == "alurkerja-config") | .data | keys | length'Expected output
22 (jumlah key sesuai tabel Step 13).
Jika gagal: kalau jumlah kurang, kembali ke Step 13 dan tambahkan key yang missing.
18. Validasi kelengkapan key alurkerja-secrets
Aksi
kubectl kustomize ${KUSTOMIZE_DIR} \
| yq 'select(.kind == "Secret" and .metadata.name == "alurkerja-secrets") | .stringData | keys | length'Expected output
9 (jumlah key sesuai tabel Step 14: 8 fungsional + DB_PASS duplikat untuk service yang masih pakai nama lama).
Jika gagal: kalau jumlah kurang, kembali ke Step 14 dan tambahkan.
19. Validasi camunda-config parseable
Aksi
kubectl kustomize ${KUSTOMIZE_DIR} \
| yq 'select(.kind == "ConfigMap" and .metadata.name == "camunda-config") | .data."application.yaml"' \
| yq '.spring.datasource.url, .spring.datasource.username, .camunda.bpm.database.schema-name'Expected output
Tiga baris berurutan: JDBC URL valid, username database, dan camunda.
schema-name tepat camunda; url mengandung <DB_HOST> yang sudah di-set, bukan 192.168.88.100 (alamat dev internal).
Jika gagal: kalau
yqgagal parse, blobapplication.yamlpunya YAML error — buka file ulang dan perbaiki indentasi.
20. Render manifest awal untuk validasi placeholder
Aksi
kubectl kustomize ${KUSTOMIZE_DIR} > /tmp/alurkerja-render.yamlExpected output
File /tmp/alurkerja-render.yaml tersimpan (size > 100 KB tipikal).
ls -la /tmp/alurkerja-render.yaml menampilkan file dengan ukuran > 50 KB.
Jika gagal: kalau
kustomizeerror, baca pesan error dan perbaiki — biasanya karena indentasi atau key tidak valid di file yang di-edit di Step 13–16.
21. Validasi tidak ada placeholder tersisa
Aksi
grep -nE '<YOUR_|dummy\.local|api-lpp\.merapi\.javan\.id|app-lpp\.merapi\.javan\.id|studio-lpp\.merapi\.javan\.id|compro-lpp\.merapi\.javan\.id|simulation-lpp\.merapi\.javan\.id|camunda-lpp\.merapi\.javan\.id' \
/tmp/alurkerja-render.yamlExpected output
Tidak ada baris yang cocok (exit code 1).
Jika gagal: kalau masih ada placeholder, hentikan proses dan kembali ke Step 13–16 untuk mengganti. Jangan apply manifest yang masih ada placeholder.
22. Verifikasi tidak ada secret value asli yang akan di-commit
Aksi
git status
git diff --cached k8s/config/secrets.yamlExpected output
k8s/config/secrets.yaml tidak muncul di "Changes to be committed".
Jika gagal: kalau ter-stage,
git restore --staged k8s/config/secrets.yaml. Pertimbangkan pakai.gitignorelokal ataugit update-index --assume-unchangedsupaya tidak terulang.
F. Schema Camunda
Langkah 23–25 menyiapkan schema database untuk Camunda BPMN engine.
23. Inisialisasi schema dasar
Aksi
psql "postgresql://<DB_USER>:<DB_PASSWORD>@<DB_HOST>:<DB_PORT>/<DB_NAME>" \
-v ON_ERROR_STOP=1 \
-f config/init-db.sqlExpected output
Beberapa baris CREATE TABLE, CREATE INDEX, tanpa error.
exit code 0 (echo $? menampilkan 0).
Perhatian: flag
-v ON_ERROR_STOP=1memastikan script berhenti pada error pertama, bukan continue dengan error tersembunyi.
24. Inisialisasi schema Camunda
Aksi
psql "postgresql://<DB_USER>:<DB_PASSWORD>@<DB_HOST>:<DB_PORT>/<DB_NAME>" \
-v ON_ERROR_STOP=1 \
-f config/camunda_schema.sqlExpected output
Banyak baris CREATE TABLE camunda.act_* (Camunda 7 punya ~50 table).
exit code 0.
Perhatian: file ini di-maintain oleh upstream Camunda, jangan modifikasi — kalau gagal, biasanya karena schema
camundasudah ada (dari instalasi sebelumnya). Drop schema denganDROP SCHEMA camunda CASCADE;lalu ulang.
25. Validasi table Camunda tersedia
Aksi
psql "postgresql://<DB_USER>:<DB_PASSWORD>@<DB_HOST>:<DB_PORT>/<DB_NAME>" \
-c "\dt camunda.*"Expected output
Daftar minimal 40+ table dengan prefix act_ (act_ru_, act_re_, act_hi_, act_id_, dst).
baris terakhir output menampilkan (NN rows) dengan NN ≥ 40.
Jika gagal: kalau jumlah row jauh lebih sedikit, schema tidak lengkap — drop schema dan ulang Step 24.
G. Render & Apply Manifest
Langkah 26–32 men-deploy seluruh workload AlurKerja ke cluster.
26. Render manifest final
Aksi
kubectl kustomize ${KUSTOMIZE_DIR} > /tmp/alurkerja-render.yamlExpected output
File ter-render (sama dengan Step 20, tapi setelah semua perbaikan dari Step 21).
wc -l /tmp/alurkerja-render.yaml menampilkan baris > 1000.
Jika gagal: kalau berbeda ukuran signifikan dengan Step 20, kemungkinan ada perubahan struktur — review
git diffdi working copy.
27. Validasi resource kinds di hasil render
Aksi
grep -cE '^kind: ConfigMap' /tmp/alurkerja-render.yaml
grep -cE '^kind: Secret' /tmp/alurkerja-render.yaml
grep -cE '^kind: Deployment' /tmp/alurkerja-render.yaml
grep -cE '^kind: Service' /tmp/alurkerja-render.yaml
grep -cE '^kind: Ingress' /tmp/alurkerja-render.yamlExpected output
ConfigMap: ≥ 3
Secret: ≥ 2
Deployment: 17
Service: ≥ 17
Ingress: ≥ 1angka Deployment = 17 (sesuai daftar workload di Section C).
Jika gagal: kalau jumlah Deployment kurang dari 17, ada workload yang missing — review
k8s/kustomization.yaml.
28. Validasi namespace di hasil render
Aksi
grep -n 'namespace:' /tmp/alurkerja-render.yaml | sort -u | headExpected output
Semua resource di-namespace dengan ${NAMESPACE} yang sama (atau tanpa namespace untuk cluster-scoped).
tidak ada namespace lain selain target (alurkerja, atau apapun yang di-set di Step 8).
Jika gagal: kalau ada resource cross-namespace, ada bug di overlay kustomize — minta bantuan tim AlurKerja.
29. Apply manifest ke cluster
Aksi
kubectl apply -k ${KUSTOMIZE_DIR}Expected output
Banyak baris <resource>/<name> created atau configured.
tidak ada baris yang mengandung error atau Error.
Jika gagal: kalau ada error parsial, baca pesan dan ulang
kubectl apply -ksetelah perbaikan — apply bersifat idempoten.
30. Validasi ConfigMap + Secret applied
Aksi
kubectl -n ${NAMESPACE} get configmap
kubectl -n ${NAMESPACE} get secretExpected output
ConfigMap: alurkerja-config, camunda-config (minimal).
Secret: alurkerja-secrets, harbor-regcred (minimal).
semua resource ada di output dengan AGE > 0.
Jika gagal: kalau ada yang missing, ulang Step 29 — kemungkinan partial apply.
31. Validasi Deployment + Service applied
Aksi
kubectl -n ${NAMESPACE} get deploy
kubectl -n ${NAMESPACE} get svcExpected output
17 baris Deployment, ≥ 17 baris Service.
kolom READY Deployment masih 0/N di tahap ini (karena pod sedang scheduled) — itu normal.
Jika gagal: kalau jumlah deploy < 17, ulang Step 29.
32. Validasi Ingress applied
Aksi
kubectl -n ${NAMESPACE} get ingress -o wideExpected output
Minimal 1 Ingress dengan kolom HOSTS berisi domain pelanggan dan ADDRESS berisi IP Ingress Controller.
kolom HOSTS cocok dengan yang di-set di Step 16.
Perhatian: kolom
ADDRESSboleh kosong sementara — biasanya terisi setelah Ingress Controller reconcile (1–2 menit).
H. Verifikasi
Langkah 33–42 memastikan seluruh workload Ready dan endpoint merespons. Bagian ini paling lama karena menunggu image pull + startup probe.
33. Rollout status Redis
Aksi
kubectl -n ${NAMESPACE} rollout status deploy/redis --timeout=5mExpected output
deployment "redis" successfully rolled outPerhatian: Redis adalah dependency pertama — kalau gagal, semua service yang butuh cache juga akan gagal. Selesaikan dulu sebelum lanjut.
34. Rollout status backend Go (11 service)
Aksi
for svc in onprem-auth onprem-bpm onprem-tenant onprem-compro-be \
onprem-notification onprem-integration onprem-report \
onprem-generate-test onprem-proxy onprem-migration \
onprem-simulation-be; do
kubectl -n ${NAMESPACE} rollout status deploy/$svc --timeout=10m
doneExpected output
11 baris "successfully rolled out".
Jika gagal: kalau ada yang stuck
ImagePullBackOff, kembali ke Step 11 (validasi Harbor secret). Kalau stuckCrashLoopBackOff, cek log:kubectl -n ${NAMESPACE} logs <POD> --tail=100.
35. Rollout status Camunda
Aksi
kubectl -n ${NAMESPACE} rollout status deploy/onprem-camunda --timeout=10mExpected output
deployment "onprem-camunda" successfully rolled outPerhatian: Camunda startup paling lambat (60–120 detik) karena bootstrap engine. Kalau timeout di 10 menit, cek log untuk error koneksi DB atau schema.
36. Rollout status frontend (4 service)
Aksi
for svc in onprem-app-fe onprem-studio-fe onprem-compro-fe onprem-simulation-fe; do
kubectl -n ${NAMESPACE} rollout status deploy/$svc --timeout=5m
doneExpected output
4 baris "successfully rolled out".
Perhatian: frontend AlurKerja adalah container Nginx serving static asset Next.js — startup cepat (< 30 detik).
37. Validasi semua pod Ready
Aksi
kubectl -n ${NAMESPACE} get podsExpected output
Semua pod kolom READY menampilkan 1/1 (atau N/N untuk pod multi-container), STATUS Running, RESTARTS = 0.
tidak ada pod dengan status Pending, ImagePullBackOff, CrashLoopBackOff, atau Error.
Jika gagal: kalau ada pod yang
RESTARTS > 0, cek log untuk error yang mungkin sudah recoverable. Kalau pod terus restart, hentikan dan investigate sebelum lanjut.
38. Validasi Camunda readiness probe
Aksi
kubectl -n ${NAMESPACE} port-forward deploy/onprem-camunda 8080:8080 &
sleep 3
curl -sI http://localhost:8080/engine-rest/engine
kill %1Expected output
HTTP/1.1 200 OK dengan body JSON [{"name":"default"}].
Jika gagal: kalau 503 atau timeout, schema Camunda mungkin belum lengkap — ulang Step 24–25.
39. Smoke test App FE
Aksi
curl -ILk https://<APP_FE_HOST>/Expected output
HTTP 200 (atau 30x redirect ke /login).
kode status 200 atau 30x; header Server menyebut nginx.
Jika gagal: kalau 404, cek Ingress host (Step 16 + 32). Kalau timeout, cek DNS (Step 6).
40. Smoke test Studio FE, Compro FE, Simulation FE
Aksi
curl -ILk https://<STUDIO_FE_HOST>/
curl -ILk https://<COMPRO_FE_HOST>/
curl -ILk https://<SIMULATION_FE_HOST>/Expected output
Tiga response 200 atau 30x.
semua endpoint merespons dalam < 2 detik.
Jika gagal: kalau hanya satu yang gagal, isolated issue — kemungkinan host di Ingress salah ketik.
41. Smoke test API gateway
Aksi
curl -Ik https://<API_HOST>/api/v1/authentication/Expected output
HTTP 200 atau 401 (Unauthorized — wajar karena tanpa token).
status code 200 atau 401, bukan 404 atau 502.
Jika gagal: kalau 502 Bad Gateway, kemungkinan
onprem-proxybelum Ready — tunggu dan ulang.
42. Smoke test WebSocket notification
Aksi
curl -Ik -H "Connection: Upgrade" -H "Upgrade: websocket" \
-H "Sec-WebSocket-Version: 13" \
-H "Sec-WebSocket-Key: $(openssl rand -base64 16)" \
https://<API_HOST>/ws/Expected output
HTTP 101 Switching Protocols, atau 401 (kalau auth required).
status code 101 atau 401, bukan 404.
Perhatian: WebSocket di-route ke
onprem-notification:3008. Kalau 404, periksa annotation Ingressnginx.ingress.kubernetes.io/proxy-read-timeoutdan path/ws/.
I. Akses Pertama Kali
Langkah 43–47 melakukan first-login dan setup tenant pertama. Tahap ini memvalidasi bahwa stack sudah usable, bukan hanya healthy.
Credential admin default berikut harus diganti segera setelah first-login. Jangan biarkan credential default aktif di production.
43. Buka URL App FE di browser
Aksi
Buka https://<APP_FE_HOST>/ di browser modern (Chrome/Firefox/Edge terkini).
Expected output
Halaman login AlurKerja dengan logo dan form email/password.
halaman ter-render lengkap (logo + form + tombol login) tanpa error di browser console.
Jika gagal: kalau ada CORS error di console, cek
APP_BASE_URLdanAPI_BASE_URLdi ConfigMap (Step 13) — harus konsisten dengan host yang dipakai browser.
44. Login sebagai admin default
Aksi
Masukkan credential default (akan disediakan terpisah oleh tim AlurKerja saat handover) dan klik Login.
Expected output
Redirect ke halaman dashboard atau tenant selection.
URL berubah ke /dashboard atau /tenants.
Jika gagal: kalau gagal login, cek log
onprem-auth:kubectl -n ${NAMESPACE} logs deploy/onprem-auth --tail=50.
45. Buat tenant pertama
Aksi
Klik Create Tenant → isi nama tenant + identifier → submit.
Expected output
Tenant baru muncul di list, status Active.
halaman menampilkan banner sukses + tenant baru di list.
Perhatian: identifier tenant biasanya jadi prefix subdomain atau path — koordinasi dengan tim network kalau pakai sub-domain per tenant.
46. Buat user pertama dengan role Owner
Aksi
Di tenant baru, masuk ke menu Users → Invite User → isi email + role Owner → kirim invitation.
Expected output
Email invitation terkirim ke alamat yang di-input; user muncul di list dengan status Pending.
notifikasi sukses + entry baru di tabel Users.
Jika gagal: kalau email tidak terkirim, cek konfigurasi SMTP di
alurkerja-config(Step 13). Bisa juga lakukan invite tanpa email dan share link manual.
47. Login sebagai user baru
Aksi
Buka link invitation, set password, login.
Expected output
Redirect ke dashboard tenant; menu navigasi sesuai role Owner.
user baru bisa akses semua menu (Studio, App, Reports, dst).
Perhatian: logout admin default dan jangan dipakai lagi. Set admin default ke disabled setelah Owner pertama terbentuk.
J. Troubleshooting
Tiga skenario error paling umum saat instalasi. Lihat juga Handbook Troubleshooting untuk daftar lebih luas.
Skenario 1: Ingress unreachable (curl connect refused / timeout)
Gejala
curl https://<APP_FE_HOST>/timeout atau "connection refused".- Browser menampilkan "site can't be reached".
Aksi diagnostik
kubectl -n ${NAMESPACE} get ingress -o wide
kubectl -n ingress-nginx logs deploy/ingress-nginx-controller --tail=50
dig +short <APP_FE_HOST>Aksi remediasi
- Cek
ADDRESSIngress sudah terisi — kalau kosong, tunggu 1–2 menit. - Cek DNS
<APP_FE_HOST>mengarah ke EXTERNAL-IP Ingress Controller. - Cek firewall pelanggan (port 80/443 reachable dari client).
Skenario 2: Database connection refused (onprem-* pod CrashLoopBackOff)
Gejala
- Pod backend stuck
CrashLoopBackOff. - Log pod menampilkan
dial tcp <DB_HOST>:5432: connect: connection refused.
Aksi diagnostik
kubectl -n ${NAMESPACE} logs <POD> --tail=100
kubectl -n ${NAMESPACE} run dbcheck --rm -it --image=postgres:15 -- \
psql "postgresql://<DB_USER>:<DB_PASSWORD>@<DB_HOST>:<DB_PORT>/<DB_NAME>" -c "SELECT 1;"Aksi remediasi
- Verifikasi credential di
alurkerja-secrets(Step 14) cocok dengan database. - Cek security group / firewall — apakah cluster CIDR di-allow di database.
- Cek
pg_hba.confdi server PostgreSQL — apakah host cluster di-allow.
Skenario 3: ImagePullBackOff saat rollout
Gejala
- Pod stuck
ImagePullBackOffatauErrImagePull. - Event pod menampilkan
Failed to pull image "harbor.merapi.javan.id/...": unauthorized.
Aksi diagnostik
kubectl -n ${NAMESPACE} describe pod <POD> | grep -A3 Events
kubectl -n ${NAMESPACE} get secret harbor-regcred -o jsonpath='{.data.\.dockerconfigjson}' | base64 -dAksi remediasi
- Verifikasi secret
harbor-regcredada dan menunjuk keharbor.merapi.javan.id(Step 11). - Verifikasi credential Harbor valid (
docker logindari mesin lokal — Step 7). - Hapus + buat ulang secret kalau credential expired.
- Pastikan
imagePullSecrets: [{name: harbor-regcred}]ada di spec Deployment — biasanya sudah di-set di kustomize.
K. Logbook Instalasi
Template berikut sinkron 1:1 dengan nomor langkah di halaman ini. Download versi spreadsheet di alurkerja-install-k8s-checklist.xlsx untuk isi sambil eksekusi.
| No | Section | Aksi | Hasil | Bukti | PIC | Catatan |
|---|---|---|---|---|---|---|
| 1 | Prasyarat | Verifikasi kubectl | ||||
| 2 | Prasyarat | Verifikasi context | ||||
| 3 | Prasyarat | Verifikasi permission | ||||
| 4 | Prasyarat | Verifikasi Ingress Controller | ||||
| 5 | Prasyarat | Verifikasi PostgreSQL | ||||
| 6 | Prasyarat | Verifikasi DNS | ||||
| 7 | Prasyarat | Verifikasi Harbor login | ||||
| 8 | Persiapan | Set variabel | ||||
| 9 | Persiapan | Buat namespace | ||||
| 10 | Persiapan | Buat harbor-regcred | ||||
| 11 | Persiapan | Validasi secret registry | ||||
| 12 | Persiapan | Clone repo manifest | ||||
| 13 | ConfigMap | Edit alurkerja-config | ||||
| 14 | ConfigMap | Edit alurkerja-secrets | ||||
| 15 | ConfigMap | Edit camunda-config | ||||
| 16 | ConfigMap | Sesuaikan host Ingress | ||||
| 17 | ConfigMap | Validasi key alurkerja-config | ||||
| 18 | ConfigMap | Validasi key alurkerja-secrets | ||||
| 19 | ConfigMap | Validasi key camunda-config | ||||
| 20 | ConfigMap | Render manifest awal | ||||
| 21 | ConfigMap | Validasi tidak ada placeholder | ||||
| 22 | ConfigMap | Verifikasi tidak commit secret | ||||
| 23 | Camunda | Init schema dasar | ||||
| 24 | Camunda | Init schema Camunda | ||||
| 25 | Camunda | Validasi table Camunda | ||||
| 26 | Apply | Render manifest final | ||||
| 27 | Apply | Validasi resource kinds | ||||
| 28 | Apply | Validasi namespace | ||||
| 29 | Apply | kubectl apply -k | ||||
| 30 | Apply | Validasi ConfigMap+Secret | ||||
| 31 | Apply | Validasi Deployment+Service | ||||
| 32 | Apply | Validasi Ingress | ||||
| 33 | Verifikasi | Rollout Redis | ||||
| 34 | Verifikasi | Rollout backend Go | ||||
| 35 | Verifikasi | Rollout Camunda | ||||
| 36 | Verifikasi | Rollout frontend | ||||
| 37 | Verifikasi | Semua pod Ready | ||||
| 38 | Verifikasi | Camunda readiness | ||||
| 39 | Verifikasi | Smoke test App FE | ||||
| 40 | Verifikasi | Smoke test Studio/Compro/Sim FE | ||||
| 41 | Verifikasi | Smoke test API | ||||
| 42 | Verifikasi | Smoke test WebSocket | ||||
| 43 | Akses | Buka URL App FE | ||||
| 44 | Akses | Login admin default | ||||
| 45 | Akses | Buat tenant pertama | ||||
| 46 | Akses | Buat user Owner | ||||
| 47 | Akses | Login user baru |
L. Validasi & Sign-off
Setelah seluruh 47 langkah selesai, isi sign-off berikut sebagai bukti instalasi diterima oleh pelanggan.
L.1 Acceptance criteria
| AC | Item | Status | Evidence (cell logbook) |
|---|---|---|---|
| AC 1.1 | Judul dokumen jelas dan sesuai scope | (Section A) | |
| AC 1.2 | Prasyarat terdokumentasi | (Step 1–7) | |
| AC 1.3 | Langkah instalasi berurutan | (Step 1–47) | |
| AC 1.4 | Konfigurasi awal jelas | (Step 13–22) | |
| AC 1.5 | Verifikasi service tertulis | (Step 33–42) | |
| AC 1.6 | Akses pertama kali terdokumentasi | (Step 43–47) | |
| AC 2 | Troubleshooting tersedia | (Section J) |
L.2 Sign-off
| Peran | Nama | Organisasi | Tanggal | Status | Catatan |
|---|---|---|---|---|---|
| Implementor | Javan | ||||
| Reviewer teknis | Pelanggan | ||||
| Approver operasional | Pelanggan |
Status sign-off:
- Accepted — instalasi diterima tanpa catatan blocker.
- Accepted with notes — diterima dengan catatan minor (tracked di logbook).
- Need revision — perlu perbaikan sebelum diterima.
Halaman ini berbasis runbook Linknet (PoC LPP 2025) yang telah teruji di production, di-generalize sebagai dokumentasi onboarding untuk pelanggan AlurKerja berikutnya. Perubahan signifikan: nomor langkah 1..N kontinu lintas section, catatan verifikasi observable per langkah, template logbook dapat di-download. Sumber asli: LINKNET_INSTALLATION_GUIDE.md internal repo alurkerja-link-net-pro.
