Configuration
Two files, two roles
| File (on the server) | Read by | Effect of a change |
|---|---|---|
~/pch-sig/.env.prod | Docker Compose, injected into the container environment | docker compose -f … up -d --no-deps backend |
~/pch-sig/backend/.env | copied into the image (/app/.env), Symfony defaults | image rebuild required |
Precedence rule: a variable present in the container environment wins over /app/.env, even when empty. Check the value actually in use:
docker exec pch_backend php bin/console debug:dotenv
None of these files is in the Git repository. Secrets live in the secrets manager; their rotation is described in docs/ROTATION_SECRETS.md.
Main variables
| Variable | Where | Role |
|---|---|---|
APP_ENV, APP_DEBUG | compose | prod, 0 |
APP_SECRET | .env.prod | Symfony secret |
POSTGRES_USER, POSTGRES_PASSWORD | .env.prod | pch_sig database |
JWT_PASSPHRASE | .env.prod | JWT key passphrase (backend/config/jwt/, server-specific) |
MAILER_USER, MAILER_PASSWORD | .env.prod | OVH SMTP account noreply@ucp-pch.org; the DSN used is smtp://…@ssl0.ovh.net:587 |
MAILER_SENDER | compose | noreply@ucp-pch.org |
MESSENGER_TRANSPORT_DSN | compose | doctrine://default: queue for e-mails and asynchronous jobs |
REDIS_URL | compose | redis://redis:6379 |
FRONTEND_URL, DEFAULT_URI | compose | https://bemba.ucp-pch.org (links in e-mails, with /#/) |
CORS_ALLOW_ORIGIN | compose | allowed domains |
ANTHROPIC_API_KEY, CLAUDE_MODEL | backend/.env | Bemba assistant (default model set in services.yaml) |
COHERE_API_KEY | backend/.env | assistant semantic search, grievance clustering |
DOCUMENTATION_BUILD_DIR, DOCUMENTATION_URL | compose | assistant document base (Docusaurus build mounted read-only) |
KOBO_API_URL, KOBO_API_TOKEN | compose / .env.prod | KoboToolbox (per-project accounts can also be set in the application) |
SENTRY_DSN | .env.prod | error reporting |
The SUSO_* variables are not used: the Survey Solutions connection is read from the survey_solutions_config table, editable from the application.
Frontend
| File | Used by | Content |
|---|---|---|
frontend/.env.development.local | npm start | REACT_APP_API_URL=http://localhost:8000/api, "LOCAL" badge |
frontend/.env.production | npm run build | REACT_APP_API_URL=/api, REACT_APP_DOCS_URL=https://docubemba.ucp-pch.org |
REACT_APP_* variables are fixed at build time: changing a value means rebuilding and redeploying the frontend.
Frontend Nginx
~/pch-sig/nginx/frontend.conf is mounted in pch_frontend. It serves the React build (HashRouter, every route returns index.html), caches versioned assets and applies the Content Security Policy (CSP): connect-src limited to the domain, KoboToolbox and Sentry. Any third-party service called from the browser must be added to the CSP.
Configuration inside the application
Much of the setup is done under Settings, without redeploying: roles and permissions, institutions and assignments, projects and programmes, PMT methods, identifier nomenclature, grievance workflows and deadlines (Workflow & SLA), teams, Kobo and Survey Solutions accounts per project, public website content.
E-mails
All e-mails are sent asynchronously (Messenger): a request never contacts the SMTP server. Failed messages go to the failed queue:
docker exec pch_backend php bin/console messenger:failed:show
docker exec pch_backend php bin/console messenger:failed:retry # production only
In pre-production, sending fails on purpose (SMTP unreachable): do not retry the failed queue.
Logging
Monolog writes to the container's standard error; Promtail collects these logs and ships them to Loki (one-year retention). See Logs.