Docs site custom domain (docs.nonlocally.org)¶
This site is a Material for MkDocs build published by .github/workflows/docs.yml: every
push to main that touches docs/**, mkdocs.yml or requirements-docs.txt runs
mkdocs build --strict and mkdocs gh-deploy, which pushes the built site to the
gh-pages branch that GitHub Pages serves. The site lives at
https://docs.nonlocally.org/; the GitHub-provided URL
https://englund-garage.github.io/openweb-marimo-platform/ redirects there, path included.
How the domain is wired¶
Three pieces, in three places:
| Piece | Where | Who changes it |
|---|---|---|
docs/CNAME containing docs.nonlocally.org |
this repo. MkDocs copies it to the site root, gh-deploy pushes it to gh-pages, and GitHub Pages reads the custom domain from it on every deploy |
anyone, through a PR |
DNS: docs.nonlocally.org CNAME englund-garage.github.io |
the nonlocally.org zone on Cloudflare, DNS only (grey cloud), TTL auto |
whoever holds that Cloudflare zone |
| TLS certificate and Enforce HTTPS | GitHub Pages provisions a Let's Encrypt certificate once the DNS check passes; the checkbox is under repository Settings → Pages | a repository admin |
Why DNS-only. GitHub issues and renews the certificate with an HTTP-01 challenge against
the hostname. Through Cloudflare's proxy that challenge is unreliable and Enforce HTTPS
can stay greyed out. mit.nonlocally.org is already DNS-only in the same zone.
Why a CNAME file rather than the settings page. The site publishes from a branch
(Pages build_type: legacy, source gh-pages, path /), and GitHub takes the custom
domain from the CNAME file at the root of that branch. Setting the domain in the UI commits
the same file to gh-pages, which the next gh-deploy --force --no-history would drop
again. Keeping it in docs/ makes the domain part of every deploy.
What moves with the origin¶
site_url in mkdocs.yml is the ONE browser origin the marimo-proxy feedback relay trusts
(DOCS_SITE_URL in k8s/marimo_proxy.py, route-scoped CORS on /api/marimo/feedback);
tests/unit/test_docs_feedback.py pins the two together, so a domain change is one PR that
touches both. The same PR carries every link to the feedback form and the docs:
docs/javascripts/feedback.js, the workspace wrapper (k8s/workspace/index.html and the
ConfigMap copy in k8s/marimo-editor-deployment.yaml), marimo_tools.py
(DOCS_FEEDBACK_URL), the Open WebUI banner (k8s/openwebui-ui-config.json) and the
models landing page (k8s/models-landing/index.html; regenerate the yaml with
python3 scripts/build_models_landing.py).
After the merge:
docsworkflow: builds and pushesgh-pageswith theCNAMEfile. Automatic.build-imagesthendeploy-staging → production: rebuilds the marimo-proxy image (the relay's new default origin) and rolls it out. Automatic; the pipeline recreates the marimo editor once (about 3–4 minutes of 502, measured in #584).- Banner:
python3 scripts/sync_ui_config.py --apply(admin key; the script plans by default). - Tool file: redeploy
marimo_tools.py(thedeploy-toolskill /kubectl cp). - Models landing:
kubectl apply -f k8s/models-landing/models-landing.yaml.
The last three are cosmetic until they happen: the old GitHub URL redirects to the new domain, so stale links keep working.
Cutover order¶
- DNS record first. Until
docs.nonlocally.orgresolves, a deployedCNAMEmakes GitHub redirect the old URL to a name that does not exist. The site would be down for exactly that window. - Merge the PR that adds
docs/CNAMEand movessite_url. The docs workflow runs on the merge and the Pages custom domain follows. -
Certificate, then Enforce HTTPS. GitHub requests the certificate once its DNS check passes (minutes, up to an hour). A repository admin then ticks Enforce HTTPS (Settings → Pages), or:
gh api -X PUT repos/Englund-Garage/openweb-marimo-platform/pages -F https_enforced=true -
Verify the domain for the org (recommended). Organization settings → Pages → Add a domain →
nonlocally.org, then theTXTrecord GitHub shows at_github-pages-challenge-englund-garage.nonlocally.org. A verified domain, and its immediate subdomains, cannot be claimed by another GitHub account if the CNAME is ever left dangling.
Verify¶
dig +short docs.nonlocally.org CNAME # englund-garage.github.io.
curl -sI https://docs.nonlocally.org/ | head -1 # HTTP/2 200
curl -sI https://englund-garage.github.io/openweb-marimo-platform/feedback/ | grep -i '^location'
# location: https://docs.nonlocally.org/feedback/
curl -sI http://docs.nonlocally.org/ | grep -i '^location' # https://… once Enforce HTTPS is on
gh api repos/Englund-Garage/openweb-marimo-platform/pages \
--jq '{cname, https_enforced, protected_domain_state}'
# The relay trusts the new origin (after the proxy rollout): 204 with the allow-origin header.
curl -s -o /dev/null -D - -X OPTIONS https://mit.nonlocally.org/api/marimo/feedback \
-H 'Origin: https://docs.nonlocally.org' -H 'Access-Control-Request-Method: POST' \
-H 'Access-Control-Request-Headers: content-type' | grep -i 'HTTP/\|allow-origin'
FEEDBACK_E2E=1 OPENWEBUI_API_KEY=… pytest tests/goal/test_feedback_docs_relay.py -q
Rollback¶
Delete docs/CNAME and set site_url back to
https://englund-garage.github.io/openweb-marimo-platform/ (the relay default and the links
follow; the pinned tests say which). Merge: GitHub drops the custom domain on the next deploy
and the github.io URL serves again. Remove the DNS record too unless the domain is verified
for the org — a dangling CNAME is the takeover case step 4 guards against.