# NextWorkspace — Agent Workflow Instructions ## Versioning - Format: `MILESTONE.FEATURE.PATCH.BUILD` (e.g., `0.1.0.0032`) - Bump VERSION file on every change before commit. - Every commit must be tagged with the version: `git tag v$(cat VERSION)` ## Deployment Model (Unified Script) The project uses a single unified script at `tools/nextwks.sh` for all operations. The old `deploy.sh` and `install.sh` are deprecated. **Key principles:** - Source of truth is **git remote only**. No local `/opt/NextWks` repo. - Building happens in `/tmp/nextwks-build/` via `git clone --depth 1` (fresh every time). - Runtime goes to `/opt/nextworkspace/` (configs, compose, binary, lng). - Secrets persist in `/opt/backup/.env` and survive `--destroy`. - Stack runs on a shared `nextwks-net` podman bridge network. ### Script Flags | Flag | What it does | |------|-------------| | `--install` | First-time setup on a bare VM: installs deps, prompts for config, builds binary, generates configs, deploys stack | | `--update` | Smart update: clones fresh, rebuilds binary, copies to target, bounces containers | | `--destroy` | Full greenfield redeploy: tears down containers, wipes `/opt/nextworkspace/`, rebuilds from scratch using saved secrets from `/opt/backup/.env` | ### Workflow for Making Changes 1. Edit code in the development clone. 2. Test locally (e.g., `go build && go run .`). 3. Bump `VERSION` (increment BUILD). 4. Update `CHANGELOG.md`. 5. Commit: `git add -A && git commit -m "description"` 6. Tag: `git tag v$(cat VERSION)` 7. Push: `git push origin main --tags` 8. Deploy: `./nextwks.sh --update` (no sudo — script handles it per-command) > **Note:** The deploy script is downloaded by users via `curl` from the repo. For production deployment, users run: > ```bash > curl -sL https://git.lohmar.co.uk/lexton-it/NextWks/raw/branch/main/tools/nextwks.sh | sudo bash -s -- --install > ``` ## Build Process - Static Go binary: `CGO_ENABLED=0 go build -o nextworkspace .` - Must run on Alpine in the container (no glibc dependency). - Binary runs as PID 1 in the `launcher` container. ## Architecture ``` Caddy (:80/:443, host ports) ├── auth.{DOMAIN} → Authelia :9091 (internal) ├── app.{DOMAIN} → Launcher :9000 (internal) with forward auth └── www.{DOMAIN} → static files All three containers on nextwks-net (podman bridge). Only Caddy exposes ports to host. ``` ## Config Template System Config files use `{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}` (same as `SESSION_SECRET`) | ## Env Vault (`/opt/backup/.env`) Persisted secrets across destroys: ``` DOMAIN=nextwks.eu TLS_EMAIL=admin@nextwks.eu ADMIN_USERNAME=master ADMIN_PASSWORD= SMTP_HOST=smtp.openxchange.eu SMTP_PORT=587 SMTP_USER=post@nextwks.eu SMTP_PASS= JWT_SECRET= SESSION_SECRET= STORAGE_ENCRYPTION_KEY= ADMIN_PASSWORD_HASH= ``` ## Health Check After deploy, the script polls `podman exec launcher wget -qO- http://127.0.0.1:9000/health` up to 10 times (2s interval). Expected response: `OK`. ## Commit Message Style - Imperative mood ("Add", "Fix", "Update", "Bump") - Reference the component if relevant ("launcher: add health endpoint") - Keep under 72 chars for the first line