fix(infra): pass pgweb credentials via discrete CLI flags
CI / commits (pull_request) Successful in 1m11s
CI / check (pull_request) Successful in 1m20s
CI / scan (pull_request) Successful in 1m23s
CI / a11y (pull_request) Successful in 1m29s
CI / perf (pull_request) Successful in 3m15s

`PGWEB_DATABASE_URL` (post-#62 rename) still failed at boot with:

    Error: Invalid URL. Valid format:
    postgres://user:password@host:port/db?sslmode=mode

The userinfo portion of a Postgres URL must be URL-encoded —
any `@`, `#`, `:`, `/`, `?`, `%`, `&`, `=`, `+`, `;` etc. in the
password breaks the parser. Compose has no built-in URL encoding,
so the URL we construct in YAML is fragile by design.

Switch to pgweb's discrete CLI flags (`--host`, `--port`, `--user`,
`--pass`, `--db`, `--ssl`). Compose interpolates each value
literally — no URL encoding required, any password works. The
image's ENTRYPOINT already passes `--bind=0.0.0.0 --listen=8081`;
our args are appended to those.

Side benefit: the failure mode for a missing password is now an
explicit Compose error
(`POSTGRES_PASSWORD must be set in infra/local/.env`) rather than
an opaque pgweb crash.
This commit is contained in:
Julien Gautier
2026-05-08 23:11:46 +02:00
parent 10f8565957
commit 1ab8bfb212
+14 -5
View File
@@ -102,11 +102,20 @@ services:
container_name: apf-portal-pgweb container_name: apf-portal-pgweb
restart: unless-stopped restart: unless-stopped
profiles: [dbtools] profiles: [dbtools]
environment: # Use discrete CLI flags rather than `PGWEB_DATABASE_URL`. The URL
# `PGWEB_DATABASE_URL` (formerly `DATABASE_URL`) — pgweb 0.16 # form is fragile: any special character in POSTGRES_PASSWORD
# deprecated the old name, ignores it, and starts up empty, # (`@`, `#`, `:`, `/`, `?`, `%`, `&`, …) breaks the userinfo
# crashing with "Invalid URL". # parser, and the resulting "Invalid URL" error is opaque. Discrete
PGWEB_DATABASE_URL: postgres://${POSTGRES_USER:-portal}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-portal_dev}?sslmode=disable # flags accept any password verbatim. The image's ENTRYPOINT
# already passes `--bind=0.0.0.0 --listen=8081`; these args are
# appended.
command:
- --host=postgres
- --port=5432
- --user=${POSTGRES_USER:-portal}
- --pass=${POSTGRES_PASSWORD:?POSTGRES_PASSWORD must be set in infra/local/.env}
- --db=${POSTGRES_DB:-portal_dev}
- --ssl=disable
ports: ports:
- '${PGWEB_PORT:-8081}:8081' - '${PGWEB_PORT:-8081}:8081'
depends_on: depends_on: