Test site: DNS moves to the fleet nameservers, no Cloudflare proxy
Deploy test site / deploy (push) Successful in 1m4s

cnxvinyl.lol's zone now lives in cnx-network-clan (ns1/ns2.cnx.network),
pointing straight at s1; mail is on mx1. Live once the nameservers at
Porkbun are switched.

- site/Caddyfile mirrors what s1 runs (checked 2026-10-23): no
  cloudflare_only or security_headers imports; Caddy gets its own certs.
- deploy-site.yml: drop the Cloudflare cache purge step and its secrets.
- site/README.md and digital-factory.md: DNS and certificate notes.
This commit is contained in:
grabowski committed 2026-10-23 11:01:55 +07:00
1 parent 1f532d0c85
commit f6829417a0
4 files changed
+19 -47

No files matched your search

+1 -21
View File
@@ -10,9 +10,6 @@ name: Deploy test site
# VPS_PORT optional, default 22
# VPS_KNOWN_HOSTS optional pinned host key line(s);
# without it the key is scanned per run
# CLOUDFLARE_ZONE_ID, CLOUDFLARE_API_TOKEN
# optional; cache purge for cnxvinyl.lol
# (token needs Zone > Cache Purge)
on:
push:
@@ -111,25 +108,8 @@ jobs:
echo "live on server: $live"
[ "$live" = "$(cat site/dist/version.txt)" ] || { echo "::error::server holds $live, expected $(cat site/dist/version.txt)"; exit 1; }
- name: Purge Cloudflare cache
env:
CLOUDFLARE_ZONE_ID: ${{ secrets.CLOUDFLARE_ZONE_ID }}
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
run: |
if [ -z "$CLOUDFLARE_ZONE_ID" ] || [ -z "$CLOUDFLARE_API_TOKEN" ]; then
echo "::warning::CLOUDFLARE_ZONE_ID / CLOUDFLARE_API_TOKEN not set; skipping cache purge"
exit 0
fi
response=$(curl -sS -X POST \
"https://api.cloudflare.com/client/v4/zones/$CLOUDFLARE_ZONE_ID/purge_cache" \
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{"purge_everything":true}')
echo "$response"
echo "$response" | grep -q '"success":\s*true' || { echo "::error::Cloudflare cache purge failed"; exit 1; }
- name: Check the public URL
# Warning only: DNS, Cloudflare or a basic_auth login can make this
# Warning only: DNS or a basic_auth login can make this
# fail while the files on the server are already correct.
run: |
expected=$(cat site/dist/version.txt)
+2 -1
View File
@@ -1003,7 +1003,8 @@ Build onward, part-time at launch; add it to the headcount.
- Customer portal domain: the plant's brand domain (new zone on ns1/ns2,
second cert on `web01`) or a name under `cnx.network` for launch.
Internal testing has its own domain, `cnxvinyl.lol` (registered
2026-10-02, DNS on Cloudflare): a static demo site built from
2026-10-02 at Porkbun; DNS moved from Cloudflare to the fleet nameservers
ns1/ns2 in October 2026, mail on `mx1`): a static demo site built from
[`site/`](../site/README.md) and served by the buildfor.life web server,
not a plant service. The brand domain decision stays open.
- Portal availability during a plant WAN outage: accept it (the portal is
+6 -12
View File
@@ -2,22 +2,17 @@
# Static web root /var/www/cnxvinyl.lol, filled by
# .gitea/workflows/deploy-site.yml in the cnx_vinyl repo.
#
# Append these blocks to /etc/caddy/Caddyfile on s1. They reuse the
# cloudflare_only and security_headers snippets defined there for
# buildfor.life (buildfor_life_web: infra/caddy/Caddyfile.example); if
# they are missing, validate fails with "File to import not found:
# cloudflare_only" and they have to be copied in from the example first.
# Append these blocks to /etc/caddy/Caddyfile on s1, then
# caddy validate --config /etc/caddy/Caddyfile
# systemctl reload caddy
# This file mirrors what s1 runs (checked 2026-10-23); keep the two in step.
#
# Cloudflare: both names proxied (orange cloud), SSL/TLS mode "Full (strict)".
# "Flexible" sends plain HTTP to Caddy, which redirects to HTTPS: a loop.
# Same rule as the buildfor.life apex: if a record is ever switched to DNS
# only, remove "import cloudflare_only" first or that name goes dark.
# DNS: the cnxvinyl.lol zone lives in the cnx-network-clan repo
# (modules/dns/zones/cnxvinyl.lol.zone, served by ns1/ns2.cnx.network) and
# points straight at s1, not through Cloudflare. Caddy gets its own
# certificates (HTTP-01/TLS-ALPN on 80/443), so no Cloudflare-only rule.
cnxvinyl.lol {
import cloudflare_only
import security_headers
header X-Frame-Options "SAMEORIGIN"
# Internal testing: keep every page and file out of search engines.
header X-Robots-Tag "noindex, nofollow"
@@ -35,6 +30,5 @@ cnxvinyl.lol {
}
www.cnxvinyl.lol {
import cloudflare_only
redir https://cnxvinyl.lol{uri} permanent
}
+10 -13
View File
@@ -3,7 +3,7 @@
`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
server as buildfor.life (Debian VPS `s1`, Caddy; not 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
@@ -30,8 +30,7 @@ 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).
server, 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
@@ -39,15 +38,14 @@ 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.
1. DNS: the zone is in the cnx-network-clan repo
(`modules/dns/zones/cnxvinyl.lol.zone`, served by `ns1`/`ns2.cnx.network`,
October 2026; until then it was Cloudflare): apex A/AAAA straight at s1
and `www CNAME cnxvinyl.lol`. If s1's address changes, change it there.
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.
`systemctl reload caddy`. Caddy gets its own certificates over
HTTP-01/TLS-ALPN (ports 80 and 443 are open on s1).
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 <deploy user> /var/www/cnxvinyl.lol /var/www/cnxvinyl.lol-prev`
@@ -56,9 +54,8 @@ go into `public/` instead.
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 <port> 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
(output of `ssh-keyscan -p <port> s1.buildfor.life`, pins the host key).
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