Files
hantim-server/CLAUDE.md
T
timothykim b51fe596c6 automate new-app.sh: DNS, cert, commit, build, verify
- resolve server IP from hantim.net instead of env var
- create Vultr DNS zone and A records via API
- wait for DNS propagation before cert issuance
- issue SSL cert via webroot (zero downtime)
- auto commit and push hantim-server
- trigger initial app build via Gitea API
- verify site is live with curl check
- update all docs to reflect single-command flow
2026-03-16 01:57:10 -04:00

2.8 KiB

CLAUDE.md

Project overview

Server provisioning and app management for the hantim webserver. This repo lives at /opt/hantim on the production server (Rocky Linux 9 on Vultr) and manages Docker Compose configs, deploy scripts, nginx configs, and Gitea Actions workflows.

Key files

  • setup.sh -- Server provisioning (idempotent, run as root)
  • scripts/deploy.sh -- SSH-triggered deploy (validates command, pulls, restarts)
  • scripts/new-app.sh -- Single-command new app (DNS + Gitea repo + cert + deploy + verify)
  • docker/nginx/ -- Reverse proxy (nginx:alpine + certbot on host)
  • docker/<domain>/compose.yml -- Per-app compose files
  • .gitea/workflows/deploy-<app>.yml -- Per-app deploy workflows

Conventions

  • App name = domain (e.g., hcsuzuki.net)
  • Container name = domain with dots replaced by underscores (e.g., hcsuzuki_net)
  • Image = git.timothykim.net/hantim/<domain>:latest
  • Cert name = domain (at /etc/letsencrypt/live/<domain>/)
  • All HTTP redirects to HTTPS; bare domain redirects to www.<domain>
  • The shared Docker network is created by nginx compose and used by all apps

Secrets

Stored in Bitwarden (free tier), fetched via bw CLI:

  • hantim-git-crypt-key -- Secure Note (base64)
  • hantim-ci-registry-push -- Secure Note (Gitea registry token)
  • hantim-server-deploy -- SSH Key (deploy user key pair)
  • hantim-new-app-script -- Secure Note (Gitea API token for creating repos)
  • hantim-vultr-api-key -- Secure Note (Vultr API key for DNS management)

Gitea org-level (hantim) secrets/variables:

  • DEPLOY_HOST -- Variable (server IP)
  • DEPLOY_SSH_KEY -- Secret (deploy SSH private key)
  • CI_REGISTRY_TOKEN -- Secret (registry token)

Working with this repo

Adding a new app

Run ./scripts/new-app.sh <domain> from dev machine. Handles everything: DNS, Gitea repo, SSL cert, commit/push, build trigger, and verification. See USECASES.md for full details.

Editing scripts

All shell scripts use set -euo pipefail. Keep all steps idempotent. setup.sh must be safe to re-run on an existing server.

Deploy flow

App repo push -> build.yml builds image, pushes to registry, SSHes to server -> deploy.sh pulls repo, pulls image, restarts container.

Infrastructure push (this repo) -> deploy-<app>.yml triggers on path match -> same deploy.sh flow. nginx deploys test config with nginx -t first.

Build and test

No build step. No tests. Verify changes by:

  1. Reading scripts and checking idempotency
  2. Walking through each use case in USECASES.md
  3. Cross-checking documentation (README.md, ARCHITECTURE.md, USECASES.md) against scripts

Commit style

  • Short, lowercase commit messages (e.g., "add hcsuzuki.net", "fix deploy command")
  • Do NOT include "Co-Authored-By" lines
  • Commit only when explicitly asked