feat(deploy): self-hosted CI/CD + dedicated edge-proxy topology

Refactor the site container from a TLS-owning, port-binding proxy into an
internal plaintext static server that sits behind a dedicated edge reverse
proxy, and add an automated build/deploy pipeline.

- Caddyfile: single :80 listener (auto_https off), Host-matcher routing for
  apex/blog/art/code with /_astro+/assets re-root and www->apex redirect
- Dockerfile: EXPOSE 80 only (TLS now handled by the edge proxy)
- compose.yml: pull registry image, join external 'edge' network, declare
  routing via caddy-docker-proxy labels; drop build/ports/cert volumes
- compose.dev.yml: local container preview on :8080
- .forgejo/workflows/deploy.yml: push-to-main -> desktop runner builds, pushes
  to the Forgejo registry, SSH-deploys to the VPS
- docs + .dockerignore updated for the new topology

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Josh Bairstow 2026-06-02 15:31:16 +10:00
parent 5c9d4a99cc
commit 7ecd1b32ae
8 changed files with 261 additions and 97 deletions

25
compose.dev.yml Normal file
View file

@ -0,0 +1,25 @@
# ----------------------------------------------------------------------------
# jb-website — LOCAL preview of the built container.
#
# The production compose.yml pulls a registry image, joins the external `edge`
# network, and publishes no ports — none of which works on a laptop. This file
# builds the image locally and maps a host port straight to the internal :80 so
# you can eyeball the real Caddy/static output without the edge proxy.
#
# docker compose -f compose.dev.yml up --build
# -> http://localhost:8080
#
# Subdomain Host-matching only fires for the real hostnames, so localhost:8080
# falls through to the apex build (see the fallback handler in Caddyfile). To
# exercise subdomain routing locally, add hosts-file entries pointing the real
# names at 127.0.0.1, or just use `npm run dev` (the urls.ts helpers collapse
# cross-subdomain links to relative paths in dev).
# ----------------------------------------------------------------------------
services:
web:
build: .
image: jb-website:dev
container_name: jb-website-dev
ports:
- "8080:80"