NextWks/AGENT.md

82 lines
3.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# NextWorkspace — Architecture & Workflow
## Deployment Model
Single unified script: **`tools/nextwks.sh`** (replaces old `deploy.sh`/`install.sh`).
| Flag | When to use |
|------|------------|
| `--install` | First-time setup on a bare VM (prompts for config) |
| `--update` | Rebuild & restart with latest code (uses saved secrets) |
| `--destroy` | Full greenfield redeploy (tears down everything, rebuilds from `/opt/backup/.env`) |
**Run WITHOUT sudo.** The script invokes `sudo` only where needed (apt, writing to `/opt/`, iptables).
## Key Architecture Decisions
### 1. Rootless Podman (no sudo for containers)
All `podman` / `podman-compose` commands run as the normal user. Containers are rootless.
- Caddy binds to host ports **8080** and **8443** (not 80/443 — unprivileged)
- iptables `PREROUTING` + `OUTPUT -o lo` redirect 80→8080, 443→8443
- Firewall rules applied by `tools/firewall-routing.sh`, persisted via `netfilter-persistent`
### 2. Ephemeral Build Directory
- Fresh `git clone --depth 1` into `/tmp/nextwks-build/` every time
- No persistent `/opt/NextWks` repo (eliminates git permission issues)
- Binary + configs built as user, then `sudo cp` to `/opt/nextworkspace/`
### 3. File Ownership
All files in `/opt/nextworkspace/` and `/opt/backup/` are `chown -R` to the non-root user after every deploy.
### 4. Config Templates with Placeholder Substitution
Config files live in git with `{PLACEHOLDER}` syntax. The script substitutes values at deploy time:
| File | Placeholders |
|------|-------------|
| `config/caddy/Caddyfile` | `{DOMAIN}`, `{TLS_EMAIL}` |
| `config/authelia/configuration.yml` | `{DOMAIN}`, `{JWT_SECRET}`, `{SESSION_SECRET}`, `{STORAGE_ENCRYPTION_KEY}`, `{SMTP_HOST}`, `{SMTP_PORT}`, `{SMTP_USER}`, `{SMTP_PASS}` |
| `config/authelia/users_database.yml` | `{ADMIN_PASSWORD_HASH}`, `{TLS_EMAIL}` |
| `compose/stack.yaml` | `{AUTHELIA_SECRET}` (= `SESSION_SECRET`) |
Configs are regenerated on **every** run (install, update, destroy) from templates + saved secrets.
### 5. Secrets Vault (`/opt/backup/.env`)
All values are single-quoted to protect `$` signs (bcrypt hashes). Survives `--destroy`. Sourced with `set +u` to avoid errors from `$` in values.
### 6. Container Lifecycle
Containers are stopped **before** copying the new binary (avoids "Text file busy"). Restarted after deploy.
---
## Network Architecture
```
Internet :443 → [iptables REDIRECT] → host :8443 → [Caddy container :443]
Internet :80 → [iptables REDIRECT] → host :8080 → [Caddy container :80]
Caddy (rootless, nextwks-net)
├── auth.{DOMAIN} → Authelia :9091 (internal, no host port)
├── app.{DOMAIN} → Launcher :9000 (internal, forward auth via Authelia)
└── www.{DOMAIN} → static files
```
All three containers on `nextwks-net` (rootless podman bridge).
Only Caddy has host ports (8080, 8443). Authelia and Launcher are internal-only.
## Firewall (`tools/firewall-routing.sh`)
- NAT redirects: 80→8080, 443→8443
- INPUT rules: allow lo, established, SSH (22), Caddy ports (8080, 8443), app ports (8000)
- Global DROP at end for all other unsolicited inbound
- Persisted: `netfilter-persistent save` (runs on every deploy mode)
## Versioning
- Format: `MILESTONE.FEATURE.PATCH.BUILD` (e.g., `0.1.0.0032`)
- Bump VERSION, update CHANGELOG.md, `git tag v$(cat VERSION)` on every change
## Workflow
1. Edit code in dev clone
2. `git commit -m "msg" && git tag v$(cat VERSION) && git push origin main --tags`
3. On server: `./nextwks.sh --update`
## Health Check
The script polls `podman exec launcher curl -sf http://127.0.0.1:9000/health` up to 15×3s. Launcher container uses `alpine:latest` with `curl` installed at startup via `apk add --no-cache curl`.