mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-09 21:10:59 +00:00
fix(compose): replace ${VAR:?required} with entrypoint validation (1.3.1)
The ${VAR:?error} syntax in docker-compose.yml broke Coolify-style
deploys: that platform parses the compose file eagerly and stores the
fallback error string as the env-var value when the var is unset, which
then propagates into DATABASE_URL and breaks the running app with
P1000 auth failures.
Switched to plain ${VAR} interpolation. Validation moves into
docker-entrypoint.sh, which checks DATABASE_URL, SESSION_SECRET,
ENCRYPTION_KEY, API_TOKEN_HMAC_KEY before connecting to the database
and exits with a deploy-platform-agnostic error listing the unset vars.
This commit is contained in:
1 parent
0e510944ce
commit
79764d3467
4 files changed
+57
-7
No files matched your search
@@ -1,5 +1,30 @@
|
||||
# Changelog
|
||||
|
||||
## [1.3.1] — 2026-04-27
|
||||
|
||||
### Fixed
|
||||
|
||||
- **Compose env-var validation no longer breaks Coolify-style deploys.**
|
||||
`docker-compose.yml` previously used `${VAR:?required}` shell-parameter
|
||||
syntax for the four secrets and `POSTGRES_PASSWORD`. Some hosting
|
||||
platforms (Coolify in particular) parse compose files eagerly and
|
||||
store the _fallback error string_ (`"POSTGRES_PASSWORD is required"`)
|
||||
as the literal env-var value when `POSTGRES_PASSWORD` was unset,
|
||||
which then collided with `DATABASE_URL` and broke the running app
|
||||
with `P1000: Authentication failed`. Compose now uses plain `${VAR}`
|
||||
interpolation; validation moved into `docker-entrypoint.sh`, which
|
||||
fails fast with a clear stderr message listing the unset variables.
|
||||
|
||||
### Notes
|
||||
|
||||
If you upgraded an existing Compose stack from 1.2.x → 1.3.0 and hit
|
||||
the `POSTGRES_PASSWORD is required` literal-as-value bug, set
|
||||
`POSTGRES_PASSWORD` in your environment to whatever your existing
|
||||
Postgres data volume was originally initialised with (likely
|
||||
`healthlog` if you started from a pre-1.2.1 release), then redeploy.
|
||||
Postgres only honours `POSTGRES_PASSWORD` on first volume init — the
|
||||
existing user keeps the original password regardless of env changes.
|
||||
|
||||
## [1.3.0] — 2026-04-27
|
||||
|
||||
### Added — Body composition + targeted hardening
|
||||
|
||||
+10
-5
@@ -14,11 +14,16 @@ services:
|
||||
ports:
|
||||
- "3000:3000"
|
||||
environment:
|
||||
DATABASE_URL: "postgresql://healthlog:${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required}@db:5432/healthlog?schema=public"
|
||||
# Plain ${VAR} interpolation only — no ${VAR:?error} validation
|
||||
# syntax. Some hosting platforms (e.g. Coolify) parse compose files
|
||||
# eagerly and store the *fallback error string* as the literal value
|
||||
# when the env var is unset, which then breaks the deployment.
|
||||
# Validation is enforced by docker-entrypoint.sh before the app starts.
|
||||
DATABASE_URL: "postgresql://healthlog:${POSTGRES_PASSWORD}@db:5432/healthlog?schema=public"
|
||||
NODE_ENV: production
|
||||
SESSION_SECRET: "${SESSION_SECRET:?SESSION_SECRET is required}"
|
||||
ENCRYPTION_KEY: "${ENCRYPTION_KEY:?ENCRYPTION_KEY is required}"
|
||||
API_TOKEN_HMAC_KEY: "${API_TOKEN_HMAC_KEY:?API_TOKEN_HMAC_KEY is required}"
|
||||
SESSION_SECRET: "${SESSION_SECRET}"
|
||||
ENCRYPTION_KEY: "${ENCRYPTION_KEY}"
|
||||
API_TOKEN_HMAC_KEY: "${API_TOKEN_HMAC_KEY}"
|
||||
NEXT_PUBLIC_APP_URL: "${NEXT_PUBLIC_APP_URL:-http://localhost:3000}"
|
||||
APP_URL: "${APP_URL:-http://localhost:3000}"
|
||||
depends_on:
|
||||
@@ -31,7 +36,7 @@ services:
|
||||
container_name: healthlog-db
|
||||
environment:
|
||||
POSTGRES_USER: healthlog
|
||||
POSTGRES_PASSWORD: "${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required}"
|
||||
POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}"
|
||||
POSTGRES_DB: healthlog
|
||||
volumes:
|
||||
- pgdata:/var/lib/postgresql/data
|
||||
|
||||
+21
-1
@@ -1,6 +1,26 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
# ── Validate required env vars ───────────────────────────────
|
||||
# We do this in the entrypoint instead of in docker-compose.yml's
|
||||
# environment block (which used to use the ${VAR:?error} syntax)
|
||||
# because some hosting platforms parse compose files eagerly and
|
||||
# end up storing the fallback error string as the literal value.
|
||||
# Validating here guarantees a clear, deploy-platform-agnostic
|
||||
# failure message before we touch the database.
|
||||
missing=""
|
||||
for var in DATABASE_URL SESSION_SECRET ENCRYPTION_KEY API_TOKEN_HMAC_KEY; do
|
||||
eval "value=\$$var"
|
||||
if [ -z "$value" ]; then
|
||||
missing="$missing $var"
|
||||
fi
|
||||
done
|
||||
if [ -n "$missing" ]; then
|
||||
echo "HealthLog: ERROR — required env vars not set:$missing" >&2
|
||||
echo "HealthLog: see .env.example for the full list and how to generate each value." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ── Wait for PostgreSQL ──────────────────────────────────────
|
||||
MAX_RETRIES=30
|
||||
RETRY=0
|
||||
@@ -15,7 +35,7 @@ until node -e "
|
||||
" 2>/dev/null; do
|
||||
RETRY=$((RETRY + 1))
|
||||
if [ "$RETRY" -ge "$MAX_RETRIES" ]; then
|
||||
echo "HealthLog: ERROR — Database not reachable after ${MAX_RETRIES}s, aborting."
|
||||
echo "HealthLog: ERROR — Database not reachable after ${MAX_RETRIES}s, aborting." >&2
|
||||
exit 1
|
||||
fi
|
||||
sleep 1
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "healthlog",
|
||||
"version": "1.3.0",
|
||||
"version": "1.3.1",
|
||||
"private": true,
|
||||
"packageManager": "pnpm@10.31.0",
|
||||
"scripts": {
|
||||
|
||||
Reference in new issue
Block a user