# Deploying Provenance This directory is the self-host stack: `docker-compose.yml` (Postgres + MinIO + Caddy + backend + worker + frontend, with a one-shot Alembic `migrate` job), `Caddyfile` for the edge, `.env.example` for configuration, and `backup.sh` / [BACKUP.md](BACKUP.md) for backup and restore. ## Run it ```bash cp .env.example .env # fill in secrets, OWNER_EMAIL, APP_ENV=production docker compose up -d # pulls backend/frontend images from git.jpaul.io ``` Images are **pulled** from the public `git.jpaul.io` registry (CI pushes them to the LAN endpoint `192.168.0.2:1234`; see CLAUDE.md). To build locally instead, layer the dev override: ```bash docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d --build ``` Caddy's site address is env-driven (`PROVENANCE_SITE_ADDRESS`): `:80` for plain HTTP behind a tunnel or for `http://localhost`, or a domain for automatic HTTPS. Nothing in this repo hard-codes a hostname. Note that a Watchtower image swap recreates only the long-running containers, not the one-shot `migrate` job — pair auto-deploys with a `docker compose up` so migrations re-run. ## The maintainer's instance Justin's own deployment — the one holding the Paul/Reier family tree: | | | |---|---| | **URL** | | | **Host** | `192.168.0.2` (the fleet host; also the LAN registry endpoint) | | **Ingress** | Cloudflare Tunnel → `caddy:80`; Cloudflare terminates TLS, so `PROVENANCE_SITE_ADDRESS` stays `:80` | | **Owner account** | `justin@jpaul.me` | | **Deploys** | CI builds on merge to `main`; the host's global Watchtower swaps the `test-main` images | Health check (no auth): `curl https://provenance.paul.farm/health`. Known drift: that endpoint currently reports `"env":"development"` — the host's `.env` never set `APP_ENV=production`. It is informational only (`app_env` is reported by `/health` and `/api/v1/admin`; it gates no behavior), but it should be corrected on the host.