Skip to content

Environment Variables

dim145 edited this page Apr 26, 2026 · 1 revision

Environment variables

Exhaustive reference of every environment variable the backend reads. Sorted by concern.

The dev compose at the repo root inlines its values directly in YAML; the production compose reads from .env. Either way, this is the catalogue of what's available.


Server core

Variable Default Required? Notes
PORT 3000 no TCP port the backend listens on.
NODE_ENV production no Cosmetic — affects log level defaults.
RUST_LOG (empty) no Tracing filter. Example: info,manga_collector_server=debug,sqlx=warn.
MAX_BODY_SIZE_MB 10 no Cap on request bodies. Clamped to [1, 1024]. Bump when allowing large poster uploads.
APP_ENABLE_DOTENV false no Opt-in to read .env from CWD. Disabled in production by design — secrets come from the runtime.
APP_UNSECURE_HEALTHCHECK false no When true, /api/health is reachable from any IP. Otherwise it requires loopback (or your reverse proxy's X-Forwarded-For lands 127.0.0.1).

Authentication

See Authentication for the full setup walkthrough.

Variable Default Required? Notes
AUTH_MODE google yes Either google or openidconnect.
AUTH_CLIENT_ID yes OAuth client ID from your IdP.
AUTH_CLIENT_SECRET yes OAuth client secret.
AUTH_ISSUER required when AUTH_MODE=openidconnect OIDC issuer URL (must serve /.well-known/openid-configuration).
AUTH_ISSUER_BASE_PATH optional Prefix appended to the issuer for non-standard OIDC layouts (e.g. /api/v1/oauth/).
AUTH_NAME Google no Display name shown on the sign-in page.
AUTH_ICON google no Icon for the sign-in button. Built-in: google. Otherwise an URL to a PNG/SVG.
SESSION_SECRET recommended Used to sign session cookies. 64+ random bytes. Currently optional because session IDs are already 128-bit cryptographically random; setting it adds HMAC verification against fixation.

Database & cache

Variable Default Required? Notes
POSTGRES_URL yes Standard postgres://user:pass@host:port/db?sslmode=... URL.
REDIS_URL (unset) no When set, the backend caches outbound API calls (MAL, MangaDex). When unset, the cache layer is disabled — every external call hits the network. Prefer setting it in any non-trivial deployment.
CACHE_PREFIX mangacollect/ no Prefix prepended to every cache key. Lets multiple apps share a Redis DB without collisions.

Storage

See Storage for the choice rationale.

Variable Default Required? Notes
S3_ENDPOINT (unset) required for S3 mode Hostname of your S3-compatible service (s3.amazonaws.com, play.minio.io, your own).
S3_ACCESS_KEY (unset) required for S3 mode
S3_SECRET_KEY (unset) required for S3 mode
S3_BUCKET_NAME (unset) required for S3 mode Existing bucket; the app does not create it.
S3_REGION us-east-1 no
S3_USE_SSL false no Set true for HTTPS endpoints.
S3_USE_PATH_STYLE false no Set true for MinIO / Garage / providers without virtual-host buckets.
STORAGE_DIR (unset) required for local mode Path on the host where posters are written when no S3_* vars are set. Mount a persistent volume here.

Mode selection: when S3_ENDPOINT + S3_BUCKET_NAME are both set, S3 mode is used. Otherwise the backend falls through to STORAGE_DIR on local filesystem.


URLs

Variable Default Required? Notes
FRONTEND_URL http://localhost:12000 yes Used as the OAuth redirect_uri host and for the post-login redirect. Must match your reverse-proxy public URL exactly.

Rate limiting

The per-IP rate limiter wraps /auth and the heavier /import/* endpoints.

Variable Default Notes
RATE_LIMIT_ENABLED true Master switch. Setting to false disables limiting entirely — do not do this in production, leaves /auth open to brute force and /import open to outbound amplification.
RATE_LIMIT_PERIOD_SECONDS 2 Token refill interval. 2 = ~0.5 req/s sustained per IP. Must be ≥ 1.
RATE_LIMIT_BURST_SIZE 30 Burst capacity. Must be ≥ 1.

Headers

Variable Default Notes
X_FRAME_OPTIONS DENY Value served in the X-Frame-Options response header. Set to SAMEORIGIN only if a first-party subdomain legitimately embeds the app. The deprecated ALLOW-FROM syntax is accepted by the server but ignored by modern browsers — prefer a CSP frame-ancestors rule for that use case.

External APIs

Variable Default Notes
GOOGLE_BOOKS_API_KEY (unset) Optional. Anonymous calls work but cap around 1k requests/day. An authenticated key bumps the daily quota to ~100k — strongly recommended for non-trivial deployments.

Calendar / upcoming-volume proxy

These activate the optional Release calendar proxy integration.

Variable Default Notes
EXTERNAL_PROXY_URL (unset) Base URL of the proxy (e.g. http://manga-release-proxy:3001). When unset or empty, the calendar feature is fully disableddiscover_upcoming_with_locale returns an empty list without calling anything.
EXTERNAL_PROXY_TIMEOUT_SECS 150 HTTP timeout per proxy request. Must stay ≥ 30 s above the proxy's own AGGREGATE_DEADLINE_SECS (default 120).

Quick template for .env

# core
PORT=3000
RUST_LOG=info,manga_collector_server=debug

# auth — fill from your IdP
AUTH_MODE=google
AUTH_CLIENT_ID=<from-idp>
AUTH_CLIENT_SECRET=<from-idp>
AUTH_NAME=Google
AUTH_ICON=google
SESSION_SECRET=<generate-with-openssl-rand-base64-48>

# data
POSTGRES_URL=postgres://USER:PASS@db:5432/mangacollector?sslmode=disable
REDIS_URL=redis://redis:6379/1
CACHE_PREFIX=mangacollect/

# storage — pick ONE block
# === S3 / MinIO ===
S3_ENDPOINT=s3.example.com
S3_ACCESS_KEY=<key>
S3_SECRET_KEY=<secret>
S3_BUCKET_NAME=mangacollect
S3_USE_SSL=true
S3_USE_PATH_STYLE=true
S3_REGION=us-east-1
# === Or local ===
# STORAGE_DIR=/data

# urls
FRONTEND_URL=https://mangacollector.example.com

# rate limit
RATE_LIMIT_ENABLED=true
RATE_LIMIT_PERIOD_SECONDS=1
RATE_LIMIT_BURST_SIZE=60

# headers
X_FRAME_OPTIONS=DENY

# health
APP_UNSECURE_HEALTHCHECK=false

# optional — calendar feature
# EXTERNAL_PROXY_URL=http://manga-release-proxy:3001
# EXTERNAL_PROXY_TIMEOUT_SECS=150

Clone this wiki locally