# Analisa K3s SatuSehat: Service + Worker ## 1. Paket yang dianalisis | Paket | Fungsi | |---|---| | `service-satusehat-main.zip` | Service/API utama SatuSehat berbasis Go/Gin | | `worker-satusehat-main.zip` | Worker SatuSehat berbasis Go/Gin dan background worker | ## 2. Kesimpulan struktur aplikasi Aplikasi ini menggunakan pola Go multi-stage build. Service utama menjalankan REST API dan gRPC, sedangkan worker menjalankan REST health endpoint sekaligus background worker. | Komponen | Port di K3s | Keterangan | |---|---:|---| | `satusehat-service` | REST `8196`, gRPC `8197` | Service/API utama, dibuka lewat Traefik | | `satusehat-worker` | REST `8080` | Internal-only, tidak diberi ingress | | `redis` | `6379` | Cache internal namespace | ## 3. Pola Kustomize yang dibuat Pola yang dipakai mengikuti referensi QRIS dan SiLARAS, tetapi diubah dari `Secret` menjadi `ConfigMap`: ```yaml configMapGenerator: - name: satusehat-service-env envs: - .env.service.prod - name: satusehat-worker-env envs: - .env.worker.prod - name: redis-env envs: - .env.redis.prod generatorOptions: disableNameSuffixHash: true ``` Deployment membaca env memakai: ```yaml envFrom: - configMapRef: name: satusehat-service-env ``` ## 4. Perubahan penting dari source ke K3s 1. Baris env yang tidak valid untuk Kustomize dibuang, terutama komentar `// ...` dan baris bebas seperti `untuk vclaim`. 2. Duplikasi `APP_ENV` dinormalisasi menjadi `APP_ENV=production`. 3. Worker dinormalisasi ke port `8080` karena Dockerfile worker terbaru mengekspos `8080`. 4. Worker diarahkan ke service internal K3s: `http://satusehat-service-prod/api/v1/`. 5. Redis dibuat sebagai komponen internal K3s agar `CACHE_REDIS_HOST` tidak menggantung ke service eksternal. ## 5. Env yang dibaca service Nilai sensitif disamarkan di laporan ini. Nilai asli ada di file env hasil generate sesuai source yang Anda kirim. | Key | Value | |---|---| | `APP_ENV` | `production` | | `GIN_MODE` | `release` | | `LOGGER_LEVEL` | `info` | | `LOGGER_FORMAT` | `text` | | `SERVER_PORT` | `8196` | | `SERVER_REST_ENABLED` | `true` | | `SERVER_REST_PORT` | `8196` | | `SERVER_GRPC_ENABLED` | `true` | | `SERVER_GRPC_PORT` | `8197` | | `CACHE_REDIS_HOST` | `redis-prod` | | `CACHE_REDIS_PORT` | `6379` | | `REDIS_PASSWORD` | `***REDACTED***` | | `AUTH_TYPE` | `hybrid` | | `AUTH_STATIC_TOKENS` | `***REDACTED***` | | `AUTH_FALLBACK_TO` | `jwt` | | `KEYCLOAK_CLIENT_ID` | `***REDACTED***` | | `KEYCLOAK_CLIENT_SECRET` | `***REDACTED***` | | `KEYCLOAK_ISSUER` | `***REDACTED***` | | `KEYCLOAK_URL` | `***REDACTED***` | | `KEYCLOAK_REALM` | `***REDACTED***` | | `KEYCLOAK_AUDIENCE` | `***REDACTED***` | | `KEYCLOAK_JWKS_URL` | `***REDACTED***` | | `KEYCLOAK_ENABLED` | `***REDACTED***` | | `POSTGRES_DEFAULT_HOST` | `10.10.123.198` | | `POSTGRES_DEFAULT_PORT` | `5100` | | `POSTGRES_DEFAULT_USERNAME` | `***REDACTED***` | | `POSTGRES_DEFAULT_PASSWORD` | `***REDACTED***` | | `POSTGRES_DEFAULT_DATABASE` | `db_farmasi` | | `POSTGRES_DEFAULT_SSLMODE` | `disable` | | `POSTGRES_DEFAULT_TIMEOUT` | `5s` | | `POSTGRES_SIMRS_HOST` | `10.10.123.238` | | `POSTGRES_SIMRS_PORT` | `5432` | | `POSTGRES_SIMRS_USERNAME` | `***REDACTED***` | | `POSTGRES_SIMRS_PASSWORD` | `***REDACTED***` | | `POSTGRES_SIMRS_DATABASE` | `simrs` | | `POSTGRES_SIMRS_SSLMODE` | `disable` | | `POSTGRES_SIMRS_TIMEOUT` | `5s` | | `POSTGRES_SATUDATA_CONNECTION` | `postgres` | | `POSTGRES_SATUDATA_HOST` | `10.10.123.165` | | `POSTGRES_SATUDATA_PORT` | `5000` | | `POSTGRES_SATUDATA_USERNAME` | `***REDACTED***` | | `POSTGRES_SATUDATA_PASSWORD` | `***REDACTED***` | | `POSTGRES_SATUDATA_DATABASE` | `satu_db` | | `POSTGRES_SATUDATA_SSLMODE` | `disable` | | `POSTGRES_SATUDATA_TIMEOUT` | `5s` | | `SQLSERVER_FARMASI_CONNECTION` | `sqlserver` | | `SQLSERVER_FARMASI_USERNAME` | `***REDACTED***` | | `SQLSERVER_FARMASI_PASSWORD` | `***REDACTED***` | | `SQLSERVER_FARMASI_HOST` | `10.10.90.232` | | `SQLSERVER_FARMASI_DATABASE` | `DBINV` | | `SQLSERVER_FARMASI_PORT` | `1433` | | `SQLSERVER_FARMASI_SSLMODE` | `disable` | | `SQLSERVER_FARMASI_TIMEOUT` | `5s` | | `MYSQL_RIS_CONNECTION` | `mysql` | | `MYSQL_RIS_USERNAME` | `***REDACTED***` | | `MYSQL_RIS_PASSWORD` | `***REDACTED***` | | `MYSQL_RIS_HOST` | `10.10.123.141` | | `MYSQL_RIS_PORT` | `3306` | | `MYSQL_RIS_DATABASE` | `fk_radiology` | | `MYSQL_RIS_TIMEOUT` | `5s` | | `BPJS_ENABLED` | `true` | | `BPJS_KDPPK` | `1323A036` | | `BPJS_CONSID` | `***REDACTED***` | | `BPJS_SECRETKEY` | `***REDACTED***` | | `BPJS_BASEURL` | `https://apijkn-dev.bpjs-kesehatan.go.id` | | `BPJS_SERVICE_NAME` | `vclaim-rest-dev` | | `BPJS_APOTEK_CONSID` | `***REDACTED***` | | `BPJS_APOTEK_SECRETKEY` | `***REDACTED***` | | `BPJS_VCLAIM_USERKEY` | `***REDACTED***` | | `BPJS_ANTROL_USERKEY` | `***REDACTED***` | | `BPJS_IHS_USERKEY` | `***REDACTED***` | | `BPJS_APOTEK_USERKEY` | `***REDACTED***` | | `SATUSEHAT_ENABLED` | `true` | | `SATUSEHAT_ORG_ID` | `100026555` | | `SATUSEHAT_FASYAKES_ID` | `3573011` | | `SATUSEHAT_CLIENT_ID` | `***REDACTED***` | | `SATUSEHAT_CLIENT_SECRET` | `***REDACTED***` | | `SATUSEHAT_AUTH_URL` | `https://api-satusehat.kemkes.go.id/oauth2/v1` | | `SATUSEHAT_BASE_URL` | `https://api-satusehat.kemkes.go.id/fhir-r4/v1` | | `SATUSEHAT_CONSENT_URL` | `https://api-satusehat.kemkes.go.id/consent/v1` | | `SATUSEHAT_KFA_URL` | `https://api-satusehat.kemkes.go.id/kfa-v2` | | `SATUSEHAT_KYC_URL` | `https://api-satusehat.kemkes.go.id/kyc/v1` | | `SATUSEHAT_KYC_CHALLENGE_CODE_URL` | `https://api-satusehat.kemkes.go.id/kyc/v1/challenge-code` | | `SATUSEHAT_WEBHOOK_SECRET` | `***REDACTED***` | | `SATUSEHAT_DICOM_URL` | `https://api-satusehat.kemkes.go.id/dicom/v1/dicomWeb/studies` | | `KYC_PRIVATE_KEY_B64` | `***REDACTED***` | | `KYC_PUBLIC_KEY_B64` | `***REDACTED***` | | `SWAGGER_HOST` | `satusehat-service.rssa.id` | | `CORS_ORIGINS` | `http://localhost:3000,http://localhost:3001,http://localhost:3002,http://localhost:3005,http://meninjar.dev.rssa.id:8198,http://localhost:8080,http://localhost:5173,http://localhost:5174,http://10.10.123.143:3001` | | `CORS_ALLOW_ALL` | `false` | | `MINIO_ENDPOINT` | `http://10.10.123.8:9000` | | `MINIO_ACCESSKEY` | `***REDACTED***` | | `MINIO_SECRETKEY` | `***REDACTED***` | | `MINIO_USESSL` | `false` | | `MINIO_BUCKETNAME` | `dev-test` | | `CACHE_ENABLED` | `true` | | `SWAGGER_BASE_PATH` | `/api/v1` | | `SWAGGER_SCHEMES` | `https` | ## 6. Env yang dibaca worker | Key | Value | |---|---| | `APP_ENV` | `production` | | `GIN_MODE` | `release` | | `LOGGER_LEVEL` | `info` | | `LOGGER_FORMAT` | `text` | | `SERVER_PORT` | `8080` | | `SATU_SEHAT_INTERNAL_FHIR_SERVER_URL` | `http://satusehat-service-prod/api/v1/` | | `AUTH_TYPE` | `hybrid` | | `AUTH_STATIC_TOKENS` | `***REDACTED***` | | `AUTH_FALLBACK_TO` | `jwt` | | `KEYCLOAK_CLIENT_ID` | `***REDACTED***` | | `KEYCLOAK_CLIENT_SECRET` | `***REDACTED***` | | `KEYCLOAK_ISSUER` | `***REDACTED***` | | `KEYCLOAK_URL` | `***REDACTED***` | | `KEYCLOAK_REALM` | `***REDACTED***` | | `KEYCLOAK_AUDIENCE` | `***REDACTED***` | | `KEYCLOAK_JWKS_URL` | `***REDACTED***` | | `KEYCLOAK_ENABLED` | `***REDACTED***` | | `POSTGRES_DEFAULT_HOST` | `10.10.123.198` | | `POSTGRES_DEFAULT_PORT` | `5100` | | `POSTGRES_DEFAULT_USERNAME` | `***REDACTED***` | | `POSTGRES_DEFAULT_PASSWORD` | `***REDACTED***` | | `POSTGRES_DEFAULT_DATABASE` | `db_farmasi` | | `POSTGRES_DEFAULT_SSLMODE` | `disable` | | `POSTGRES_DEFAULT_TIMEOUT` | `5s` | | `POSTGRES_SIMRS_HOST` | `10.10.123.163` | | `POSTGRES_SIMRS_PORT` | `5432` | | `POSTGRES_SIMRS_USERNAME` | `***REDACTED***` | | `POSTGRES_SIMRS_PASSWORD` | `***REDACTED***` | | `POSTGRES_SIMRS_DATABASE` | `simrs` | | `POSTGRES_SIMRS_SSLMODE` | `disable` | | `POSTGRES_SIMRS_TIMEOUT` | `5s` | | `POSTGRES_SATUDATA_CONNECTION` | `postgres` | | `POSTGRES_SATUDATA_HOST` | `10.10.123.165` | | `POSTGRES_SATUDATA_PORT` | `5000` | | `POSTGRES_SATUDATA_USERNAME` | `***REDACTED***` | | `POSTGRES_SATUDATA_PASSWORD` | `***REDACTED***` | | `POSTGRES_SATUDATA_DATABASE` | `satu_db` | | `POSTGRES_SATUDATA_SSLMODE` | `disable` | | `POSTGRES_SATUDATA_TIMEOUT` | `5s` | | `SQLSERVER_FARMASI_CONNECTION` | `sqlserver` | | `SQLSERVER_FARMASI_USERNAME` | `***REDACTED***` | | `SQLSERVER_FARMASI_PASSWORD` | `***REDACTED***` | | `SQLSERVER_FARMASI_HOST` | `10.10.90.232` | | `SQLSERVER_FARMASI_DATABASE` | `DBINV` | | `SQLSERVER_FARMASI_PORT` | `1433` | | `SQLSERVER_FARMASI_SSLMODE` | `disable` | | `SQLSERVER_FARMASI_TIMEOUT` | `5s` | | `MYSQL_RIS_CONNECTION` | `mysql` | | `MYSQL_RIS_USERNAME` | `***REDACTED***` | | `MYSQL_RIS_PASSWORD` | `***REDACTED***` | | `MYSQL_RIS_HOST` | `10.10.123.141` | | `MYSQL_RIS_PORT` | `3306` | | `MYSQL_RIS_DATABASE` | `fk_radiology` | | `MYSQL_RIS_TIMEOUT` | `5s` | | `SERVER_REST_ENABLED` | `true` | | `SERVER_REST_PORT` | `8080` | | `SERVER_GRPC_ENABLED` | `false` | | `SERVER_GRPC_PORT` | `8099` | | `CACHE_REDIS_HOST` | `redis-prod` | | `CACHE_REDIS_PORT` | `6379` | | `REDIS_PASSWORD` | `***REDACTED***` | | `BPJS_ENABLED` | `true` | | `BPJS_KDPPK` | `1323A036` | | `BPJS_CONSID` | `***REDACTED***` | | `BPJS_SECRETKEY` | `***REDACTED***` | | `BPJS_BASEURL` | `https://apijkn-dev.bpjs-kesehatan.go.id` | | `BPJS_SERVICE_NAME` | `vclaim-rest-dev` | | `BPJS_APOTEK_CONSID` | `***REDACTED***` | | `BPJS_APOTEK_SECRETKEY` | `***REDACTED***` | | `BPJS_VCLAIM_USERKEY` | `***REDACTED***` | | `BPJS_ANTROL_USERKEY` | `***REDACTED***` | | `BPJS_IHS_USERKEY` | `***REDACTED***` | | `BPJS_APOTEK_USERKEY` | `***REDACTED***` | | `SATUSEHAT_ENABLED` | `true` | | `SATUSEHAT_ORG_ID` | `100026555` | | `SATUSEHAT_FASYAKES_ID` | `3573011` | | `SATUSEHAT_CLIENT_ID` | `***REDACTED***` | | `SATUSEHAT_CLIENT_SECRET` | `***REDACTED***` | | `SATUSEHAT_AUTH_URL` | `https://api-satusehat.kemkes.go.id/oauth2/v1` | | `SATUSEHAT_BASE_URL` | `https://api-satusehat.kemkes.go.id/fhir-r4/v1` | | `SATUSEHAT_CONSENT_URL` | `https://api-satusehat.dto.kemkes.go.id/consent/v1` | | `SATUSEHAT_KFA_URL` | `https://api-satusehat.kemkes.go.id/kfa-v2` | | `SWAGGER_HOST` | `satusehat-worker.rssa.id` | | `CORS_ORIGINS` | `http://localhost:3000,http://localhost:3001,http://localhost:3002,http://localhost:3005,http://meninjar.dev.rssa.id:8093,http://localhost:8080,http://localhost:5173,http://localhost:5174,http://10.10.123.143:3001,http://10.10.123.147:8098` | | `CORS_ALLOW_ALL` | `false` | | `MINIO_ENDPOINT` | `http://10.10.123.8:9000` | | `MINIO_ACCESSKEY` | `***REDACTED***` | | `MINIO_SECRETKEY` | `***REDACTED***` | | `MINIO_USESSL` | `false` | | `MINIO_BUCKETNAME` | `dev-test` | | `CACHE_ENABLED` | `true` | | `SWAGGER_BASE_PATH` | `/api/v1` | | `SWAGGER_SCHEMES` | `https` | ## 7. Catatan validasi env source Service env source memiliki 3 baris tidak valid untuk format env Kustomize. Worker env source memiliki 3 baris tidak valid. Baris tersebut tidak dimasukkan ke `.env.*.prod` agar `kubectl apply -k` tidak gagal. Contoh jenis baris yang dibuang: ```text // komentar gaya JS untuk vclaim untuk IHS untuk Apotek ``` ## 8. File output Manifest final tersedia pada folder: ```text satusehat-k3s/ ``` Paket siap kirim tersedia sebagai ZIP: ```text satusehat-k3s-kustomize-env-nosecret.zip ```