diff --git a/deploy/stages.md b/deploy/stages.md new file mode 100644 index 0000000..8062a78 --- /dev/null +++ b/deploy/stages.md @@ -0,0 +1,103 @@ +# Stage provisioning on the VPS (188.245.116.44) + +Test and Int run as Compose stacks on the operator's VPS; DNS for +`*.dorfteich.cloud` already points there (deployment.md §Stages). Steps +marked **[root]** need host root access and are executed by the repo +owner; everything else can be done by CI or a deploy user. + +## Overview + +| Stage | Directory | Domain | Ports (localhost) | +| ----- | ------------------------------ | ---------------------- | ------------------ | +| Test | `/home/DOCKER/dorfteich-test/` | `test.dorfteich.cloud` | web 8100, api 8101 | +| Int | `/home/DOCKER/dorfteich-int/` | `int.dorfteich.cloud` | web 8110, api 8111 | + +## 1. Stage directories **[root]** + +```sh +for stage in test int; do + mkdir -p /home/DOCKER/dorfteich-$stage + mkdir -p /home/RAID/DOCKER/dorfteich-$stage # bulk data, if RAID exists on this host +done +``` + +Copy `deploy/compose/docker-compose.yml` and `.env.example` → `.env` into +each stage directory. Set per stage in `.env` (mode 600): + +- `POSTGRES_PASSWORD`: unique random value per stage +- `COMPOSE_PROJECT_NAME`: `dorfteich-test` / `dorfteich-int` +- `WEB_PORT`/`API_PORT`: 8100/8101 (test), 8110/8111 (int) +- `IMAGE_PREFIX=gitea.101010.cloud/stwaidele/dorfteich` +- `TAG`: managed by the CD pipeline (`` on test, `int` on int) + +## 2. Reverse proxy vhosts **[root]** + +Both vhosts terminate TLS and route by path; WebSocket upgrade on +`/collab` is required from milestone M3 on, configure it now. Caddy +example: + +```caddy +test.dorfteich.cloud { + handle /api/* { + reverse_proxy 127.0.0.1:8101 + } + handle /collab* { + reverse_proxy 127.0.0.1:8102 # collab service arrives with M3 + } + handle { + reverse_proxy 127.0.0.1:8100 + } +} +``` + +(nginx equivalent: `proxy_pass` per location; for `/collab` add +`proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade";`.) + +Int: same block with `int.dorfteich.cloud` and ports 8110/8111/8112. + +## 3. Gitea act_runner **[root]** + +The CI/CD workflows (`.gitea/workflows/`) need one act_runner on the VPS +with Docker access and the `ubuntu-latest` label: + +```sh +# 1. Download act_runner (https://gitea.com/gitea/act_runner/releases) +# 2. Registration token: Gitea → Site/Repo Settings → Actions → Runners +act_runner register \ + --instance https://gitea.101010.cloud \ + --token \ + --name vps-dorfteich \ + --labels ubuntu-latest:docker://ghcr.io/catthehacker/ubuntu:act-22.04 +# 3. Run as a systemd service (act_runner daemon), user in the docker group. +``` + +## 4. Deploy user and SSH keys + +The CD workflow (issue #8) deploys via SSH: +`ssh deploy@188.245.116.44 'cd /home/DOCKER/dorfteich-test && docker compose pull && docker compose up -d'`. + +- **[root]** Create a `deploy` user (or reuse an existing deployment + user), member of the `docker` group, owning the stage directories. +- Generate one ed25519 keypair per stage; public keys into + `deploy`'s `authorized_keys` (optionally with a `command=` restriction + to the compose command), private keys become the repository secrets + `DEPLOY_SSH_KEY_TEST` / `DEPLOY_SSH_KEY_INT`. + +## 5. Registry access + +The pipeline pushes images to the Gitea container registry +(`gitea.101010.cloud/stwaidele/dorfteich-{web,api,collab}`): + +- Repository secret `REGISTRY_TOKEN`: a Gitea access token with + `write:package` scope (owner `stwaidele` or a CI account). +- On the VPS, `docker login gitea.101010.cloud` for the `deploy` user + with a `read:package` token, so `compose pull` works. + +## 6. Verification checklist + +- [ ] `https://test.dorfteich.cloud/healthz` → `ok` +- [ ] `https://test.dorfteich.cloud/api/v1/readyz` → `{"status":"ok",…}` +- [ ] same for int +- [ ] runner shows _online_ under Gitea → Settings → Actions → Runners +- [ ] a test workflow run executes on the runner +- [ ] `.env` files are mode 600, owned by `deploy`