The CORS allowed-origins list, host port mappings, log level, container
timezone, and worker concurrency are now all driven by environment
variables with sane defaults. Same-origin access through the nginx
proxy keeps working with no config; direct cross-origin backend
access can be locked down via ALLOWED_ORIGINS.
- backend/config: ALLOWED_ORIGINS env (comma-separated, "*" for any)
exposed via settings.cors_origins. LOG_LEVEL too.
- backend/main: build the CORS middleware from settings.cors_origins,
auto-disable allow_credentials when origins is wildcard (CORS spec
forbids credentials + "*").
- docker-compose: parameterize FRONTEND_PORT, BACKEND_PORT, REDIS_PORT,
CELERYD_CONCURRENCY, LOG_LEVEL, and TZ via ${VAR:-default} so each
has a working fallback if the .env entry is missing.
- .env.example: new template documenting every knob with examples.
- .env: pruned to only the values that diverge from .env.example;
removed dead VITE_API_URL.
- README: configuration knobs table + "accessing from another machine"
section explaining the same-origin proxy story.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
84 lines
4.2 KiB
Plaintext
84 lines
4.2 KiB
Plaintext
# ─────────────────────────────────────────────────────────────────────────────
|
|
# Mulita / PhotoVault — example environment file
|
|
#
|
|
# Copy this file to `.env` and adjust the values for your setup. Every key
|
|
# below has a sensible default in docker-compose.yml, so you only need to
|
|
# uncomment the ones you actually want to change.
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
|
|
|
|
# ── REQUIRED ─────────────────────────────────────────────────────────────────
|
|
|
|
# Host path to your photo library. The compose file mounts this at /photos
|
|
# inside the backend + worker containers. The backend creates a default
|
|
# source root pointing at /photos on first boot, so once this is set the
|
|
# library is scanned with zero further configuration.
|
|
#
|
|
# Examples:
|
|
# macOS / Linux: PHOTO_DIRS=/Users/you/Pictures
|
|
# Network share: PHOTO_DIRS=/mnt/nas/photos
|
|
# Windows (WSL): PHOTO_DIRS=/mnt/c/Users/you/Pictures
|
|
PHOTO_DIRS=./photos
|
|
|
|
|
|
# ── PORTS ────────────────────────────────────────────────────────────────────
|
|
|
|
# Host port the SPA is served on. Browse to http://<host>:<FRONTEND_PORT>/.
|
|
FRONTEND_PORT=3000
|
|
|
|
# Host port for the backend API. Almost never needed directly — the frontend
|
|
# nginx proxies /api/ to the backend over the internal compose network. Kept
|
|
# exposed for debugging / curl.
|
|
BACKEND_PORT=8001
|
|
|
|
# Redis host port. Internal services reach Redis on its container name; this
|
|
# is just for local debugging.
|
|
REDIS_PORT=6379
|
|
|
|
|
|
# ── CORS ─────────────────────────────────────────────────────────────────────
|
|
|
|
# Comma-separated list of allowed origins for direct browser access to the
|
|
# backend. Same-origin requests through the nginx / vite proxy never trip
|
|
# CORS, so this only matters when something hits the backend port directly
|
|
# from a different origin (e.g. another machine, dev tools, a reverse proxy
|
|
# under a different hostname).
|
|
#
|
|
# Default "*" is permissive, fine for a single-user homelab. Lock it down in
|
|
# real deployments:
|
|
# ALLOWED_ORIGINS=https://photos.example.com
|
|
# ALLOWED_ORIGINS=https://photos.example.com,http://192.168.1.10:3000
|
|
ALLOWED_ORIGINS=*
|
|
|
|
|
|
# ── LOGGING / TIMEZONE ───────────────────────────────────────────────────────
|
|
|
|
# Python log level for the backend and Celery worker. Bump to DEBUG when
|
|
# chasing scan / thumbnail issues.
|
|
LOG_LEVEL=INFO
|
|
|
|
# Container timezone. Affects the timestamps in logs and the "added at"
|
|
# field on newly imported photos. Defaults to UTC.
|
|
# TZ=Europe/Berlin
|
|
# TZ=America/New_York
|
|
TZ=UTC
|
|
|
|
|
|
# ── WORKER CONCURRENCY ───────────────────────────────────────────────────────
|
|
|
|
# How many parallel Celery worker processes to spin up. Each one can run
|
|
# one scan / thumbnail / metadata job at a time. Bump on a beefy host with a
|
|
# big library; lower on a Pi.
|
|
CELERYD_CONCURRENCY=4
|
|
|
|
|
|
# ── INTERNAL (rarely overridden) ─────────────────────────────────────────────
|
|
|
|
# These point at the in-compose Redis and the bind-mounted SQLite db. Override
|
|
# only if you're running Mulita without docker-compose or against an external
|
|
# Redis.
|
|
# REDIS_URL=redis://redis:6379
|
|
# CELERY_BROKER_URL=redis://redis:6379
|
|
# CELERY_RESULT_BACKEND=redis://redis:6379
|
|
# DATABASE_URL=sqlite+aiosqlite:////data/db/mulita.db
|