-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy path.env.dockercompose.example
More file actions
181 lines (170 loc) · 9.7 KB
/
Copy path.env.dockercompose.example
File metadata and controls
181 lines (170 loc) · 9.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# =============================================================================
# Huella Latam — docker-compose environment
# =============================================================================
# Quick start:
# cp .env.dockercompose.example .env.dockercompose
# docker compose --env-file .env.dockercompose up --build
#
# This file holds LOCAL-DEV defaults that work out of the box. For staging /
# production, override the marked values (JWT_SECRET, AUTH_PROVIDER + Azure
# vars, NODE_ENV, storage). `.env.dockercompose` is gitignored; this template
# (`.env.dockercompose.example`) is committed.
#
# Note: docker-compose only auto-loads a file literally named `.env`. Since this
# file has a descriptive name, pass it explicitly with `--env-file`.
#
# ⚠️ Variable precedence: docker-compose interpolation uses
# shell env > --env-file > defaults
# If you use direnv (.envrc) with exports for `pnpm dev` (e.g. VITE_*,
# JWT_SECRET), those exports SILENTLY OVERRIDE this file. See
# `docs/operations/docker-compose.md` → Troubleshooting → "Compose uses the
# wrong value for a variable" for diagnosis and fixes.
# =============================================================================
# -----------------------------------------------------------------------------
# Database (PostgreSQL container)
# -----------------------------------------------------------------------------
POSTGRES_USER=huella
POSTGRES_PASSWORD=huella
POSTGRES_DB=huella_latam
# Host port to reach Postgres from your machine (container is always 5432)
POSTGRES_PORT_HOST_MAPPING=5432
# -----------------------------------------------------------------------------
# API (core)
# -----------------------------------------------------------------------------
# development = verbose logs + dev-friendly defaults. Use `production` for deploys.
NODE_ENV=development
API_HOST=0.0.0.0
# Host port to reach the API (container always listens on 8080)
API_PORT=8080
LOG_LEVEL=debug
APP_VERSION=local
# CORS: origin allowed to call the API (the web app URL)
ALLOWED_ORIGIN=http://localhost:3000
# Static HMAC secret for the non-JWKS @fastify/jwt branch. The API ships NO
# built-in default (a checked-in secret is a published credential), so this
# dummy value is what makes local dev work. Required when AUTH_PROVIDER=jwks
# has no JWKS_URI; unused once JWKS_URI is set.
# ⚠️ CHANGE IN PRODUCTION — must be a strong secret outside local dev.
JWT_SECRET=dev-only-dummy-secret-change-me
# Relaxes required-field validation for local testing. Keep false in prod.
LOCAL_BYPASS_REQUIRED_FIELDS=false
# -----------------------------------------------------------------------------
# Authentication
# AUTH_PROVIDER: none | forced-user | jwks
# none → API unauthenticated (simplest local boot)
# forced-user → injects a fake user without Azure (set the two vars below)
# jwks → validates OIDC access tokens (Entra, Keycloak, …; set the JWKS block below)
# -----------------------------------------------------------------------------
AUTH_PROVIDER=none
# Required only when AUTH_PROVIDER=forced-user
FORCED_USER_EMAIL=
FORCED_USER_IDP_ID=
# Email promoted to superadmin by the promote-superadmin script (optional)
SUPERADMIN_EMAIL=
# -----------------------------------------------------------------------------
# JWKS — how the API validates access tokens when AUTH_PROVIDER=jwks. The API
# reads these directly (there are no AZURE_* auth vars). A .env file can't do the
# conditional derivation Entra needs (tenant-type branching, plus CIAM's
# GUID-vs-subdomain host split), so:
# • Azure Entra → derive these from your tenant per
# docs/infrastructure/AzureAuthenticationSetup.md (or use the
# .envrc.azure.example direnv helper, which computes them for you).
# • Keycloak → see the example block below.
# -----------------------------------------------------------------------------
JWKS_URI=
JWKS_ISSUER=
JWKS_AUDIENCE=
JWKS_REQUIRED_SCOPE=
JWKS_SKIP_SCOPE_CHECK=
#
# --- Keycloak (generic OIDC) example — local dev with the compose/keycloak-db.yaml + compose/keycloak.dev.yaml overlays ---
# To use Keycloak: set AUTH_PROVIDER=jwks and the JWKS_* values below:
# AUTH_PROVIDER=jwks
# JWKS_ISSUER=http://localhost:18080/realms/huella # = token `iss` (browser-facing host)
# JWKS_URI=http://keycloak:8080/realms/huella/protocol/openid-connect/certs # internal, resolvable from the api container
# JWKS_AUDIENCE=huella-api # requires the realm audience mapper
# JWKS_REQUIRED_SCOPE=access_as_user # default; the realm grants this as a default client scope
# Scope is validated from `scp` (Azure) or `scope` (Keycloak); do NOT set JWKS_SKIP_SCOPE_CHECK.
# And bring up the Keycloak service alongside the base stack via the overlay:
# COMPOSE_FILE=docker-compose.yml:compose/keycloak-db.yaml:compose/keycloak.dev.yaml
# Or pass the same files with `-f`; Keycloak uses host `:18080` and imports
# `huella`/`huella-web` on first boot.
# -----------------------------------------------------------------------------
# Storage provider (REQUIRED — the API refuses to boot if unset)
# Allowed values: azure_blob_storage | minio
# minio → needs the MINIO_* vars and the MinIO service running (bring it up
# by merging the overlay: `-f docker-compose.yml -f docker-compose.minio.yml`).
# azure_blob_storage → needs the AZURE_STORAGE_* block below.
# -----------------------------------------------------------------------------
STORAGE_PROVIDER=minio
# -----------------------------------------------------------------------------
# Azure Blob Storage (optional)
# Leave AZURE_STORAGE_ACCOUNT_NAME empty to disable file upload/download AND
# badge/terms seeding. Set the account name + container to enable.
#
# Identity model — the credential depends on WHERE the app runs, not on
# local-vs-prod. Only Azure-hosted compute has a Managed Identity:
# - On Azure (App Service / Container Apps): leave the 3 vars below empty. The
# API falls back to DefaultAzureCredential → the compute's Managed Identity.
# - Local docker AND on-premise / any non-Azure host: no Managed Identity, so a
# dedicated Service Principal is required — set all 3 vars together (on-prem
# uses production-grade, vault-managed values). They are intentionally separate
# from AZURE_TENANT_ID (used by JWKS) so the SP tenant (Directory tenant where
# storage lives) can differ from the auth tenant (Entra External ID).
# - The SP must have the "Storage Blob Data Contributor" role on the account.
# -----------------------------------------------------------------------------
AZURE_STORAGE_ACCOUNT_NAME=
AZURE_STORAGE_CONTAINER_NAME=
# Dedicated SP for storage (Directory tenant where the storage account lives).
# All three must be set together to take effect.
AZURE_STORAGE_TENANT_ID=
AZURE_STORAGE_CLIENT_ID=
AZURE_STORAGE_CLIENT_SECRET=
# -----------------------------------------------------------------------------
# Chatbot (optional AI feature — DPG optionality)
# -----------------------------------------------------------------------------
# Master switch, off by default platform-wide. Enabled here for local dev with
# the built-in mock provider (no cloud). To enable in a real deployment you must
# also set LLM_PROVIDER=azure-openai + AZURE_OPENAI_ENDPOINT +
# AZURE_OPENAI_DEPLOYMENT_NAME + COOKIE_SECRET (see .envrc.azure.example).
CHATBOT_ENABLED=true
# -----------------------------------------------------------------------------
# Web (Vite) — inlined into the bundle at BUILD time (docker build args).
# Changing these requires rebuilding the web image.
# -----------------------------------------------------------------------------
# Host port to reach the web app
WEB_PORT=3000
# Browser-reachable API URL (host port from API_PORT above)
VITE_API_BASE_URL=http://localhost:8080
VITE_FRONT_BASE_URL=http://localhost:3000
VITE_APP_VERSION=local
VITE_IS_DEMO_APP=false
# Show the optional chatbot widget — mirror of CHATBOT_ENABLED above.
VITE_CHATBOT_ENABLED=true
VITE_LOCAL_BYPASS_REQUIRED_FIELDS=false
# Generic OIDC config for the frontend (build-time; the web image must be rebuilt
# when these change). The web ALWAYS uses OIDC, so ISSUER, CLIENT_ID and SCOPES are
# required — the app fails loud at boot if any is empty. REDIRECT_URI and
# POST_LOGOUT default to the serving origin if left blank.
# VITE_OIDC_SCOPES — space-separated scopes requested from the IdP. Baseline:
# openid → required for OIDC (id_token)
# email → the backend requires the email claim or it rejects the token
# profile → display name for the UI
# offline_access is intentionally NOT requested here: silent renew relies on the
# SSO-session-bound refresh token (8h) instead of a long-lived offline one.
# For Entra External ID, also append the API scope (e.g. "… api://<API_CLIENT_ID>/access_as_user")
# so the access token's aud is the API. Keycloak emits access_as_user as a realm
# default scope, so it is NOT requested here.
# For Keycloak (compose overlay): VITE_OIDC_ISSUER=http://localhost:18080/realms/huella
VITE_OIDC_ISSUER=
VITE_OIDC_CLIENT_ID=huella-web
VITE_OIDC_SCOPES=openid profile email
VITE_OIDC_REDIRECT_URI=
VITE_OIDC_POST_LOGOUT_REDIRECT_URI=
# Browser-facing object-storage origin, baked into the nginx CSP (connect-src/
# img-src) so the browser may PUT/GET presigned URLs. Set it to the storage URL
# the BROWSER uses: the MinIO domain on-prem, or https://<account>.blob.core.windows.net
# in cloud. Leave empty if there are no browser uploads (CSP then omits storage).
# For local MinIO QA set it to the browser-facing presign origin (needs the
# `127.0.0.1 minio` /etc/hosts entry): STORAGE_ORIGIN=http://minio:9000
STORAGE_ORIGIN=