Files
2026-04-09 16:54:35 -04:00

132 lines
4.2 KiB
Markdown

# Use Cases
Expected behaviors for each operation this repo supports. See README.md for
instructions, ARCHITECTURE.md for technical details.
## 0. Initial Bitwarden Secrets Manager setup
**Trigger:** one-time, before anything else works.
**Expected outcome:**
- Bitwarden organization with Secrets Manager enabled
- Project `hantim` with all secrets listed in README.md
- Machine accounts `hantim-server` and `hantim-ci` with project access
- Access tokens generated for each machine account
## 1. Provision a new server
**Trigger:** run `bootstrap.sh` on a fresh Rocky Linux 9 install.
**Prerequisites:** DNS pointed to server, bws access token ready.
**Expected outcome:**
- All dependencies installed (Docker, certbot, bws, etc.)
- `deploy` user exists with restricted SSH and sudo
- Firewall allows HTTP, HTTPS, Garage RPC
- Certbot renewal configured
- All services running (nginx, apps, Garage)
- SSL certs issued for all configured domains
- `.env` files generated from bws for services with `.env.keys`
## 2. Restore from backup
**Trigger:** same three commands as provisioning on a fresh server.
**Expected outcome:** identical to provisioning. All scripts are idempotent.
Certs are re-issued, images pulled from registry. No data migration needed
for stateless static sites.
## 3. Add a new static site
**Trigger:** `./tools/app.sh all example.com` from dev machine.
**Prerequisites:** domain nameservers on Vultr, `bws`/`jq`/`dig` installed.
**Expected outcome:**
- DNS A records created for bare + www
- Gitea repo `hantim/example.com` created from template
- Config files added: compose, nginx conf, deploy workflow
- SSL cert issued (zero downtime)
- Garage media bucket created with media-key access
- First build triggered
- `https://www.example.com` responds within 3 minutes
- UptimeRobot HTTPS monitor created (skipped if already exists)
- Site ready for customization via git clone + push
## 4. Update app code
**Trigger:** push to an app repo.
**Expected outcome:**
- Docker image built and pushed to registry
- Container restarted on server with new image
- No manual steps
## 5. Update Docker Compose config
**Trigger:** push compose file change to this repo.
**Expected outcome:**
- Path-matched workflow triggers
- Container restarted with updated config
## 6. Update nginx config
**Trigger:** push nginx conf change to this repo.
**Expected outcome:**
- Config tested with `nginx -t` before applying
- If test fails, running nginx is untouched
- If new certs needed, issued before applying config
- nginx reloaded with new config
## 7. Re-run configure
**Trigger:** push change to `scripts/configure.sh`, or run manually.
**Expected outcome:**
- All steps idempotent — safe to run anytime
- Existing certs skipped
- Services restarted
## 8. Add a new Docker service
**Trigger:** `./tools/service.sh all <name> <port>` from dev machine.
**Prerequisites:** `bws`/`jq`/`dig` installed.
**Expected outcome:**
- DNS A record created for `<name>.hantim.net`
- Compose file and deploy workflow scaffolded
- Nginx conf created proxying `<name>.hantim.net` to port `<port>`
- SSL cert issued for `<name>.hantim.net` (no www variant)
- Service ready for customization (edit compose.yml image, add `.env.keys` if needed)
## 9. Analytics tracking
**Trigger:** automatic — nginx injects the GoatCounter script into all HTML responses.
**Expected outcome:**
- Every site includes the GoatCounter tracking script (injected via `sub_filter`)
- Page views are recorded at `goatcounter.hantim.net`
- New sites provisioned with `app.sh` include tracking automatically
- GoatCounter dashboard itself is not tracked
## 10. Upload media files
**Trigger:** `aws s3 cp` or `aws s3 sync` to `s3://example.com/`, or `./media.sh push` from a site repo.
**Expected outcome:**
- File uploaded via S3 API (`s3.hantim.net`)
- Replicated to both Garage nodes (hantim + argento)
- Accessible at `https://www.example.com/media/<path>`
## 11. Local development with media files
**Trigger:** `./media.sh pull` from a site repo.
**Expected outcome:**
- Media files downloaded from Garage to `static/media/` (gitignored)
- Files served locally at `/media/` by the app container's nginx
- To upload local changes back to Garage: `./media.sh push`