Files
bookhoard/.env.example
T
John O'Keefe 313268a7ae feat(deploy): db-init one-shot service — paste-and-go bootstrap for the runtime role
The role split previously required a one-time manual script run on
existing volumes (initdb.d only fires on fresh ones). This folds the
bootstrap into the compose file the way split-account deployments
standardly do it: a one-shot db-init service runs z_rls_role.sh
(idempotent, network mode via PGHOST=db + PGPASSWORD from DBPASS) on
every 'compose up', and the app gates on
db-init: condition: service_completed_successfully.

- Zero manual steps for fresh AND existing deployments: update compose,
  add DBSRVPASS to .env, 'compose pull && up -d'.
- Security posture improves: the superuser password is now held ONLY by
  the init service — the app container connects exclusively as the
  non-superuser runtime role.
- z_rls_role.sh gains dual connection modes (local socket for docker
  exec, network for the init service) with the DBPASS requirement
  enforced only in network mode.
- Verified on the dev stack: init runs and exits clean, app gates on it
  and comes up healthy, second 'up' re-converges idempotently, invariant
  test passes through the new dependency chain.

The initdb.d mount stays as-is (harmless double coverage on fresh
volumes; both paths are idempotent).
2026-10-29 11:17:42 -04:00

51 lines
2.3 KiB
Bash

# Environment Variables
# Copy this file to .env and update the values
# Only secrets are required - all other settings have defaults in docker-compose.yml
# JWT Secret for authentication (generate a secure random string)
# Generate with: openssl rand -hex 32
JWT_SECRET=your-secure-jwt-secret-key-here
# PostgreSQL database password (the bootstrap superuser account; kept
# for container initialization — the app itself connects as bookhoard_srv)
# Generate with: openssl rand -hex 16
DBPASS=your-secure-database-password-here
# Runtime database role password (bookhoard_srv — the non-superuser
# account the app connects as; subject to RLS). Required for the app to
# start. Consumed by the one-shot db-init service on every startup
# (idempotent — creates/refreshes the role and its privileges).
# Generate with: openssl rand -hex 16
DBSRVPASS=your-secure-runtime-role-password-here
# Networking: change a port if it conflicts on your host
# Postgres port, host + container (e.g. another local DB already uses 5432)
# DB_PORT=15432
# App web port, host + container
# SERVER_PORT=8765
# Deployment
# External URL for device sync (must include protocol; defaults to http://localhost:8765)
# Examples: https://bookhoard.example.com | http://192.168.1.10:8765
# BASE_URL=https://bookhoard.example.com
# Mark session cookies Secure — set true behind a TLS-terminating reverse proxy (Caddy/nginx/traefik)
# COOKIE_SECURE=true
# Pin or rollback a specific published image version (defaults to "latest")
# IMAGE_TAG=1.0.0
# Optional: Override Defaults (defaults are set in docker-compose.yml)
# Test Mode: WARNING - Only set to true for integration testing
# TEST_MODE=true
# Rate Limiting: Disable or increase limits for testing
# RATE_LIMIT_ENABLED=false
# REQUESTS_PER_MINUTE=1000
# Conversion Tool: Switch from kepubify to ebook-convert
# BOOKHOARD_CONVERSION_TOOL=/usr/bin/ebook-convert
# Conversion Cache TTL: Override default 24h
# BOOKHOARD_CONVERSION_CACHE_TTL=48h
# Archive Retention: days to keep archived items (files missing from disk for
# 2+ scans) before they are purged, deleting their reading history with them.
# Set 0 to keep archived items until purged manually on the library admin page.
# ARCHIVE_RETENTION_DAYS=90
# System timezone (fallback for server-side time operations, defaults to UTC)
# TZ=America/New_York