jb-infra/compose.yml
Josh Bairstow 76df80a26c chore: initial VPS edge stack (caddy-docker-proxy + Forgejo)
Edge reverse proxy (TLS + label routing) and self-hosted Forgejo (git +
Actions + container registry) for joshbairstow.com, plus the desktop runner
config and the one-time bootstrap runbook.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 15:31:25 +10:00

80 lines
2.7 KiB
YAML

# ----------------------------------------------------------------------------
# jb-infra — VPS edge stack: reverse proxy + self-hosted git/CI.
#
# Brought up MANUALLY on the VPS, once (it rarely changes). Everything else
# (jb-website and future projects) is deployed by CI and just joins the `edge`
# network + declares routing labels.
#
# docker network create edge # one time, BEFORE this stack
# docker compose up -d
#
# - caddy : owns 80/443, terminates TLS (automatic ACME) for every host, and
# builds its routing from Docker labels on containers attached to
# the `edge` network.
# - forgejo : git server + Actions + container registry at git.joshbairstow.com.
# ----------------------------------------------------------------------------
services:
caddy:
# Pin to the current release; verify the tag at
# https://hub.docker.com/r/lucaslorentz/caddy-docker-proxy/tags
image: lucaslorentz/caddy-docker-proxy:2.10-alpine
container_name: edge-caddy
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "443:443/udp" # HTTP/3
environment:
# Only build routes from containers on this network.
CADDY_INGRESS_NETWORKS: edge
networks:
- edge
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- caddy_data:/data # certs live here — MUST persist (rate limits otherwise)
- caddy_config:/config
labels:
# ACME contact for every cert this proxy issues.
caddy.email: josh@joshbairstow.com
forgejo:
# Pin to the current stable line; verify at
# https://codeberg.org/forgejo/-/packages/container/forgejo
image: codeberg.org/forgejo/forgejo:11
container_name: forgejo
restart: unless-stopped
environment:
USER_UID: "1000"
USER_GID: "1000"
# Server identity — must be correct or registry login / clone URLs break.
FORGEJO__server__ROOT_URL: https://git.joshbairstow.com/
FORGEJO__server__DOMAIN: git.joshbairstow.com
FORGEJO__server__HTTP_PORT: "3000"
FORGEJO__server__SSH_DOMAIN: git.joshbairstow.com
FORGEJO__server__SSH_PORT: "222"
# Enable Actions (CI). Runners register against this instance.
FORGEJO__actions__ENABLED: "true"
# SQLite keeps the footprint small on a modest VPS.
FORGEJO__database__DB_TYPE: sqlite3
networks:
- edge
volumes:
- forgejo_data:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
# git-over-SSH. 222 avoids the host's own sshd on 22.
- "222:22"
labels:
caddy: git.joshbairstow.com
caddy.reverse_proxy: "{{upstreams 3000}}"
networks:
edge:
external: true
volumes:
caddy_data:
caddy_config:
forgejo_data: