# Test site: cnxvinyl.lol `https://cnxvinyl.lol/` is the internal test site for this repository: demo pages from `docs/` (the [plant operation page](../docs/plant-operation.html) first) and any static site we want to show by link. It runs on the same web server as buildfor.life (Debian VPS `s1`, Caddy behind Cloudflare) and is not a plant service; plant systems follow the [digital factory plan](../docs/digital-factory.md). Every page and file is sent with `noindex` and `robots.txt` disallows everything; nothing is behind a login unless `basic_auth` in the Caddyfile is switched on. ## How it is built - `public/` is copied verbatim to the web root: the landing page (`index.html`), `robots.txt`, and any static site as its own directory (`public//index.html` is served at `//`). - `build.sh` assembles `site/dist`: `public/` plus every entry in its `DEMOS` list, which copies a page out of `docs/` (for example `docs/plant-operation.html` to `/demos/plant-operation/`), so the docs stay the one source. It writes `version.txt` (the commit) and fails on any internal link that does not resolve. - To add a demo: one line in `DEMOS`, one entry on the landing page. To add a static site: drop its built output in `public//` and link it. - Local preview: `bash site/build.sh`, then open `site/dist/index.html`. ## How it is deployed `.gitea/workflows/deploy-site.yml` runs on every push to `master` that touches `site/`, an HTML page under `docs/`, or the workflow itself, and on demand (Actions tab, "Run workflow"). It builds, rsyncs `site/dist` into the idle one of `/var/www/cnxvinyl.lol` and `/var/www/cnxvinyl.lol-prev`, swaps them by rename (the blog's pattern), checks `version.txt` on the server, purges the Cloudflare cache when the token is set, and finally checks the public URL (warning only). The deploy owns the whole web root: anything put into `/var/www/cnxvinyl.lol` by hand disappears on the next deploy. Static sites go into `public/` instead. ## One-time setup 1. DNS in Cloudflare, both proxied (orange cloud): `cnxvinyl.lol CNAME s1.buildfor.life` and `www CNAME cnxvinyl.lol` (Cloudflare flattens the apex CNAME, so the site follows s1 if its address changes). SSL/TLS mode **Full (strict)**: "Flexible" makes a redirect loop with Caddy. 2. Caddy on s1: append [`Caddyfile`](Caddyfile) to `/etc/caddy/Caddyfile` (the comments in it list the checks), `caddy validate`, then `systemctl reload caddy`. Caddy gets the certificate the same way it does for the buildfor.life apex. 3. Web root: the deploy user must be able to create and rename directories in `/var/www`, as it already does for the blog. If not: `sudo install -d -o /var/www/cnxvinyl.lol /var/www/cnxvinyl.lol-prev` and make `/var/www` writable for that user (the swap renames entries in it). 4. Secrets in Gitea (repo: Settings > Actions > Secrets, or user level so every repo of the account gets them): `VPS_HOST`, `VPS_USER`, `VPS_SSH_KEY`, optionally `VPS_PORT` (default 22), `VPS_KNOWN_HOSTS` (output of `ssh-keyscan -p s1.buildfor.life`, pins the host key), `CLOUDFLARE_ZONE_ID` and `CLOUDFLARE_API_TOKEN` (Zone > Cache Purge on cnxvinyl.lol). The names match the blog's workflow, so the blog's deploy key and values work unchanged: s1 only checks the key against the deploy user's `authorized_keys`, whichever repository sends it. Gitea secrets cannot be read back, so they are entered again here from the private key file; repo secrets set on `B4L/buildfor_life_web` do not reach this repository, B4L organisation secrets only reach it if it moves into B4L. The blog key is `deploy@s1.b4l.co.th`, fingerprint `SHA256:o4w7HL+EsPI3MXbbcYWGn0EykN7qeLtYg0Tc9FI1a3s`, and it is the only key in `/home/deploy/.ssh/authorized_keys` on s1 (sshd on port 2255, so `VPS_PORT` is 2255). The deploy log prints the fingerprint of the key in `VPS_SSH_KEY`; if it differs, the server answers "Permission denied (publickey)". If the private key is gone, make a new key instead: `ssh-keygen -t ed25519 -N "" -C cnx_vinyl-deploy -f cnx_vinyl-deploy`, public half into the deploy user's `~/.ssh/authorized_keys` on s1, private half into `VPS_SSH_KEY`, then delete the local copy. 5. Runner: the job asks for `ubuntu-latest`, the label the blog's runner serves. This repository is under a user account, not the B4L organisation, so a runner registered only for B4L does not pick it up; if the run stays "Waiting", register the runner for this repository or instance-wide, or move the repository into B4L. 6. Run the workflow once from the Actions tab and open `https://cnxvinyl.lol/`.