Create staging-environment-setup.md via n8n
This commit is contained in:
parent
94c08c20a5
commit
953aaa1cef
119
Tech/Reference/staging-environment-setup.md
Normal file
119
Tech/Reference/staging-environment-setup.md
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
---
|
||||||
|
project: staging-environment-setup
|
||||||
|
type: reference
|
||||||
|
status: active
|
||||||
|
path: Tech/Reference
|
||||||
|
tags:
|
||||||
|
- pbs
|
||||||
|
- infrastructure
|
||||||
|
- staging
|
||||||
|
- traefik
|
||||||
|
- cloudflare
|
||||||
|
- docker
|
||||||
|
created: 2026-04-15
|
||||||
|
updated: 2026-04-15
|
||||||
|
---
|
||||||
|
|
||||||
|
# Staging Environment — Architecture Reference
|
||||||
|
|
||||||
|
Reference doc for how the PBS staging environment is structured. Captured
|
||||||
|
retroactively from the original Feb 24 build session, before the n8n email
|
||||||
|
pipeline existed.
|
||||||
|
|
||||||
|
> **Note on path:** Filed under a proposed new `Tech/Reference` folder for
|
||||||
|
evergreen architecture docs (vs. `Tech/Sessions` for point-in-time notes or
|
||||||
|
`Tech/Projects` for active work). Flag if you'd rather move it.
|
||||||
|
|
||||||
|
## Domain & DNS Strategy
|
||||||
|
|
||||||
|
Staging lives at `staging.plantbasedsoutherner.com`, with all supporting
|
||||||
|
tools nested as further subdomains under it.
|
||||||
|
|
||||||
|
```
|
||||||
|
staging.plantbasedsoutherner.com ← WordPress
|
||||||
|
n8n.staging.plantbasedsoutherner.com ← n8n
|
||||||
|
portainer.staging.plantbasedsoutherner.com ← Portainer
|
||||||
|
status.staging.plantbasedsoutherner.com ← Uptime Kuma
|
||||||
|
db.staging.plantbasedsoutherner.com ← phpMyAdmin
|
||||||
|
gitea.staging.plantbasedsoutherner.com ← Gitea
|
||||||
|
```
|
||||||
|
|
||||||
|
**Cloudflare DNS uses a wildcard A record** so new subdomains require zero
|
||||||
|
DNS work:
|
||||||
|
|
||||||
|
```
|
||||||
|
Type: A
|
||||||
|
Name: *.staging
|
||||||
|
Value:
|
||||||
|
Proxy: DNS only (grey cloud)
|
||||||
|
```
|
||||||
|
|
||||||
|
The wildcard must remain **DNS only** (grey cloud) for Let's Encrypt HTTP
|
||||||
|
challenges to succeed. With Cloudflare proxy on, ACME hits Cloudflare's IP
|
||||||
|
instead of the origin and TLS handshake fails.
|
||||||
|
|
||||||
|
## SSL / Traefik
|
||||||
|
|
||||||
|
Traefik handles all routing and SSL via Let's Encrypt **HTTP challenge**
|
||||||
|
(not TLS challenge — TLS challenge is incompatible with Cloudflare in
|
||||||
|
front).
|
||||||
|
|
||||||
|
Each container declares its hostname via Traefik labels; Traefik handles
|
||||||
|
cert issuance and renewal automatically per hostname.
|
||||||
|
|
||||||
|
## Migration Pattern (Prod → Staging Clone)
|
||||||
|
|
||||||
|
The original staging build used a full prod clone. Key gotchas:
|
||||||
|
|
||||||
|
- **Database URL replacement:** Use WP-CLI `search-replace` (not raw SQL)
|
||||||
|
to handle serialized Elementor data correctly. Run from inside the
|
||||||
|
wordpress container.
|
||||||
|
- **Avoid "staging.staging" loops:** Replace `plantbasedsoutherner.com` → `
|
||||||
|
staging.plantbasedsoutherner.com` in one direction only; double-check
|
||||||
|
existing staging references before running.
|
||||||
|
- **Redis password:** Must be present in the container env for both prod
|
||||||
|
and staging — easy to forget when moving env vars between `.env` files.
|
||||||
|
- **DB user recreation:** Fresh MySQL inits won't carry over user grants
|
||||||
|
from the prod dump.
|
||||||
|
|
||||||
|
## Resource Sizing
|
||||||
|
|
||||||
|
Staging started on a 1GB Linode Nanode and was upgraded to 2GB after
|
||||||
|
hitting memory ceilings during full-stack runs (WordPress + MySQL + Redis +
|
||||||
|
n8n + Traefik + monitoring). 2GB is the practical minimum for the full
|
||||||
|
stack.
|
||||||
|
|
||||||
|
## Healthchecks
|
||||||
|
|
||||||
|
All Docker containers have healthchecks defined. A few patterns learned:
|
||||||
|
|
||||||
|
- **Traefik** requires an IPv6 loopback target in some configurations.
|
||||||
|
- **Containers without `curl`** (slim images, Gitea, Python slim) need
|
||||||
|
alternative healthcheck commands — wget, a Python one-liner, or the
|
||||||
|
application's own CLI.
|
||||||
|
- **Gitea healthcheck on `/api/v1/version`** returns 404 before the setup
|
||||||
|
wizard completes, blocking initial Traefik routing. Remove the healthcheck
|
||||||
|
for first-time setup, then add it back.
|
||||||
|
|
||||||
|
## Inventory & Ansible (added later)
|
||||||
|
|
||||||
|
The Ansible inventory eventually evolved to keep staging and production
|
||||||
|
strictly separated — see the GitHub deploy key project for the final
|
||||||
|
structure with `bootstrap_staging`, `bootstrap_production`, `staging`, and
|
||||||
|
`production` groups (no meta-groups that could hit both environments).
|
||||||
|
|
||||||
|
## Open Items
|
||||||
|
|
||||||
|
- [ ] Confirm `Tech/Reference` is the right folder for this kind of doc, or
|
||||||
|
move to `Tech/Sessions` / `Tech/Projects`
|
||||||
|
- [ ] Cross-link this from the GitHub deploy key project plan once both are
|
||||||
|
in the vault
|
||||||
|
|
||||||
|
## Related
|
||||||
|
|
||||||
|
- GitHub private repo + Ansible inventory restructure (April 2026)
|
||||||
|
- PBS Security Hardening (Crowdsec + Authelia, staged on staging first)
|
||||||
|
- WP-Cron / Supercronic deploy (March 2026)
|
||||||
|
|
||||||
|
|
||||||
|
...sent from Jenny & Travis
|
||||||
Loading…
Reference in New Issue
Block a user