Self-hosted Gitea on a single e2-small AlmaLinux 10 VM in us-east1, serving gitea.jasonmross.dev. Runtime is podman quadlets (systemd .container/.network/.volume units). Both images are built on Debian 13: Gitea from a GPG-verified release binary, and Caddy from an xcaddy build carrying the Google Cloud DNS provider (ACME DNS-01) and the Coraza WAF with the OWASP CRS embedded. Infrastructure is a Pulumi program in Go against a GCS state backend. Cloud Build handles CI: a push trigger for images, one for infra, and a weekly scheduled rebuild. Everything Cloud Build touches is 2nd gen. Notable design decisions, each documented where it lives: - Quadlets track a floating :prod tag. AutoUpdate=registry compares digests for a tag, so a digest-pinned image silently disables auto-updates. - Git transport and LFS bypass the WAF. With the bypass removed, a plain git push returns 403 -- packfiles trip CRS reliably. - gitea:wafMode drives both SecRuleEngine and whether the fail2ban jail acting on WAF verdicts exists. Banning on detections that were never blocks would turn a tuning false positive into an nftables ban. - fail2ban bans at the nftables prerouting hook. Published container ports are DNAT'd and never traverse INPUT, where the stock actions install their rules. - The DNS zone, backup bucket, and Gitea signing secrets are not Pulumi-owned, so pulumi destroy cannot take them with it. - The podman subnet is pinned because it is what Gitea's REVERSE_PROXY_TRUSTED_PROXIES names. Three update layers: dnf5-automatic for the OS, podman-auto-update with health-gated rollback for containers, and a weekly image rebuild that gives the second layer something to pull. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
16 lines
549 B
SYSTEMD
16 lines
549 B
SYSTEMD
# Rendered by vm/bootstrap.sh into /etc/containers/systemd/
|
|
#
|
|
# The subnet is PINNED deliberately. Left to podman it is drawn from the default
|
|
# pool and is not stable across a network recreate -- and this CIDR is exactly
|
|
# what Gitea's REVERSE_PROXY_TRUSTED_PROXIES has to name. An unpinned subnet
|
|
# means a network recreate silently reverts every fail2ban ban to targeting
|
|
# Caddy instead of the real client.
|
|
[Unit]
|
|
Description=Gitea container network
|
|
|
|
[Network]
|
|
NetworkName=gitea
|
|
Subnet=${PODMAN_SUBNET}
|
|
Gateway=${PODMAN_GATEWAY}
|
|
Label=app=gitea
|