Environment variables reference
Always inject secrets as runtime env (compose environment: / Synology Container Manager environment). The root .env is gitignored and dockerignored, so it is not baked into the image.
Required
| Variable | Description |
|---|---|
DATABASE_URL | Postgres connection string (postgres://bebe:<pw>@postgres:5432/bebe). |
REDIS_URL | Queue connection string (redis://redis:6379). |
SECRET_KEY | Session/encryption key. 32+ bytes (openssl rand -hex 32). |
PUBLIC_URL | Public external URL (https://bebe.example.com). The media base URL also falls back to this. |
Media-service secrets (required)
Used by the web and media processes inside the app image to authenticate and sign with each other. If missing, photo pages return 500.
| Variable | Description |
|---|---|
MEDIA_SERVICE_TOKEN | web → media bearer token. 32+ bytes (openssl rand -hex 32). |
MEDIA_JWT_SECRET | Signing key for file-serve / upload tokens. 32+ bytes (generated separately). |
DB role split
The entrypoint creates the bebe_web / bebe_media roles with these passwords. web touches only the public schema, media only the media schema.
| Variable | Description |
|---|---|
DATABASE_URL_WEB | For the web process (bebe_web role). |
DATABASE_URL_MEDIA | For the media process (bebe_media role). |
BEBE_WEB_DB_PASSWORD | Password for the bebe_web role. |
BEBE_MEDIA_DB_PASSWORD | Password for the bebe_media role. |
Media base URL (usually unset)
| Variable | Description |
|---|---|
MEDIA_INTERNAL_URL | Internal media address inside the container. Single container, so http://localhost:3001. |
MEDIA_PUBLIC_BASE_URL | Browser-facing media base. Usually unset → falls back to PUBLIC_URL. Do not put an unexposed port like :3001. |
NEXT_PUBLIC_MEDIA_BASE_URL | Same as above. Unset (or equal to PUBLIC_URL) is correct. |
Optional
| Variable | Default | Description |
|---|---|---|
PORT | 3000 | Exposed port. Avoids Synology's 5000/5001. |
TZ | Asia/Seoul | Quiet hours / digest / memory pushes use container-local time, so set the family timezone. |
PUID / PGID | 1000 (DSM example 1026/100) | Volume ownership. On Synology, check with id <user>. |
ADMIN_USER_EMAIL | — | Instance admin email(s) (comma-separated). In the single-family model the first owner is already the admin. |
STORAGE_MODE | local | local or s3. |
STORAGE_PATH | /data | Local storage path (the mounted volume). |
STORAGE_S3_* | — | Endpoint / bucket / keys when using S3/MinIO. |
BACKUP_DIR | /backups | Where app backup bundles are written. |
FACE_ML_URL | http://ml:8000 | Face-recognition ML sidecar address (opt-in). If the ml container isn't running, it's never called. |
LOG_LEVEL | info | pino log level. |
Runtime settings (OIDC, SMTP, retention, etc.) are configured in the in-app admin UI, not via env. If a value is provided via env, the UI is locked.