# Use Cases ## 1. Provision a new server Set up a fresh Rocky Linux 9 server from scratch. ```bash dnf install -y git git clone https://git.timothykim.net/hantim/hantim-server.git /opt/hantim bash /opt/hantim/scripts/bootstrap.sh ``` **What happens:** - Installs all dependencies (jq, certbot, unzip, Docker) - Installs `bws` CLI, prompts for Bitwarden Secrets Manager access token - Fetches registry token and deploy SSH public key via `bws` - Logs into Docker registry - Creates deploy user with restricted SSH + sudo - Runs `configure.sh`: - Opens firewall ports (HTTP, HTTPS, Garage RPC) - Issues SSL certs for all domains in `docker/nginx/conf.d/` - Starts nginx and all app containers **Prerequisites:** - DNS for all configured domains must point to the server - Bitwarden Secrets Manager access token for the `hantim-server` machine account - Docker images must exist in the Gitea registry (or apps will start on next push) ## 2. Restore from backup Identical to provisioning a new server. Run the same three commands on a fresh server. - `bootstrap.sh` and `configure.sh` are idempotent -- safe to re-run - SSL certs are re-issued automatically (Let's Encrypt) - Docker images are pulled from the Gitea registry - No data migration needed for stateless static sites ## 3. Add a new static site From your dev machine (single command): ```bash ./scripts/new-app.sh hcsuzuki.net ``` **Prerequisites:** - Bitwarden vault must contain `hantim-new-app-script`, `hantim-vultr-api-key`, and `hantim-server-deploy` - Domain nameservers must be pointed to Vultr (configured on directnic.com) - Dependencies: `bw`, `jq`, `dig` **What happens (fully automated):** 1. Resolves server IP from `hantim.net` 2. Fetches Gitea API token, Vultr API key, and deploy SSH key from Bitwarden 3. Creates DNS zone on Vultr (if needed) and A records for bare + www 4. Waits for DNS to propagate 5. Creates Gitea repo `hantim/hcsuzuki.net` from `static-site-template` 6. Creates local files: - `docker/hcsuzuki.net/compose.yml` (container name: `hcsuzuki_net`) - `.gitea/workflows/deploy-hcsuzuki.net.yml` - `docker/nginx/conf.d/hcsuzuki.net.conf` (HTTP->HTTPS, bare->www, proxy) 7. SSHes to server as deploy user, issues SSL cert via webroot (zero downtime) 8. Commits and pushes hantim-server (triggers deploy) 9. Triggers initial build of the app repo via Gitea API 10. Polls `https://www.hcsuzuki.net` until it responds (up to 3 minutes) After the site is live, clone the app repo and customize: ```bash git clone git@git.timothykim.net:hantim/hcsuzuki.net.git cd hcsuzuki.net # edit static/index.html, etc. git add . && git commit -m "initial content" && git push ``` ## 4. Update app code Push a change to the app repo (e.g., `timothykim.net`): ```bash cd timothykim.net # make changes git add . && git commit -m "update content" && git push ``` **What happens:** 1. Gitea Actions runs `build.yml`: builds Docker image, pushes to registry 2. SSHes into server, runs `deploy-timothykim.net` 3. `deploy.sh` pulls latest hantim-server, pulls new image, restarts container No manual steps needed. ## 5. Update Docker Compose config Edit a compose file in this repo and push: ```bash vim docker/timothykim.net/compose.yml git add docker/timothykim.net/compose.yml git commit -m "update timothykim.net config" git push ``` **What happens:** 1. `deploy-timothykim.yml` workflow triggers (path match) 2. `deploy.sh` pulls latest code, pulls image, runs `docker compose up -d` ## 6. Update nginx config Edit an nginx config in this repo and push: ```bash vim docker/nginx/conf.d/timothykim.net.conf git add docker/nginx/conf.d/timothykim.net.conf git commit -m "update nginx config" git push ``` **What happens:** 1. `deploy-nginx.yml` workflow triggers (path match) 2. `deploy.sh` pulls latest code 3. If any conf files reference certs that don't exist yet, nginx is briefly stopped and certs are issued via standalone certbot (auto-restarts on failure) 4. Tests nginx config with `nginx -t` -- if it fails, deploy aborts and the running nginx is untouched 5. Runs `docker compose up -d` and reloads nginx **Note:** Each conf file must contain server blocks for only one domain. The cert name is derived from the filename (e.g. `hcsuzuki.net.conf` -> cert `hcsuzuki.net`). Redirect-only domains like `hcsuzukiviolin.com` get their own conf file. ## 7. Re-run configure on existing server Safe to do at any time, manually or via CI: ```bash cd /opt/hantim git pull bash scripts/configure.sh ``` Or push a change to `scripts/configure.sh` — the `provision.yml` workflow triggers automatically. - All steps are idempotent - Existing certs are skipped - Brief nginx downtime (seconds) while certbot checks run - Services are restarted