replace NPM with vanilla nginx + certbot
- nginx:alpine replaces nginx-proxy-manager - certbot on host with standalone issuance and auto-renewal - per-site nginx configs in conf.d/ (HTTP->HTTPS, bare->www) - container names use underscores (timothykim_net) - setup.sh: automated cert issuance, dynamic app startup - deploy.sh: nginx -t guard, graceful image-not-found - new-app.sh: Gitea API repo creation, nginx conf generation - add ARCHITECTURE.md, USECASES.md, CLAUDE.md - remove old NPM data/certs from tracking
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
# 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` -- Scaffolds a new static site (Gitea repo + compose + workflow + nginx conf)
|
||||
- `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)
|
||||
|
||||
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, then issue SSL cert on
|
||||
server **before** pushing. See USECASES.md for full steps.
|
||||
|
||||
### 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
|
||||
Reference in New Issue
Block a user