Helios Operations Guide¶
Deployment¶
Deploy to server¶
# Dev (from develop branch)
make deploy ENV=dev
# Staging
make deploy ENV=staging
# Production (requires a tag)
git tag v1.0
git push --tags
make deploy ENV=prod REF=v1.0
Quick deploy (skip git fetch)¶
Local development¶
npm run dev # Start dev server (localhost:3000)
npm run build # Production build
npm run lint # ESLint
Key Configuration¶
Environment variables¶
| Variable | Where | Purpose |
|---|---|---|
ALETHEIA_API_URL |
.env (server) |
Server-side API URL (Docker container name) |
NEXT_PUBLIC_ALETHEIA_API_URL |
.env (server) |
Client-side API URL (contact form POST) |
REVALIDATION_SECRET |
.env (server) |
ISR webhook auth (must match Aletheia) |
NEXT_PUBLIC_HCAPTCHA_SITEKEY |
.env (server) |
hCaptcha widget (leave empty to disable) |
NEXT_PUBLIC_UMAMI_URL |
.env (server) |
Umami analytics script URL |
NEXT_PUBLIC_UMAMI_WEBSITE_ID |
.env (server) |
Umami website ID |
Domain configuration¶
Domain → practice mapping is defined in two places:
src/lib/practices.ts— Single source of truth. Bothproxy.tsandapi.tsderive their maps from this.- Nginx vhosts —
server_namedirectives (in Aethernginx/conf.d/,/opt/docker/aether/repo/)
When adding a new practice: add one entry to practices.ts, update nginx vhosts.
SEO protection¶
Non-production domains are blocked from indexing in two places:
src/app/robots.ts—PRODUCTION_DOMAINSwhitelistsrc/app/layout.tsx—PRODUCTION_DOMAINSwhitelist (adds<meta name="robots" content="noindex">)
Both must be updated when a practice domain goes live.
Content Updates¶
Content is managed in Aletheia at /websites/:
- Pages:
/websites/pages/— create/edit pages with content blocks - Config:
/websites/config/— per-practice theme, SEO, domain settings - Media: upload images/videos via the page editor
Content update flow¶
- Edit content in Aletheia
/websites/ - Publish the page (draft → published)
- If ISR revalidation is configured (A5): page updates automatically
- If not: redeploy Helios to pick up new content (
make deploy ENV=prod REF=...)
Troubleshooting¶
Pages show stale content¶
Content is cached at build time (SSG). Options:
- Redeploy: make deploy ENV=prod REF=...
- Once A5 is built: publishing in Aletheia triggers ISR revalidation automatically
New practice shows 404¶
Check domain mappings:
1. src/lib/practices.ts — PRACTICES array
2. Nginx vhost — server_name
Contact form returns error¶
- Check Aletheia is running and
/api/v1/websites/sites/{domain}/contact/endpoint responds - Check
NEXT_PUBLIC_ALETHEIA_API_URLenv var is set and reachable from browser - Check browser console for CORS errors
- Check
hcaptcha_token— if hCaptcha isn't configured in Aletheia, token validation must be skipped
Dynamic theme not applying¶
- Check
SiteConfig.themehas validprimary_hue,primary_chroma,accent_hue,accent_chroma - Inspect
<html style="...">— should have inline OKLCH variables - Dev server needs restart to pick up new
NEXT_PUBLIC_*env vars
Nav dropdown not working on LAN IP¶
Dev-mode-only issue: Turbopack HMR doesn't hydrate React on non-localhost IPs.
Works in production builds (npm run build && npx next start).
Use localhost:3000 for dev testing of interactive features.