Files
hantim-server/README.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

115 lines
3.9 KiB
Markdown

# hantim-server
Server provisioning and app management for the hantim webserver. This repo
lives at `/opt/hantim` on the server and contains Docker Compose configs, deploy
scripts, nginx configs, and Gitea Actions workflows for each app.
## Repo structure
```
docker/
nginx/ # Reverse proxy (nginx:alpine) + SSL config
nginx.conf # Main nginx config
conf.d/ # Per-app server blocks (e.g. timothykim.net.conf)
compose.yml
timothykim.net/ # timothykim.net static site
compose.yml
scripts/
deploy.sh # Deploy script (validates command, git pull, docker compose up)
new-app.sh # Scaffolding script to add a new app
setup.sh # Server provisioning script (idempotent)
.gitea/workflows/ # Per-app deploy workflows triggered by path changes
```
## Provisioning a new server
On a fresh Rocky Linux 9 install:
```bash
dnf install -y git
git clone https://git.timothykim.net/hantim/hantim-server.git /opt/hantim
bash /opt/hantim/setup.sh
```
`setup.sh` is fully automated and idempotent. It:
1. Installs system dependencies (git-crypt, jq, certbot, Node.js 20, Docker)
2. Installs and authenticates the Bitwarden CLI
3. Unlocks git-crypt using a key stored in Bitwarden
4. Fetches the Docker registry token and deploy SSH public key from Bitwarden
5. Logs into the Gitea Docker registry
6. Creates the `deploy` user with restricted SSH access and sudo
7. Issues SSL certificates via certbot for all configured domains
8. Starts all services (nginx first, then all apps)
**Prerequisites**: DNS for all configured domains must point to the server
before running setup.
## Adding a new app
```bash
./scripts/new-app.sh <domain>
```
Example: `./scripts/new-app.sh hcsuzuki.net`
This single command handles everything: creates DNS records on Vultr, creates
the Gitea repo from `static-site-template`, generates all config files, issues
the SSL cert (zero downtime), commits and pushes, triggers the first build,
and verifies the site is live.
**Prerequisites:** domain nameservers pointed to Vultr, `bw`/`jq`/`dig`
installed, SSH access to the server. See USECASES.md for full details.
After the site is live, clone the app repo and customize it:
```bash
git clone git@git.timothykim.net:hantim/<domain>.git
cd <domain>
# edit content
git add . && git commit -m "initial content" && git push
```
## Deploying changes
**App code change** (push to an app repo like `timothykim.net`):
- The app's `build.yml` builds the Docker image, pushes to the registry, and
SSHes into the server to trigger a deploy
**Compose or nginx config change** (push to this repo):
- Gitea Actions workflows trigger based on which `docker/<app>/` paths changed
- `deploy.sh` pulls the latest code and runs `docker compose up -d`
- For nginx deploys, the config is tested before applying to prevent downtime
## Restoring from backup
Run the same three commands as provisioning. `setup.sh` is idempotent:
- Existing packages are skipped
- Existing certs are skipped (or re-issued if the server is new)
- All services are started
## Secrets
The following are stored in Bitwarden and fetched automatically by `setup.sh`:
| Bitwarden item | Type | Purpose |
|---|---|---|
| `hantim-git-crypt-key` | Secure Note | git-crypt symmetric key (base64) |
| `hantim-ci-registry-push` | Secure Note | Gitea token for Docker registry |
| `hantim-server-deploy` | SSH Key | Deploy user's SSH key |
The following are configured in the `hantim` Gitea org settings:
| Name | Type | Purpose |
|---|---|---|
| `DEPLOY_HOST` | Variable | Server IP or hostname |
| `DEPLOY_SSH_KEY` | Secret | SSH private key for the deploy user |
| `CI_REGISTRY_TOKEN` | Secret | Gitea token for Docker registry login |
The following are stored in Bitwarden and used by `new-app.sh`:
| Bitwarden item | Type | Purpose |
|---|---|---|
| `hantim-new-app-script` | Secure Note | Gitea API token for creating repos |
| `hantim-vultr-api-key` | Secure Note | Vultr API key for DNS management |