From b71d07c09884d3e3a959ce00f7f8752040068431 Mon Sep 17 00:00:00 2001 From: npeter83 Date: Tue, 16 Jun 2026 15:21:43 +0200 Subject: [PATCH] chore(dev): self-contained local dev stack (own Postgres + scheduler) localdev no longer points at the shared database; it now runs its own local Postgres and its own scheduler, fully decoupled. Removes the shared-DB migration coupling (no more redeploys after migrations) and lets the background scheduler actually run during local dev. --- docker-compose.localdev.yml | 52 +++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/docker-compose.localdev.yml b/docker-compose.localdev.yml index 1ca87f1..a9e1c28 100644 --- a/docker-compose.localdev.yml +++ b/docker-compose.localdev.yml @@ -1,22 +1,34 @@ -# Local development against the central Postgres (an always-on host that also runs the scheduler). +# Self-contained local development stack — Postgres + API + scheduler, all on this machine. # -# Runs only the webapp/API — no local database, no scheduler — pointed at the shared -# DB on the server. You see the same live data the 24/7 backfill is filling, and you -# never run a second scheduler against it. +# Fully decoupled: its own local database (a Docker volume) and its own scheduler, so there +# is no shared DB and no migration coupling with any other instance. Edit code, rebuild, and +# everything (including the background sync) runs right here. # -# Setup: in .env set -# DATABASE_URL=postgresql+psycopg://subfeed:@your-db-host:5432/subfeed -# (use the central DB's host/port and the real POSTGRES_PASSWORD), then: -# docker compose -f docker-compose.localdev.yml up --build +# docker compose -f docker-compose.localdev.yml up -d --build # -# Browse at http://localhost:8080 — Google login works here because the OAuth redirect -# is http://localhost:8080/auth/callback. -# -# Note: the API runs `alembic upgrade head` on startup, so launching this with newer -# local migrations will apply them to the shared DB. For risky schema work, point -# DATABASE_URL at a throwaway local Postgres instead. +# Browse at http://localhost:8080 — Google login works because the OAuth redirect is +# http://localhost:8080/auth/callback. The API runs `alembic upgrade head` on startup, so it +# applies local migrations to THIS local DB only. Seed the catalog once with a pg_dump from +# another instance if you want real data (see RUNBOOK). services: + db: + image: postgres:16-alpine + environment: + POSTGRES_USER: ${POSTGRES_USER:-subfeed} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-subfeed} + POSTGRES_DB: ${POSTGRES_DB:-subfeed} + volumes: + - pgdata:/var/lib/postgresql/data + security_opt: + - apparmor:unconfined + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-subfeed} -d ${POSTGRES_DB:-subfeed}"] + interval: 5s + timeout: 5s + retries: 12 + restart: unless-stopped + api: build: context: . @@ -27,11 +39,19 @@ services: BUILD_DATE: ${BUILD_DATE:-} env_file: .env environment: - # Exactly one scheduler may write to the shared DB; the server owns it. - SCHEDULER_ENABLED: "false" + # Own local database (overrides whatever DATABASE_URL is in .env). + DATABASE_URL: postgresql+psycopg://${POSTGRES_USER:-subfeed}:${POSTGRES_PASSWORD:-subfeed}@db:5432/${POSTGRES_DB:-subfeed} + # This instance owns its scheduler now (its own DB, so no double-write concern). + SCHEDULER_ENABLED: "true" + depends_on: + db: + condition: service_healthy # Harmless on Docker Desktop; needed if ever run under Docker-in-LXC. security_opt: - apparmor:unconfined ports: - "${APP_PORT:-8080}:8000" restart: unless-stopped + +volumes: + pgdata: