b135f11557
Security (P0): - Remove committed session-secret default; auto-generate and persist a random secret to the config volume when SESSION_SECRET is unset (prevents forgeable session cookies / auth bypass). - Validate playlist names to a safe charset and render sldl configs via literal Python substitution instead of sed (closes a command-injection and path-traversal path through playlist names). - shlex-quote credential values written to shell-sourced env files, and strip newlines from values patched into .conf files. - Render playlist .conf files 0600; warn at startup if the master key is co-located with the config volume; document keeping it separate. Portability: - Configurable timezone via TZ (default UTC) instead of hardcoded Edmonton. - Remove personal defaults (navidrome user "andrew", ephemeral.club URLs). - Ship generic example seeds; move the cross-album dedup keep-list and the legacy playlist import to editable config files; drop the personal _upgrade.csv. - Generic VPN reference in docker-compose.snippet.yml. First-run experience: - Redirect to /setup instead of 500 when OIDC is unconfigured; surface a missing master key inline; entrypoint exits with an actionable message when the config folder is not writable. - Add unauthenticated /health (JSON) and /setup (checklist) diagnostics. Docs: - Write docs/ARCHITECTURE.md and docs/MIGRATION.md (previously referenced but missing); expand README with ownership, backups, advanced settings, and migration guidance. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
52 lines
2.2 KiB
YAML
52 lines
2.2 KiB
YAML
# Optional: route Soulseek traffic through a VPN container (gluetun).
|
|
#
|
|
# This is a reference, not a drop-in file. Most people can ignore it and use
|
|
# the plain `ports:` mapping shown in the README. Use this pattern only if you
|
|
# want alembic's outbound traffic to leave through a VPN.
|
|
#
|
|
# The idea: instead of giving alembic its own network, you attach it to a
|
|
# gluetun container's network with `network_mode: "service:gluetun"`. All of
|
|
# alembic's traffic then exits through the VPN gluetun maintains.
|
|
#
|
|
# When you do this, three things change compared to the README example:
|
|
# 1. alembic no longer publishes its own port. Publish 8420 on the gluetun
|
|
# service instead (add `- 8420:8420` to gluetun's `ports:`).
|
|
# 2. gluetun's firewall must allow alembic to reach your other containers
|
|
# (Navidrome, etc). Add your Docker bridge subnet to gluetun's
|
|
# FIREWALL_OUTBOUND_SUBNETS, for example:
|
|
# FIREWALL_OUTBOUND_SUBNETS=192.168.0.0/24,172.18.0.0/16
|
|
# Find your subnet with: docker network inspect <your-compose-project>_default
|
|
# 3. If you use a reverse proxy, point it at gluetun's host/port, not
|
|
# alembic's. Once alembic shares gluetun's network it has no container
|
|
# hostname of its own.
|
|
|
|
alembic:
|
|
image: alembic:latest
|
|
container_name: alembic
|
|
network_mode: "service:gluetun"
|
|
depends_on:
|
|
gluetun:
|
|
condition: service_healthy
|
|
env_file:
|
|
# Your OIDC settings (POCKETID_ISSUER, POCKETID_CLIENT_ID,
|
|
# POCKETID_CLIENT_SECRET) and any other env vars.
|
|
- /path/to/alembic-config/alembic.env
|
|
volumes:
|
|
- /path/to/your/music:/data/music:rw
|
|
- /path/to/alembic-config:/config:rw
|
|
secrets:
|
|
- alembic_master_key
|
|
restart: unless-stopped
|
|
|
|
# Add alongside the existing top-level `secrets:` block (create one if this
|
|
# compose file doesn't have one yet).
|
|
#
|
|
# Keep master.key OUTSIDE the config volume. The key decrypts every stored
|
|
# credential, and the encrypted database lives in the config volume, so if the
|
|
# key sits in there too then a single leaked backup exposes both halves and the
|
|
# encryption buys you nothing. Put it in its own directory that your config
|
|
# backup does not include:
|
|
# secrets:
|
|
# alembic_master_key:
|
|
# file: /path/to/alembic-secrets/master.key
|