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
|
|
@ -170,9 +170,8 @@ Recommendation for a project of this size:
|
|||
**Suggested stack on the VPS:**
|
||||
- **Caddy** as the reverse proxy — automatic HTTPS via Let's Encrypt, dead-simple Caddyfile, handles the host-header → path-prefix routing cleanly.
|
||||
- **Docker + docker compose** — the Astro static output baked into a tiny container (Caddy + the `dist/` files, or just nginx-alpine + static files); side-hustle containers added alongside under the same compose file.
|
||||
- **Deployment** options:
|
||||
- Build locally → push image to a registry (GHCR or Docker Hub) → SSH to VPS → `compose pull && up -d`. Fully manual, very transparent.
|
||||
- Or GitHub Actions: build + push image on tag, then a webhook or SSH step triggers the VPS pull. Slightly more setup, far less ceremony per deploy. Recommended once the workflow is steady.
|
||||
- **Deployment** (decided 2026-06-02 — see §6.5):
|
||||
- Self-hosted **Forgejo** on the VPS (`git.joshbairstow.com`) hosts the repo + CI + a container registry; a **Forgejo Actions runner on the home desktop** builds the image and SSH-deploys to the VPS. Earlier GHCR/GitHub-Actions options were dropped in favour of self-hosting (learning value + avoids GitHub).
|
||||
|
||||
### 6.4 Other open questions
|
||||
|
||||
|
|
@ -182,6 +181,32 @@ Recommendation for a project of this size:
|
|||
- **`code.` subdomain content:** ~~is this also served from this repo~~ — confirmed in-repo (2026-06-01).
|
||||
- **Design system docs source:** ~~URL 404'd~~ — imported successfully (2026-06-01); see `docs/design-system/`.
|
||||
|
||||
### 6.5 CI/CD + multi-project topology (decided 2026-06-02)
|
||||
|
||||
The site is one project among several that will eventually share the VPS via
|
||||
subdomains (separate repos/containers each). To keep their lifecycles
|
||||
independent, infrastructure splits in two:
|
||||
|
||||
- **`jb-infra` repo (bootstrapped manually on the VPS):** a dedicated
|
||||
**caddy-docker-proxy** edge container owns 80/443, terminates TLS for all
|
||||
hosts, and routes by **Docker labels** over a shared external `edge` network;
|
||||
plus **Forgejo** (`git.joshbairstow.com`) for self-hosted git + Actions + a
|
||||
container registry.
|
||||
- **This repo:** refactored to an *internal* plaintext static server (drops
|
||||
TLS/ACME/port-binding; keeps host→path + asset re-root in `Caddyfile`), joins
|
||||
the `edge` network, and declares its hostnames via `caddy` labels in
|
||||
`compose.yml`. CI lives in `.forgejo/workflows/deploy.yml`.
|
||||
|
||||
**Flow:** push to `main` → home-desktop runner builds the image → pushes to the
|
||||
Forgejo registry → SSHes to the VPS → `compose pull && up -d`. The small VPS
|
||||
never builds (build offloaded to the always-on desktop). New projects plug in by
|
||||
joining `edge` + adding labels — no central config edits.
|
||||
|
||||
Rationale: self-hosting Forgejo is a deliberate learning investment and avoids
|
||||
GitHub; the label-driven edge proxy scales to many independent repos cleanly;
|
||||
offloading builds keeps the VPS on the cheap tier. RAM target bumped to 2 GB (or
|
||||
1 GB + swap). See `jb-infra/README.md` for the full bootstrap runbook.
|
||||
|
||||
## 7. Decisions log
|
||||
|
||||
| Date | Decision | Rationale |
|
||||
|
|
@ -196,6 +221,9 @@ Recommendation for a project of this size:
|
|||
| 2026-06-01 | `code.` subdomain is in-repo (third in-repo section alongside `blog.` and `art.`) | User confirmed; routing model already supports it |
|
||||
| 2026-06-01 | Architecture must remain open to adding further in-repo subdomain paths later | User flagged this as a constraint; host-aware routing in §6.2 scales to N paths without rework |
|
||||
| 2026-06-01 | Brand-system docs imported to `docs/design-system/` from a fresh handoff bundle | Establishes the canonical brand spec in-repo so future work can cite it |
|
||||
| 2026-06-02 | Self-host git + CI via Forgejo on the VPS (`git.joshbairstow.com`); runner on the home desktop | Learning value + avoids GitHub availability issues; offloads builds from the small VPS |
|
||||
| 2026-06-02 | Dedicated `caddy-docker-proxy` edge container owns TLS/routing via Docker labels; website becomes an internal server | Decouples each project's deploy; new subdomains/containers plug in with zero central edits |
|
||||
| 2026-06-02 | Infra (edge proxy + Forgejo) split into a separate `jb-infra` repo, bootstrapped manually | Infra changes rarely; keeps the app repo's CI focused on the app |
|
||||
|
||||
## 8. Next steps
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue