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:
parent
5c9d4a99cc
commit
7ecd1b32ae
8 changed files with 261 additions and 97 deletions
144
Caddyfile
144
Caddyfile
|
|
@ -1,89 +1,99 @@
|
|||
# ----------------------------------------------------------------------------
|
||||
# jb-website — Caddy site config.
|
||||
# jb-website — INTERNAL static server (behind the edge reverse proxy).
|
||||
#
|
||||
# Routing model (see docs/planning.md §6.2):
|
||||
# joshbairstow.com -> /srv/* (apex / home)
|
||||
# blog.joshbairstow.com -> /srv/blog/* (writing archive + posts)
|
||||
# art.joshbairstow.com -> /srv/art/* (generative art focus view)
|
||||
# code.joshbairstow.com -> /srv/code/* (experiments & tools)
|
||||
# This Caddy no longer terminates TLS or owns 80/443. The edge proxy
|
||||
# (caddy-docker-proxy, see the infra repo) terminates HTTPS for every host and
|
||||
# reverse-proxies plaintext to this container on :80, preserving the original
|
||||
# Host header. We branch on that Host header to serve the right slice of the
|
||||
# single static build:
|
||||
#
|
||||
# Each block points at the same /srv directory but uses `root` with the path
|
||||
# prefix appropriate to the subdomain. Caddy handles HTTPS via the automatic
|
||||
# ACME / Let's Encrypt flow at the email address below.
|
||||
# joshbairstow.com / www. -> /srv (apex / home)
|
||||
# blog.joshbairstow.com -> /srv/blog (writing archive + posts)
|
||||
# art.joshbairstow.com -> /srv/art (generative art focus view)
|
||||
# code.joshbairstow.com -> /srv/code (experiments & tools)
|
||||
#
|
||||
# Local dev: see the `localhost` block at the bottom — Caddy listens on :8080
|
||||
# with no TLS so `docker compose up` works out of the box on a laptop.
|
||||
# Shared build assets (/_astro/*, /assets/*) live at the apex root, so the
|
||||
# subdomain handlers re-root those paths back to /srv.
|
||||
#
|
||||
# One bare `:80` listener + host matchers (NOT named-host site blocks) keeps
|
||||
# this purely plaintext: named-host blocks would re-trigger Caddy's automatic
|
||||
# HTTPS, which the edge proxy already handles. Local preview is provided by
|
||||
# compose.dev.yml mapping a host port to this :80.
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
{
|
||||
# Replace with the address you want ACME-challenge contact / cert-expiry mail at.
|
||||
email josh@joshbairstow.com
|
||||
# Edge proxy owns TLS; this server is plaintext-only and has no admin needs.
|
||||
auto_https off
|
||||
admin off
|
||||
}
|
||||
|
||||
# ---- apex ------------------------------------------------------------------
|
||||
joshbairstow.com, www.joshbairstow.com {
|
||||
root * /srv
|
||||
:80 {
|
||||
encode zstd gzip
|
||||
file_server
|
||||
try_files {path} {path}/index.html /404.html
|
||||
|
||||
# ---- www -> apex redirect ----------------------------------------------
|
||||
# The upstream only ever sees http, so the scheme is hardcoded https.
|
||||
@www host www.joshbairstow.com
|
||||
redir @www https://joshbairstow.com{uri} permanent
|
||||
}
|
||||
|
||||
# ---- blog ------------------------------------------------------------------
|
||||
blog.joshbairstow.com {
|
||||
root * /srv/blog
|
||||
encode zstd gzip
|
||||
# Assets and the canvas-island JS live at /_astro and /assets on the apex build.
|
||||
# Re-route them from the subdomain root by falling through to the parent /srv.
|
||||
@asset path /_astro/* /assets/*
|
||||
handle @asset {
|
||||
# ---- apex --------------------------------------------------------------
|
||||
@apex host joshbairstow.com
|
||||
handle @apex {
|
||||
root * /srv
|
||||
try_files {path} {path}/index.html /404.html
|
||||
file_server
|
||||
}
|
||||
handle {
|
||||
file_server
|
||||
try_files {path} {path}/index.html /srv/404.html
|
||||
}
|
||||
}
|
||||
|
||||
# ---- art -------------------------------------------------------------------
|
||||
art.joshbairstow.com {
|
||||
root * /srv/art
|
||||
encode zstd gzip
|
||||
@asset path /_astro/* /assets/*
|
||||
handle @asset {
|
||||
# ---- blog --------------------------------------------------------------
|
||||
@blog host blog.joshbairstow.com
|
||||
handle @blog {
|
||||
@asset path /_astro/* /assets/*
|
||||
handle @asset {
|
||||
root * /srv
|
||||
file_server
|
||||
}
|
||||
handle {
|
||||
root * /srv/blog
|
||||
try_files {path} {path}/index.html /srv/404.html
|
||||
file_server
|
||||
}
|
||||
}
|
||||
|
||||
# ---- art ---------------------------------------------------------------
|
||||
@art host art.joshbairstow.com
|
||||
handle @art {
|
||||
@asset path /_astro/* /assets/*
|
||||
handle @asset {
|
||||
root * /srv
|
||||
file_server
|
||||
}
|
||||
handle {
|
||||
root * /srv/art
|
||||
try_files {path} {path}/index.html /srv/404.html
|
||||
file_server
|
||||
}
|
||||
}
|
||||
|
||||
# ---- code --------------------------------------------------------------
|
||||
@code host code.joshbairstow.com
|
||||
handle @code {
|
||||
@asset path /_astro/* /assets/*
|
||||
handle @asset {
|
||||
root * /srv
|
||||
file_server
|
||||
}
|
||||
handle {
|
||||
root * /srv/code
|
||||
try_files {path} {path}/index.html /srv/404.html
|
||||
file_server
|
||||
}
|
||||
}
|
||||
|
||||
# ---- fallback ----------------------------------------------------------
|
||||
# Any other Host (e.g. hitting the container directly, or local preview at
|
||||
# localhost:8080) serves the apex build so the site is never blank.
|
||||
handle {
|
||||
root * /srv
|
||||
try_files {path} {path}/index.html /404.html
|
||||
file_server
|
||||
}
|
||||
handle {
|
||||
file_server
|
||||
try_files {path} {path}/index.html /srv/404.html
|
||||
}
|
||||
}
|
||||
|
||||
# ---- code ------------------------------------------------------------------
|
||||
code.joshbairstow.com {
|
||||
root * /srv/code
|
||||
encode zstd gzip
|
||||
@asset path /_astro/* /assets/*
|
||||
handle @asset {
|
||||
root * /srv
|
||||
file_server
|
||||
}
|
||||
handle {
|
||||
file_server
|
||||
try_files {path} {path}/index.html /srv/404.html
|
||||
}
|
||||
}
|
||||
|
||||
# ---- local dev (no TLS) ----------------------------------------------------
|
||||
# Hit http://localhost:8080 to preview the built apex; the subdomain rewrites
|
||||
# above only fire when accessed by their real hostnames.
|
||||
:8080 {
|
||||
root * /srv
|
||||
encode zstd gzip
|
||||
file_server
|
||||
try_files {path} {path}/index.html /404.html
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue