README

Last updated 17 Oct 2025, 13:40

Zenpower Landing

Operator Quickstart: see docs/ops-quickstart.md

Minimal static landing page served via Nginx. Optional service behind Traefik at host www.${DOMAIN}.

Modernisation in flight

  • Astro/Vite source lives under src/; keep the existing site/ HTML as a fallback until the Astro build hardens.
  • Documentation categories come from docs/index.json (generated via python tools/docs/build_docs.py).
  • Demoscene theme (hypergrid canvas, scanlines, neon palette) honours prefers-reduced-motion.
  • Build locally with npm ci --prefer-offline --no-audit followed by npm run build; avoid long installs inside short CLI sessions.

Previewing the Astro bundle

make landing-build-astro          # npm ci + astro build → apps/landing/dist/
COMPOSE_PROFILES=reverse-proxy,landing-preview make landing-preview-up
make landing-preview-check        # curl headers for https://astro-preview.${DOMAIN}

Stop the preview with make landing-preview-down. Traefik issues TLS via the existing letsencrypt resolver; ensure DNS for astro-preview.${DOMAIN} points at the Traefik entrypoint before enabling.

Variant builds

make landing-build-test           # outputs apps/landing/dist-test/ (test.zenpower.at)
make landing-build-demo           # outputs apps/landing/dist-demo/ (demo.zenpower.at)
make landing-build-social         # outputs apps/landing/dist-social/ (social.zenpower.at)
COMPOSE_PROFILES=reverse-proxy,landing-test make landing-preview-test
COMPOSE_PROFILES=reverse-proxy,landing-demo make landing-preview-demo
COMPOSE_PROFILES=reverse-proxy,landing-social make landing-preview-social

Stop the variant previews with make landing-preview-down-test, make landing-preview-down-demo, and make landing-preview-down-social. Update DNS for test.${DOMAIN}, demo.${DOMAIN}, and social.${DOMAIN} once you are ready to expose the sandboxes.

Production deploy

make landing-deploy                # workspace prep → astro builds for core/test/demo/social → traefik+landing reload

The deploy helper will:

  • refresh workspace metadata (fetch vendor snapshots, regenerate docs/status/workspace_prep.*);
  • run npm run build four times with PUBLIC_SITE_MODE={core,test,demo,social} so the container ships all surfaces from a single nginx image;
  • rebuild the landing image via the multi-stage Dockerfile and restart Traefik/landing with fresh labels for every subdomain (www, apex, status, docs, mcp, sso, test, demo, social).

Use make web-check after deployment to confirm HTTPS responses, and docker compose --env-file .env -f infra/docker-compose.yml ps landing if you need to inspect the running container.

Quick start (local via Compose)

  • Ensure .env has DOMAIN set (e.g., example.com).
  • Start stack with profile: COMPOSE_PROFILES=web docker compose -f infra/docker-compose.yml up -d landing traefik
  • Open https://www.${DOMAIN} (if DNS points locally, use /etc/hosts for testing).

Notes

  • Security headers and HTTPS handled by Traefik middlewares and certs.
  • The Astro bundle reuses the same copy as the legacy static HTML; both versions remain until rollout checklists pass.
  • The waitlist form stays non-persistent; hook it up via API before flipping the feature flag.

Security hardening

  • Traefik adds HSTS, X-Frame-Options, nosniff, and a landing-only CSP (default-src 'self'; ...).
  • A well-known security.txt is served at /.well-known/security.txt.
  • robots: prelaunch default is noindex via X-Robots-Tag header and robots.txt set to disallow all. Remove before public launch.

Managing Host Services (Home Ops)

Use monorepo ops targets (delegating to ~/ops-state) for local bring-up and health:

make ops-preflight
make ops-up-reverse-proxy
make ops-up-web
make ops-health-local
make ops-status-page

Shared flags in ~/ops-state/host-config/compose.env:

  • DOMAIN (required for TLS routing)
  • HOSTPORTS=1 to enable local port binds (default is off)
  • EXPECT_REDIS2=1 to enforce dual-Redis health locally (optional)

See Operator Quickstart: docs/ops-quickstart.md