siftlode/docker-compose.server.yml
npeter83 ebcb5144b6 chore: rename remaining subfeed references to siftlode
Replace the leftover 'subfeed' name across logger names + log_config,
frontend localStorage keys, Postgres user/db/volume defaults in the
compose files, .env.example, config.py, backup/restore scripts and the
README. Pure rename; no behavioural change. localStorage keys move from
subfeed.* to siftlode.* (one-time UI-state reset is acceptable).
2026-06-21 06:53:12 +02:00

68 lines
2.7 KiB
YAML

# Server (Proxmox LXC) deployment of the full Siftlode stack.
#
# This is the "central" instance: it owns the single shared Postgres database and
# runs the background scheduler (RSS poll, enrichment, recent/deep backfill) 24/7.
# Local dev machines and any future VPS point their DATABASE_URL at this Postgres
# and run with SCHEDULER_ENABLED=false (see docker-compose.localdev.yml) so exactly
# one scheduler ever writes to the DB.
#
# Usage (inside the LXC, from the project root which is the bind-mounted /docker):
# export COMPOSE_FILE=docker-compose.server.yml # or put it in .env
# docker compose up -d --build
#
# Postgres data lives in ./pgdata (a host-visible bind mount under /docker/siftlode)
# so it is covered by the host's /docker backups; logical pg_dump backups via
# scripts/backup.sh remain the portable mechanism for moving between hosts.
services:
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: ${POSTGRES_USER:-siftlode}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-siftlode}
POSTGRES_DB: ${POSTGRES_DB:-siftlode}
volumes:
- ./pgdata:/var/lib/postgresql/data
ports:
# Published on the LAN so the local dev webapp uses this central DB.
- "5432:5432"
# Required for Docker-in-LXC: the container can't load the docker-default
# AppArmor profile inside an unprivileged-from-AppArmor's-view namespace.
security_opt:
- apparmor:unconfined
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-siftlode} -d ${POSTGRES_DB:-siftlode}"]
interval: 5s
timeout: 5s
retries: 12
restart: unless-stopped
api:
build:
context: .
dockerfile: Dockerfile
args:
APP_VERSION: ${APP_VERSION:-dev}
GIT_SHA: ${GIT_SHA:-unknown}
BUILD_DATE: ${BUILD_DATE:-}
env_file: .env
environment:
DATABASE_URL: postgresql+psycopg://${POSTGRES_USER:-siftlode}:${POSTGRES_PASSWORD:-siftlode}@db:5432/${POSTGRES_DB:-siftlode}
# This instance owns the background sync. Keep it true here and false everywhere else.
SCHEDULER_ENABLED: "true"
depends_on:
db:
condition: service_healthy
security_opt:
- apparmor:unconfined
ports:
# Exposed on the LAN for status/health checks only. Interactive Google login
# needs a public HTTPS redirect URL (set up later); backfill runs regardless.
- "${APP_PORT:-8080}:8000"
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; exit(0 if urllib.request.urlopen('http://localhost:8000/healthz').status == 200 else 1)"]
interval: 15s
timeout: 5s
retries: 5
start_period: 25s
restart: unless-stopped