first commit

This commit is contained in:
2026-10-09 02:35:14 +07:00
commit 4ca7a9a58e
108 changed files with 23035 additions and 0 deletions
+388
View File
@@ -0,0 +1,388 @@
#!/usr/bin/env bash
# =============================================================================
# eBdesk SiCABE — Environment Defaults
# Sourced by install.sh and bootstrap.sh
# Override any value by exporting the variable before running install.sh
# or by creating deploy/.env with: export VAR=value
# =============================================================================
# ─── Global ─────────────────────────────────────────────────────────────────
export SICABE_ENV="${SICABE_ENV:-development}"
export COMPOSE_PROJECT_NAME="${COMPOSE_PROJECT_NAME:-sicabe}"
export SICABE_DOMAIN="${SICABE_DOMAIN:-localhost}"
export TIMEZONE="${TIMEZONE:-Asia/Jakarta}"
# ─── Secrets (ALWAYS override in production!) ───────────────────────────────
# Password statis agar konsisten saat docker-compose memproses env vars.
# Di production, overriede semua nilai berikut di file .env dengan password kuat.
# openssl rand -hex 16 > .env
# PostgreSQL: 1 instance shared untuk semua service (beda database)
export POSTGRES_PASSWORD="${POSTGRES_PASSWORD:-sicabe_pg_super_DevOnly}"
export KEYCLOAK_DB_PASSWORD="${KEYCLOAK_DB_PASSWORD:-sicabe_kc_db_DevOnly}"
export NESSIE_DB_PASSWORD="${NESSIE_DB_PASSWORD:-sicabe_nessie_db_DevOnly}"
export AIRFLOW_DB_PASSWORD="${AIRFLOW_DB_PASSWORD:-sicabe_af_db_DevOnly}"
export OPENMETADATA_DB_PASSWORD="${OPENMETADATA_DB_PASSWORD:-sicabe_om_db_DevOnly}"
export KEYCLOAK_ADMIN_PASSWORD="${KEYCLOAK_ADMIN_PASSWORD:-admin123}"
export MINIO_ROOT_PASSWORD="${MINIO_ROOT_PASSWORD:-minio12345}"
export AIRFLOW_ADMIN_PASSWORD="${AIRFLOW_ADMIN_PASSWORD:-airflow123}"
export GRAFANA_ADMIN_PASSWORD="${GRAFANA_ADMIN_PASSWORD:-grafana123}"
export OPENMETADATA_ADMIN_PASSWORD="${OPENMETADATA_ADMIN_PASSWORD:-openmetadata123}"
# OpenLDAP (identity — sumber grup untuk Trino & StarRocks)
export LDAP_ADMIN_PASSWORD="${LDAP_ADMIN_PASSWORD:-ldap_admin_DevOnly}"
export LDAP_CONFIG_PASSWORD="${LDAP_CONFIG_PASSWORD:-ldap_config_DevOnly}"
# OIDC Client secrets untuk setiap komponen (wajib sinkron dengan konfigurasi
# Trino, Grafana, dll. yang menggunakan nilai hardcoded di file .properties)
export TRINO_CLIENT_SECRET="${TRINO_CLIENT_SECRET:-trino-secret}"
export STARROCKS_CLIENT_SECRET="${STARROCKS_CLIENT_SECRET:-starrocks-secret}"
export AIRFLOW_CLIENT_SECRET="${AIRFLOW_CLIENT_SECRET:-airflow-secret}"
export OPENMETADATA_CLIENT_SECRET="${OPENMETADATA_CLIENT_SECRET:-om-secret}"
export GRAFANA_CLIENT_SECRET="${GRAFANA_CLIENT_SECRET:-grafana-secret}"
# ─── Network ────────────────────────────────────────────────────────────────
export HTTP_PORT="${HTTP_PORT:-80}"
export HTTPS_PORT="${HTTPS_PORT:-443}"
# Catatan: PostgreSQL TIDAK diexpose ke host (internal network saja).
# Untuk debugging dari host: docker exec -it sicabe-postgres psql -U sicabe_admin -d keycloak
# ─── Skema Port Host (prefix 12xxx) ─────────────────────────────────────────
# Aturan: host port = "12" + 3 digit port kanonik. Port internal container tetap.
# Memudahkan pelatihan: seluruh endpoint ada di blok 12000-12999.
# ─── Keycloak (Phase 1 — Governance: IAM) ──────────────────────────────────
export KEYCLOAK_VERSION="${KEYCLOAK_VERSION:-26.7}"
export KEYCLOAK_PORT="${KEYCLOAK_PORT:-12080}"
export KEYCLOAK_DB="${KEYCLOAK_DB:-keycloak}"
export KEYCLOAK_DB_USER="${KEYCLOAK_DB_USER:-keycloak}"
export KEYCLOAK_DB_HOST="${KEYCLOAK_DB_HOST:-postgres}"
# CATATAN: KC_HOSTNAME_URL sudah DIHAPUS di Keycloak 26.0.0 — jangan dipasang lagi
# (dulu diekspor di sini, dan tidak berpengaruh apa pun). Yang menentukan issuer,
# discovery, dan redirect sekarang: KC_HOSTNAME = URL publik lengkap, yang di compose
# diisi dari KEYCLOAK_PUBLIC_URL (lihat docker-compose.yml service keycloak).
export SICABE_REALM="${SICABE_REALM:-sicabe}"
export KEYCLOAK_ADMIN="${KEYCLOAK_ADMIN:-admin}"
# ─── Identity — OpenLDAP (Phase 1b) ─────────────────────────────────────────
# LDAP = sumber kebenaran GRUP (Trino & StarRocks group provider).
# User tetap didefinisikan di realm Keycloak (autentikasi OIDC).
export OPENLDAP_VERSION="${OPENLDAP_VERSION:-1.5.0}"
export OPENLDAP_PORT="${OPENLDAP_PORT:-12389}"
export LDAP_ORGANISATION="${LDAP_ORGANISATION:-SiCABE}"
export LDAP_DOMAIN="${LDAP_DOMAIN:-sicabe.local}"
export LDAP_ADMIN_DN="${LDAP_ADMIN_DN:-cn=admin,dc=sicabe,dc=local}"
export LDAP_BASE_DN="${LDAP_BASE_DN:-dc=sicabe,dc=local}"
export LDAP_USERS_DN="${LDAP_USERS_DN:-ou=users,dc=sicabe,dc=local}"
export LDAP_GROUPS_DN="${LDAP_GROUPS_DN:-ou=groups,dc=sicabe,dc=local}"
# ─── MinIO (Phase 2 — Storage) ──────────────────────────────────────────────
# Image MinIO HANYA tersedia di quay.io — repo Docker Hub `minio/minio` dan
# `minio/mc` sudah tidak ada (pull gagal: "repository does not exist").
export MINIO_VERSION="${MINIO_VERSION:-RELEASE.2025-09-07T16-13-09Z}"
export MINIO_MC_VERSION="${MINIO_MC_VERSION:-RELEASE.2025-08-13T08-35-41Z}"
export MINIO_PORT="${MINIO_PORT:-12900}"
export MINIO_CONSOLE_PORT="${MINIO_CONSOLE_PORT:-12901}"
export MINIO_ROOT_USER="${MINIO_ROOT_USER:-minioadmin}"
export MINIO_BUCKET_ICEBERG_DATA="${MINIO_BUCKET_ICEBERG_DATA:-iceberg-data}"
# Apache Nessie (Phase 2 — Storage: Metadata Catalog)
export NESSIE_VERSION="${NESSIE_VERSION:-0.108.4-java}"
export NESSIE_PORT="${NESSIE_PORT:-12120}"
# Nessie persistence database (PostgreSQL) — mengikuti konvensi shared Postgres
export NESSIE_DB="${NESSIE_DB:-nessie}"
export NESSIE_DB_USER="${NESSIE_DB_USER:-nessie}"
# ─── Alamat antar-container (multi-host) ────────────────────────────────────
# B1 (Review 10 §4.4): hostname yang dilihat CONTAINER saat menghubungi komponen
# lain. Kontrak: DEFAULT = nama container di docker-compose.yml → SINGLE-HOST
# TIDAK BERUBAH (dibuktikan diff `docker compose config` sha256 identik).
# Untuk menyebar komponen ke beberapa host, override ke alamat host pemilik:
# POSTGRES_HOST=10.20.0.12 MINIO_HOST=10.20.0.12 KEYCLOAK_HOST=10.20.0.10
# OPENMETADATA_HOST=10.20.0.10 STARROCKS_FE_HOST=10.20.0.11
# Dibedakan dari komponen EXISTING milik sistem lain (lihat bagian di bawah):
# yang itu memakai *_URL / S3_ENDPOINT + EXTERNAL_SERVICES.
export POSTGRES_HOST="${POSTGRES_HOST:-postgres}"
export MINIO_HOST="${MINIO_HOST:-minio}"
export KEYCLOAK_HOST="${KEYCLOAK_HOST:-keycloak}"
export OPENMETADATA_HOST="${OPENMETADATA_HOST:-openmetadata-server}"
export AIRFLOW_WEBSERVER_HOST="${AIRFLOW_WEBSERVER_HOST:-airflow-webserver}"
export STARROCKS_FE_HOST="${STARROCKS_FE_HOST:-starrocks-fe}"
export STARROCKS_CN_HOST="${STARROCKS_CN_HOST:-starrocks-cn}"
export OPENSEARCH_HOST="${OPENSEARCH_HOST:-openmetadata-opensearch}"
# ─── URL BROWSER-FACING (tls.mode != none) ──────────────────────────────────
# Dipakai HANYA untuk apa yang dilihat BROWSER (issuer OIDC, redirect, link UI) —
# BUKAN untuk lalu lintas container (itu memakai `*_HOST`/alamat di atas).
# Default = nilai sekarang, jadi tanpa perubahan apa pun perilakunya identik.
# Saat `tls.mode` = edge/full, generator menimpanya menjadi https://<label>.<domain>.
# Perhatian: `iss` token memuat SKEMA, jadi berpindah none -> edge mengubah
# issuer dan semua user harus login ulang (lihat R10 §5.7).
export KEYCLOAK_PUBLIC_URL="${KEYCLOAK_PUBLIC_URL:-http://localhost:${KEYCLOAK_PORT:-12080}}"
# Kebijakan SSL realm Keycloak. Default Keycloak `external` menuntut HTTPS untuk
# permintaan dari alamat NON-lokal — dan alamat Tailscale 100.64.0.0/10 (CGNAT)
# TERMASUK non-lokal, sehingga admin console via http://<tailscale>:12080 gagal
# dengan "HTTPS required". Keycloak 26 tidak punya opsi server-level untuk ini
# (tidak ada KC_HTTPS_REQUIRED), jadi harus per realm. Diisi `external` oleh
# generator saat tls.mode != none (ada Traefik/TLS di depan).
# Default `external` = aman: admin console via HTTP hanya diizinkan dari alamat lokal.
# Generator menulis `none` HANYA bila tls.mode != none... (mode `none` pada multi-host,
# yaitu HTTP polos ala dev) — di situ akses dari alamat Tailscale/CGNAT memang perlu
# diizinkan. Single-host (tanpa cluster.yml) tidak melewati generator, jadi ia memakai
# default ini dan tetap aman.
export KEYCLOAK_SSL_REQUIRED="${KEYCLOAK_SSL_REQUIRED:-external}"
# Cache Keycloak: `ispn` (default, registry di DB) atau `local` untuk instalasi
# SATU Keycloak — mematikan klaster + pemeriksaan cluster health.
export KEYCLOAK_CACHE="${KEYCLOAK_CACHE:-ispn}"
# ── Ingress / TLS (langkah 2, T-20) ──────────────────────────────────────────
# Traefik berjalan hanya pada profile `edge` (docker compose --profile edge).
# Tiap host menerbitkan sertifikatnya SENDIRI: acme.json tidak boleh dibagi antar
# host (Traefik tidak punya penyimpanan ACME terdistribusi), dan batas Let's
# Encrypt 5 sertifikat identik/minggu sebaiknya dihindari dengan staging dulu.
export CLUSTER_DOMAIN="${CLUSTER_DOMAIN:-sicabe.com}"
export TRAEFIK_VERSION="${TRAEFIK_VERSION:-v3.7}"
export TRAEFIK_HTTP_PORT="${TRAEFIK_HTTP_PORT:-80}"
export TRAEFIK_HTTPS_PORT="${TRAEFIK_HTTPS_PORT:-443}"
# Alamat bind port 80/443. Di multi-host diisi generator dengan alamat host,
# supaya ingress tidak terbuka di semua antarmuka.
export TRAEFIK_BIND_ADDR="${TRAEFIK_BIND_ADDR:-0.0.0.0}"
export TRAEFIK_ACME_EMAIL="${TRAEFIK_ACME_EMAIL:-admin@${CLUSTER_DOMAIN:-sicabe.com}}"
export TRAEFIK_DNS_PROVIDER="${TRAEFIK_DNS_PROVIDER:-cloudflare}"
# STAGING dulu (batas longgar). Produksi:
# https://acme-v02.api.letsencrypt.org/directory
# Jeda sebelum LE memeriksa TXT. Apex + wildcard memakai nama TXT yang SAMA
# (_acme-challenge.<domain>), jadi propagasi perlu waktu — default Traefik 0s.
export TRAEFIK_ACME_PROPAGATION_DELAY="${TRAEFIK_ACME_PROPAGATION_DELAY:-30s}"
# Catatan lego/Cloudflare (opsional, diset sebagai env container bila perlu):
# CLOUDFLARE_PROPAGATION_TIMEOUT (default 120), CLOUDFLARE_POLLING_INTERVAL (2), CLOUDFLARE_TTL (120)
export TRAEFIK_ACME_CASERVER="${TRAEFIK_ACME_CASERVER:-https://acme-staging-v02.api.letsencrypt.org/directory}"
# Cloudflare DNS-01: token API dengan izin Zone:DNS:Edit. WAJIB diisi sebelum
# sertifikat bisa diterbitkan; kosong = Traefik tetap start dan memakai
# sertifikat self-signed bawaan (routing masih bisa diuji).
export CF_DNS_API_TOKEN="${CF_DNS_API_TOKEN:-}"
export GRAFANA_PUBLIC_URL="${GRAFANA_PUBLIC_URL:-http://localhost:${GRAFANA_PORT:-12300}}"
# URL browser-facing: default localhost (nama internal airflow-webserver:8080 tidak
# bisa diresolusi browser). Bundle multi-host mengisinya dengan alamat host pemilik.
export AIRFLOW_PUBLIC_URL="${AIRFLOW_PUBLIC_URL:-http://localhost:${AIRFLOW_PORT:-12082}}"
export OPENMETADATA_PUBLIC_URL="${OPENMETADATA_PUBLIC_URL:-http://localhost:${OPENMETADATA_PORT:-12085}}"
export TRINO_PUBLIC_URL="${TRINO_PUBLIC_URL:-https://localhost:${TRINO_HTTPS_PORT:-12443}}"
export MINIO_CONSOLE_PUBLIC_URL="${MINIO_CONSOLE_PUBLIC_URL:-http://localhost:${MINIO_CONSOLE_PORT:-12901}}"
# ─── Endpoint Object Storage & Nessie ───────────────────────────────────────
# Default = container lokal hasil deploy ini (perilaku tidak berubah). Untuk
# memakai penyimpanan objek (S3/MinIO) atau Nessie EXISTING, override di .env:
# S3_ENDPOINT → dilihat CONTAINER (Trino, Nessie, StarRocks)
# NESSIE_URL → dilihat CONTAINER (Trino, Sling, StarRocks)
# NESSIE_HOST/PORT → dilihat HOST (skrip verifikasi)
# Contoh:
# S3_ENDPOINT=https://s3.corp.internal
# S3_ACCESS_KEY=... S3_SECRET_KEY=... S3_REGION=ap-southeast-1
# NESSIE_URL=https://nessie.corp.internal
export S3_ENDPOINT="${S3_ENDPOINT:-http://minio:9000}"
export S3_REGION="${S3_REGION:-us-east-1}"
# CATATAN: S3_ACCESS_KEY / S3_SECRET_KEY sengaja TIDAK di-default di sini.
# Bila di-default dari MINIO_ROOT_*, nilainya terkunci pada nilai default sebelum
# .env di-source (mis. minio12345) sehingga berbeda dari kredensial sebenarnya.
# Semua pemakaian memakai fallback saat-pakai: ${S3_ACCESS_KEY:-${MINIO_ROOT_USER:-...}}.
export NESSIE_URL="${NESSIE_URL:-http://nessie:19120}"
export NESSIE_HOST="${NESSIE_HOST:-localhost}"
export NESSIE_PORT="${NESSIE_PORT:-12120}"
# ─── Trino (Phase 3 — Processing) ───────────────────────────────────────────
export TRINO_VERSION="${TRINO_VERSION:-483}"
# TRINO_PORT = port HTTP polos historis. Trino TIDAK melayani HTTP polos
# (allow-insecure-over-http=false) dan port ini tidak di-expose. Dipakai gate Fase 3
# (verify-phase3-processing.sh) sebagai target uji-negatif "HTTP polos harus mati".
export TRINO_PORT="${TRINO_PORT:-12081}"
export TRINO_HTTPS_PORT="${TRINO_HTTPS_PORT:-12443}"
# Endpoint dari sisi HOST (gate verifikasi + bootstrap step 4). Untuk Trino
# EXISTING: TRINO_URL=https://trino.corp:8443 dan TRINO_TLS_VERIFY=1 (verifikasi TLS aktif;
# default 0 = lewati verifikasi, hanya untuk sertifikat self-signed dev).
export TRINO_URL="${TRINO_URL:-https://localhost:${TRINO_HTTPS_PORT:-12443}}"
export TRINO_TLS_VERIFY="${TRINO_TLS_VERIFY:-0}"
# Service account (HTTP Basic) untuk service/pipeline. Password di-hash (bcrypt)
# ke config/trino/password.db oleh bootstrap.sh/install.sh — pra-syarat: htpasswd.
export TRINO_SVC_SEED_PASSWORD="${TRINO_SVC_SEED_PASSWORD:-svc_seed_dev}"
export TRINO_SVC_DBT_PASSWORD="${TRINO_SVC_DBT_PASSWORD:-svc_dbt_dev}"
export TRINO_SVC_AIRFLOW_PASSWORD="${TRINO_SVC_AIRFLOW_PASSWORD:-svc_airflow_dev}"
export TRINO_SVC_OM_PASSWORD="${TRINO_SVC_OM_PASSWORD:-svc_om_dev}"
# ─── StarRocks (Phase 4 — Serving) ──────────────────────────────────────────
export STARROCKS_VERSION="${STARROCKS_VERSION:-4.0.13}"
export STARROCKS_FE_PORT="${STARROCKS_FE_PORT:-12930}"
export STARROCKS_HTTP_PORT="${STARROCKS_HTTP_PORT:-12030}"
# Endpoint dari sisi HOST (gate verifikasi + bootstrap step 5). Untuk StarRocks
# EXISTING: STARROCKS_HOST=starrocks.corp (dan STARROCKS_PORT=9030, port MySQL
# StarRocks — bukan port publish compose 12930).
export STARROCKS_HOST="${STARROCKS_HOST:-localhost}"
export STARROCKS_PORT="${STARROCKS_PORT:-${STARROCKS_FE_PORT:-12930}}"
# ─── Airflow (Phase 5 — Ingestion) ──────────────────────────────────────────
export AIRFLOW_VERSION="${AIRFLOW_VERSION:-3.3.2}"
export AIRFLOW_PORT="${AIRFLOW_PORT:-12082}"
# Endpoint dari sisi HOST (gate Fase 5, test-verification). Untuk Airflow
# EXISTING: AIRFLOW_HOST=airflow.corp (+ AIRFLOW_PORT sesuai) → install.sh tidak
# menyalakan service Airflow, dan uji container menjadi SKIP.
export AIRFLOW_HOST="${AIRFLOW_HOST:-localhost}"
# Secret key untuk JWT internal Airflow (task runner auth) — WAJIB sama di semua container
export AIRFLOW_SECRET_KEY="${AIRFLOW_SECRET_KEY:-sicabe_airflow_jwt_DevOnly_0123456789abcdef}"
export AIRFLOW_DB="${AIRFLOW_DB:-airflow}"
export AIRFLOW_DB_USER="${AIRFLOW_DB_USER:-airflow}"
export AIRFLOW_DB_HOST="${AIRFLOW_DB_HOST:-postgres}"
export AIRFLOW_EXECUTOR="${AIRFLOW_EXECUTOR:-LocalExecutor}"
# Image Airflow kustom. Sejak OM 2.0.2 image ini memuat extra
# `openmetadata-ingestion[airflow]` + plugin `openmetadata-managed-apis` yang
# disajikan di /pluginsv2/ — inilah yang menghidupkan tombol "Test Connection"
# di UI OpenMetadata (§8.11). Tag lama `3.3.1-slim` (tanpa plugin) tetap ada
# sebagai jalur rollback: set AIRFLOW_IMAGE=sicabe/airflow:3.3.1-slim.
# BATCH B (review R18, 2026-10-01): naik ke 3.3.2 (OM 2.0.3 mem-pin Airflow 3.3.2).
# Jalur rollback: sicabe/airflow:3.3.1-om202 (atau 3.3.1-om202-presqlalchemy).
# ⚠️ Image 3.3.2 di Python 3.13 DITOLAK pada uji go/no-go B3 (dbt mati) — yang
# dipakai adalah varian Python 3.11. Lihat deploy/output/b3-hasil-uji.md.
# 2026-10-02: tag `-ol` = 3.3.2 + provider **OpenLineage** (permintaan pemilik
# proyek). Provider itu INERT tanpa backend OpenLineage (belum ada di stack) —
# jadi ini mengaktifkan kemampuan, belum menghasilkan lineage.
# Rollback: sicabe/airflow:3.3.2-om203 (tanpa OpenLineage).
export AIRFLOW_IMAGE="${AIRFLOW_IMAGE:-sicabe/airflow:3.3.2-om203-ol}"
# ─── Image refs yang bisa diarahkan ke MIRROR/registry internal ──────────────
# Repositori asal bisa berubah kebijakan: mis. image community MinIO kini menuntut
# autentikasi → `pull` anonim GAGAL ("unauthorized"). Arahkan ke registry/mirror
# internal via var FULL-IMAGE di bawah, TANPA menyunting docker-compose.yml.
# Bila var ini tidak diset, default dibangun dari *_VERSION di atas (perilaku lama).
export MINIO_IMAGE="${MINIO_IMAGE:-quay.io/minio/minio:${MINIO_VERSION}}"
export MINIO_MC_IMAGE="${MINIO_MC_IMAGE:-quay.io/minio/mc:${MINIO_MC_VERSION}}"
export NESSIE_IMAGE="${NESSIE_IMAGE:-ghcr.io/projectnessie/nessie:${NESSIE_VERSION}}"
# ─── OpenLineage → OpenMetadata (eksperimen experiments/lineage-airflow-om) ──
# Provider OpenLineage sudah terpasang di image di atas, tetapi INERT sampai
# diarahkan ke OpenMetadata. Konfigurasi transport dibaca dari KONEKSI Airflow
# `openlineage_config` (bukan dari env) supaya token lineage TIDAK perlu
# ditulis di deploy/.env — lihat blok koneksi di bootstrap.sh.
#
# AKTIF sejak 2026-10-02 (adopsi opsi C — keputusan pemilik proyek).
# ⚠️ PRASYARAT: koneksi `openlineage_config` + `openmetadata_lineage_api` harus
# SUDAH ADA. Pemuatan konfigurasi provider TIDAK dibungkus try/except, jadi
# bila CONFIG_CONN_ID diisi sedangkan koneksinya belum ada, task dapat GAGAL.
# Koneksi dibuat oleh `./bootstrap.sh` (langkah "Setup connections").
# Mematikan kembali : AIRFLOW_OPENLINEAGE_CONFIG_CONN_ID= (kosongkan).
export AIRFLOW_OPENLINEAGE_CONFIG_CONN_ID="${AIRFLOW_OPENLINEAGE_CONFIG_CONN_ID:-openlineage_config}"
# Namespace job OpenLineage — label asal job; tidak memengaruhi pemetaan tabel
# (pemetaan tabel berjalan otomatis lewat nama dataset + service OM).
export AIRFLOW_OPENLINEAGE_NAMESPACE="${AIRFLOW_OPENLINEAGE_NAMESPACE:-airflow_sicabe}"
export AIRFLOW__CORE__PARALLELISM="${AIRFLOW__CORE__PARALLELISM:-4}"
# Catatan (R18/A2): AIRFLOW_CONN_MINIO_ACCESS_KEY & AIRFLOW_CONN_MINIO_SECRET_KEY
# DIHAPUS dari berkas ini. Keduanya tidak pernah dikonsumsi skrip/compose mana pun
# (diverifikasi dengan grep seluruh repo) dan nilainya TIDAK SAH untuk MinIO
# produksi — pengujian langsung di experiments/airflow332 menghasilkan
# SignatureDoesNotMatch (access key `minioadmin`, sedangkan secret-nya hanya
# 10 karakter padahal password root 32 karakter).
# Jalur resmi kredensial MinIO adalah S3_ACCESS_KEY / S3_SECRET_KEY dengan
# fallback saat-pakai ke MINIO_ROOT_* (lihat blok "S3 / MinIO" di atas) — itulah
# yang dipakai bootstrap.sh untuk membangun connection `minio_s3`, dan cara itu
# sudah terverifikasi bekerja. Ini sekaligus menutup item R02-L4.
# Catatan: AIRFLOW_CONN_TRINO_HOST/PORT DIHAPUS pada review Fase 5 — tidak pernah
# dikonsumsi skrip/compose mana pun, dan connection 'trino_default' yang dulu
# dibangun darinya sudah tidak disediakan (tidak dipakai DAG; versi lamanya
# menunjuk http://trino:8080 tanpa kredensial → 403). Lihat §7.6.
# ─── OpenMetadata (Phase 6 — Governance: Metadata) ─────────────────────────
# BATCH B (review R18): 2.0.2 -> 2.0.3 (wajib seversi dengan openmetadata-ingestion
# di image Airflow). Migrasi OM bersifat SATU ARAH — rollback = pulihkan dump
# (lihat deploy/output/merge-airflow332-rollback.md).
export OPENMETADATA_VERSION="${OPENMETADATA_VERSION:-2.0.3}"
export OPENMETADATA_PORT="${OPENMETADATA_PORT:-12085}"
export OPENMETADATA_DB="${OPENMETADATA_DB:-openmetadata_db}"
export OPENMETADATA_DB_USER="${OPENMETADATA_DB_USER:-openmetadata}"
# Endpoint dari sisi HOST (gate Fase 6, bootstrap step 7, test-verification).
# Untuk OpenMetadata EXISTING: OPENMETADATA_URL=http://om.corp:8585
export OPENMETADATA_URL="${OPENMETADATA_URL:-http://localhost:${OPENMETADATA_PORT:-12085}}"
# ─── Grafana (Phase 6 — Governance: Observability) ─────────────────────────
export GRAFANA_VERSION="${GRAFANA_VERSION:-13.1}"
export GRAFANA_PORT="${GRAFANA_PORT:-12300}"
# Endpoint dari sisi HOST. Untuk Grafana EXISTING: GRAFANA_URL=http://grafana.corp:3000
export GRAFANA_URL="${GRAFANA_URL:-http://localhost:${GRAFANA_PORT:-12300}}"
# Prometheus — sumber metrik untuk datasource Grafana (fase 6).
export PROMETHEUS_VERSION="${PROMETHEUS_VERSION:-v3.6.0}"
export PROMETHEUS_PORT="${PROMETHEUS_PORT:-12090}"
# statsd-exporter — metrik Airflow (StatsD/UDP 9125) → Prometheus :9102 (M2 observabilitas).
export STATSD_EXPORTER_VERSION="${STATSD_EXPORTER_VERSION:-v0.28.0}"
export STATSD_EXPORTER_PORT="${STATSD_EXPORTER_PORT:-12091}"
# jmx-exporter — saturasi Trino (JMX RMI) → Prometheus :9404 (M3 observabilitas).
export JMX_EXPORTER_VERSION="${JMX_EXPORTER_VERSION:-latest}"
# ─── Port tambahan hasil merge eksperimen (Fase 3-6) ────────────────────────
export OPENSEARCH_PORT="${OPENSEARCH_PORT:-12920}"
export OPA_VERSION="${OPA_VERSION:-1.20.2}"
export OPA_PORT="${OPA_PORT:-12181}"
# Endpoint OPA dari sisi HOST (gate verifikasi + bootstrap step 4). Untuk OPA
# EXISTING: OPA_URL=http://opa.corp:8181 (policy path tetap /v1/data/trino/allow).
export OPA_URL="${OPA_URL:-http://localhost:${OPA_PORT:-12181}}"
export OPENLDAP_PORT="${OPENLDAP_PORT:-12389}"
export DREMIO_UI_PORT="${DREMIO_UI_PORT:-12947}"
export DREMIO_JDBC_PORT="${DREMIO_JDBC_PORT:-12010}"
export DREMIO_FLIGHT_PORT="${DREMIO_FLIGHT_PORT:-12011}"
# ─── Endpoint IAM (Keycloak & OpenLDAP) ─────────────────────────────────────
# Default = container lokal hasil deploy ini. Untuk memakai IAM EXISTING,
# override di .env (tiga variabel):
#
# KEYCLOAK_URL=http://kc.internal:8080 # dijangkau dari HOST (bootstrap/verify)
# LDAP_URL=ldap://ldap.internal:389 # dijangkau dari CONTAINER (Trino & StarRocks)
# LDAP_HOST=ldap.internal # dijangkau dari HOST (bootstrap/verify)
# LDAP_PORT=389
#
# Dua alamat diperlukan karena pada mode lokal hostname-nya berbeda:
# container melihat `openldap:389`, host melihat `localhost:12389`.
export KEYCLOAK_URL="${KEYCLOAK_URL:-http://localhost:${KEYCLOAK_PORT:-12080}}"
export LDAP_URL="${LDAP_URL:-ldap://openldap:389}"
export LDAP_HOST="${LDAP_HOST:-localhost}"
export LDAP_PORT="${LDAP_PORT:-${OPENLDAP_PORT:-12389}}"
# Dremio admin dibuat otomatis oleh bootstrap.sh (Step 9) via REST API first-run,
# lalu dipakai script scripts/dremio/register-nessie-source.sh untuk source Nessie.
export DREMIO_URL="${DREMIO_URL:-http://localhost:12947}"
# ─── Port INTERNAL (container ↔ container) — bisa diparameterkan ─────────────
# Port yang dipakai ANTAR-container untuk menjangkau layanan; default = port
# container standar. Ubah HANYA bila layanan yang dipakai berjalan di port berbeda
# (mis. Keycloak/Postgres EXISTING) — cukup di .env, TANPA menyunting docker-compose.yml.
# Layanan milik cluster sendiri selalu memakai DEFAULT ini (hostname service + port container),
# jadi mengubahnya hanya relevan untuk layanan eksternal berport non-standar.
export POSTGRES_INTERNAL_PORT="${POSTGRES_INTERNAL_PORT:-5432}"
export KEYCLOAK_INTERNAL_PORT="${KEYCLOAK_INTERNAL_PORT:-8080}"
export MINIO_INTERNAL_PORT="${MINIO_INTERNAL_PORT:-9000}"
export NESSIE_INTERNAL_PORT="${NESSIE_INTERNAL_PORT:-19120}"
export OPENLDAP_INTERNAL_PORT="${OPENLDAP_INTERNAL_PORT:-389}"
export OPA_INTERNAL_PORT="${OPA_INTERNAL_PORT:-8181}"
# ─── Komponen EXISTING (dikelola sistem lain) ────────────────────────────────
# Bila sebuah komponen sudah dikelola sistem lain, container-nya TIDAK perlu
# (dan tidak boleh) dinyalakan oleh deploy ini. install.sh menyimpulkan ini
# secara OTOMATIS dari endpoint di atas: bila nilainya berbeda dari nilai lokal
# docker-compose.yml, komponen itu dianggap eksternal.
#
# keycloak lokal http://localhost:12080 → jadikan eksternal: KEYCLOAK_URL
# openldap lokal ldap://openldap:389 → LDAP_URL
# minio lokal http://minio:9000 → S3_ENDPOINT (+ minio-init dilewati)
# nessie lokal http://nessie:19120 → NESSIE_URL
# trino lokal https://localhost:12443 → TRINO_URL
# opa lokal http://localhost:12181 → OPA_URL
#
# Postgres tidak punya variabel endpoint → set eksplisit bila dikelola DBA.
# EXTERNAL_SERVICES menang atas auto-deteksi; LOCAL_SERVICES memaksa kembali lokal.
# Nama service mengikuti docker-compose.yml (mis. starrocks-fe, airflow-webserver).
export EXTERNAL_SERVICES="${EXTERNAL_SERVICES:-}"
export LOCAL_SERVICES="${LOCAL_SERVICES:-}"
export DREMIO_USER="${DREMIO_USER:-admin}"
export DREMIO_PASSWORD="${DREMIO_PASSWORD:-dremio_admin_DevOnly1}"
export DREMIO_ADMIN_EMAIL="${DREMIO_ADMIN_EMAIL:-admin@sicabe.local}"
# ─── StarRocks credentials (root + aplikasi) ────────────────────────────────
export STARROCKS_ROOT_PASSWORD="${STARROCKS_ROOT_PASSWORD:-starrocks_root_DevOnly}"
export STARROCKS_APP_PASSWORD="${STARROCKS_APP_PASSWORD:-starrocks_app_DevOnly}"