docs: record live VPS details + DNS-at-Cloudflare caveat; add pre-flight script
- scripts/check-vps.sh: read-only reachability/ports/SSH-facts/DNS checker - README: real IPv4/IPv6 + Debian 13 + existing swap; firewall already on Vultr - DNS is managed at Cloudflare (NS delegated), not VentraIP — records must be DNS-only (grey cloud) so Caddy issues real certs and port 222 works - fix git remote to ssh:// form for the custom 222 port Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
76df80a26c
commit
75fabc864e
2 changed files with 224 additions and 23 deletions
73
README.md
73
README.md
|
|
@ -27,36 +27,62 @@ declares routing labels.
|
|||
|
||||
---
|
||||
|
||||
## The VPS (provisioned 2026-06-02)
|
||||
|
||||
Vultr shared-CPU **2 GB**, **Debian 13 (trixie)**, kernel 6.12, ~5.4 GB swap
|
||||
already present (no need to add any). Desktop SSH key installed; Vultr firewall
|
||||
groups applied on both IPv4 and IPv6.
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| IPv4 | `45.32.242.27` |
|
||||
| IPv6 | `2001:19f0:5801:1313:5400:6ff:fe35:c0a7` |
|
||||
| SSH | `root@45.32.242.27` (port 22) |
|
||||
|
||||
## Pre-flight check
|
||||
|
||||
Before and after each bootstrap step, run the read-only checker from your
|
||||
desktop to confirm reachability, ports, the box's facts, and DNS:
|
||||
|
||||
```sh
|
||||
./scripts/check-vps.sh --ip6 2001:19f0:5801:1313:5400:6ff:fe35:c0a7
|
||||
```
|
||||
|
||||
It exits 0 when SSH + port 22 are good; closed app ports and unset DNS show as
|
||||
warnings (expected until DNS is updated and the stack is up).
|
||||
|
||||
## Bootstrap (one-time, in order)
|
||||
|
||||
Order matters — TLS issuance needs DNS + open ports first, and the `edge`
|
||||
network must exist before any stack references it.
|
||||
|
||||
### 1. DNS
|
||||
Point at the VPS public IP, and **wait for propagation** before step 4:
|
||||
- `A joshbairstow.com → <VPS_IP>`
|
||||
- `A *.joshbairstow.com → <VPS_IP>` (wildcard covers blog/art/code/git + future)
|
||||
- `AAAA` equivalents if the VPS has IPv6.
|
||||
### 1. DNS — managed at **Cloudflare**, not VentraIP
|
||||
VentraIP is only the registrar; the domain's nameservers are delegated to
|
||||
Cloudflare (`grace/keenan.ns.cloudflare.com`), so create the records **in the
|
||||
Cloudflare dashboard**. Point them at the VPS and **wait for propagation**:
|
||||
- `A joshbairstow.com → 45.32.242.27`
|
||||
- `A *.joshbairstow.com → 45.32.242.27` (wildcard: covers blog/art/code/git + future)
|
||||
- `AAAA joshbairstow.com → 2001:19f0:5801:1313:5400:6ff:fe35:c0a7`
|
||||
- `AAAA *.joshbairstow.com → 2001:19f0:5801:1313:5400:6ff:fe35:c0a7`
|
||||
|
||||
A wildcard record means new subdomains resolve with no DNS change; certs are
|
||||
still issued per-host via HTTP-01, so no DNS-challenge plugin is required.
|
||||
> **Set these records to DNS-only (grey cloud), not proxied (orange cloud).**
|
||||
> The current records point at Cloudflare's proxy. With the proxy ON: Cloudflare
|
||||
> terminates TLS with its own edge cert (so Caddy's automatic HTTPS is bypassed),
|
||||
> and it only proxies HTTP(S) ports — **git-over-SSH on 222 and the registry
|
||||
> would break**. DNS-only makes clients hit the VPS directly, so Caddy issues
|
||||
> real Let's Encrypt certs via HTTP-01 (no DNS-challenge plugin needed) and all
|
||||
> ports work. If you later want Cloudflare's proxy/CDN, switch Caddy to the
|
||||
> DNS-01 challenge with the Cloudflare plugin + an API token — a separate change.
|
||||
|
||||
### 2. VPS base
|
||||
Firewall is already handled by the Vultr firewall group (80, 443, 222, 22), so
|
||||
host `ufw` is optional. Swap already exists. The remaining task is Docker:
|
||||
```sh
|
||||
# Install Docker Engine + compose plugin (official convenience script or distro pkg)
|
||||
# Install Docker Engine + compose plugin
|
||||
curl -fsSL https://get.docker.com | sh
|
||||
|
||||
# Firewall: allow only what we serve.
|
||||
# 80, 443 -> edge proxy (HTTP/HTTPS, incl. ACME challenges)
|
||||
# 222 -> Forgejo git-over-SSH
|
||||
# 22 -> your normal host SSH (keep it!)
|
||||
ufw allow 80,443/tcp && ufw allow 222/tcp && ufw allow OpenSSH && ufw enable
|
||||
```
|
||||
RAM: prefer the **2 GB** Vultr tier. On 1 GB, add swap first:
|
||||
```sh
|
||||
fallocate -l 2G /swapfile && chmod 600 /swapfile && mkswap /swapfile && swapon /swapfile
|
||||
echo '/swapfile none swap sw 0 0' >> /etc/fstab
|
||||
docker --version && docker compose version # confirm
|
||||
```
|
||||
(Re-run `./scripts/check-vps.sh` — `DOCKER` should now report a version.)
|
||||
|
||||
### 3. Create the shared network + bring up the stack
|
||||
```sh
|
||||
|
|
@ -90,8 +116,8 @@ forgejo-runner daemon --config /path/to/jb-infra/runner/config.yml
|
|||
### 6. Wire the jb-website repo
|
||||
In the `jb-website` repo settings on Forgejo (`Settings → Actions`):
|
||||
- **Variables:** `REGISTRY_OWNER` = your lowercase owner.
|
||||
- **Secrets:** `REGISTRY_USER`, `REGISTRY_TOKEN` (the PAT), `DEPLOY_HOST`,
|
||||
`DEPLOY_USER`, `DEPLOY_SSH_KEY`.
|
||||
- **Secrets:** `REGISTRY_USER`, `REGISTRY_TOKEN` (the PAT), `DEPLOY_HOST`
|
||||
(`45.32.242.27`), `DEPLOY_USER`, `DEPLOY_SSH_KEY`.
|
||||
|
||||
On the **VPS**, prepare the deploy target:
|
||||
```sh
|
||||
|
|
@ -105,8 +131,9 @@ of `DEPLOY_SSH_KEY`.
|
|||
|
||||
### 7. First deploy
|
||||
```sh
|
||||
# in the jb-website repo (rename master→main first; see that repo's README)
|
||||
git remote add origin git@git.joshbairstow.com:222/<owner>/jb-website.git
|
||||
# in the jb-website repo (default branch is already `main`).
|
||||
# Custom SSH port 222 needs the ssh:// URL form (scp-style host:port doesn't work):
|
||||
git remote add origin ssh://git@git.joshbairstow.com:222/<owner>/jb-website.git
|
||||
git push -u origin main
|
||||
```
|
||||
The push triggers `.forgejo/workflows/deploy.yml`: the desktop builds + pushes
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue