Skip to main content

html-golive

CI PyPI Python License: MIT

Self-hosted one-command HTML deployment — Vercel-lite for your intranet.

Turn any HTML file, project folder or zip archive into a shareable URL on your own machine, NAS, VPS or intranet server.

30-second quickstart

pip install html-golive && golive init

That sets up everything and prints live URLs — open one and you're done. Then publish your own page:

golive publish report.html --name "Q3 Report" --slug q3
# → http://localhost:8787/q3

install, publish and serve an HTML page in three commands

Something not working? Run golive verify and paste the output into an issue.


Table of contents

📖 Full user manual: docs/manual.md — every feature, organised by task (publishing, editor, access control, data, security, identity, migration, FAQ).

The admin portal — light theme

Dark theme

The admin portal — dark theme

The built-in admin portal at /admin: sites, data, permissions, stats, audit log, identity, data backend, security and settings — dark/light themes, English and Chinese (toggle top-right).

Why html-golive

  • One command, one URL. No build step, no server code, no cloud account. golive publish → share the link.
  • Everything becomes a single file. Folders and zips are bundled — CSS/JS inlined, images compressed and embedded (or uploaded through your own image host).
  • Static pages, real data. Publish a plain HTML file that reads and writes a real database via window.TemplateAPI / window.SupabaseAPI — no backend code required.
  • Own your stack. Runs entirely on your infrastructure. No outbound calls at publish/serve time (details).
  • Production habits built in. Slug collision checks, 10-snapshot rollback, credential/PII scanning on every publish, audit log.

Quickstart

1 · Install

pip install html-golive              # core
pip install 'html-golive[oidc]'      # + SSO / OpenID Connect login
pip install 'html-golive[image]'     # + image compression (Pillow)
pip install 'html-golive[s3]'        # + S3-compatible backends (boto3)
pip install 'html-golive[postgres]' # + self-hosted Postgres (psycopg3)

2 · Publish

golive publish index.html --name Demo --slug demo
golive publish ./my-project/ --slug app      # folder → bundled single HTML
golive publish site.zip                      # zip / tar.gz work too
golive publish page.html --style apple       # apply one of 19 CSS styles

3 · Serve

golive serve --port 8787          # foreground; Ctrl+C stops it
# → http://<your-host>:8787/demo

golive serve start                # or run it in the background
golive serve status               # pid, port, version
golive serve logs -f
golive serve stop

Everyday commands

golive list                                  # all published sites
golive publish new.html --update demo        # overwrite update
golive rollback demo --dry-run               # inspect snapshots, then --yes
golive preview draft.html                    # live preview + style panel
golive clone https://example.com --save-only # snapshot a public page
golive styles                                # list the 19 CSS styles
golive doctor                                # one-screen health check
golive serve status                          # is a server running? which version?
golive skill install                         # teach your AI agent to drive golive

# v0.3 — online editing & watermark
golive publish page.html --enable-editor --owner you@example.com
golive maintainer add demo teammate@example.com
golive publish page.html --watermark "CONFIDENTIAL"

Online editing (v0.3)

export GOLIVE_EDITOR_TOKEN=$(openssl rand -hex 16)
golive publish report.html --slug q3 --enable-editor --owner you@example.com
golive serve
# open http://localhost:8787/q3?editor_token=<token>&editor_user=you@example.com
# click ✏️ → edit text inline → 💾 save (snapshot taken automatically)

Saves go through the same security scanner as publishes, are limited to the site owner + maintainers, and every overwrite is preceded by a rollback snapshot. With auth.provider: oidc the editor accepts the login session instead of the token+header pair.

SSO quickstart (v0.8.0)

Enable OpenID Connect login — Google, Keycloak, Authentik, Auth0, or any IdP with a discovery document:

auth:
  provider: oidc
  oidc:
    preset: google          # or auth0 / okta / azure / keycloak / authentik
    client_id: your-client-id
    redirect_uri: https://pages.example.com/auth/callback

Set the client secret via GOLIVE_OIDC_CLIENT_SECRET and a stable GOLIVE_COOKIE_SECRET in production. Since v0.8.0 every id_token is signature-verified against the IdP's published keys (requires pip install 'html-golive[oidc]').

Login ≠ admin. Signing in proves who someone is; it does not grant management access. List superadmin emails separately:

admin:
  admins: [alice@corp.example]

A common slip is putting admins: at the top level — it has no effect there. See manual §16 for details.


Upgrading

pip install -U html-golive
golive serve restart     # a running server keeps the OLD code until restarted
golive doctor            # confirms CLI version == running service version

Two things bite people:

  • Updating the code does not update a running server. Restart it, then let golive doctor confirm the two versions match.
  • Clones made before v0.7.0 cannot git pull. That release force-pushed main and rewrote history. Recovery commands are in the guide below (force pushes to main are now blocked).

📖 docs/upgrading.md — PyPI / pipx / git paths, the v0.7.0 history-rewrite recovery (with and without local changes), the 0.6→0.7 SQLite data-layer default change, and how to roll back.

Features

Publishing & content

  • Single HTML / directory / zip / tar.gz publishing with asset bundling
  • 19 built-in CSS beautification styles (--style, custom font CDN via GOLIVE_FONT_CDN_BASE)
  • Image compression (--compress) and pluggable image upload (GOLIVE_UPLOADER_CMD command template, or native S3 uploader)
  • Website cloning (golive clone <url>) with static snapshot mode

Operations

  • Short slugs with reserved-word and collision checks
  • Rollback with 10 snapshots per site
  • Built-in static server with JSON API and health endpoint
  • Live preview with hot reload and style-switch panel
  • golive doctor one-screen report: CLI vs running-service version, all three backends with paths and sizes, skill status, audit log
  • Background service management: golive serve start|status|stop|restart|logs

Data & backends (v0.2, SQLite data layer in v0.7)

  • window.TemplateAPI / window.SupabaseAPI injection — static pages get a real database with zero backend code
  • Three independent backend layers, each switchable on its own:
    • storage (site HTML): local (default) / s3 / supabase
    • registry (site metadata): sqlite (default) / postgres / supabase
    • data (TemplateAPI rows): sqlite (default) / postgres / supabase / none Defaults are fully local — SQLite files under GOLIVE_HOME, nothing to register. One Supabase project can back all three when you want them shared across machines.
  • golive migrate-check — port pages from other golive deployments
  • Docker Compose deployment (+ optional MinIO profile)

Editing, identity & watermarking (v0.3, signature-verified OIDC in v0.8)

  • In-browser inline editor (publish --enable-editor): contenteditable text editing with a save API that re-runs the full security pipeline, snapshots before every overwrite, and enforces owner/maintainer ACLs (golive maintainer add/remove/list)
  • Page watermarking (--watermark [text]): canvas-tiled identity watermark — OIDC user, static text, or page meta tag; optional view-report webhook; GOLIVE_WATERMARK_OFF=1 kill switch
  • Signature-verified OIDC login (v0.8.0): auth.provider: oidc with Google / Keycloak / Authentik / any discovery-document IdP; PKCE + signed session cookies; every id_token checked against IdP signing keys (iss/aud/exp/nonce, alg: none refused); presets for common providers; sessions accepted by the management and editor APIs
  • Optional LLM security review of weak scan hits via any OpenAI-compatible endpoint (security.llm.*), with a conservative degrade path and a strict_mode gate

Admin portal (v0.5, config-store in v0.8)

  • Web management portal at /admin: site list/search, metadata editing, maintainer & ownership management, snapshot rollback, delete with slug confirmation — role-scoped (owner / maintainer / superadmin via admin.admins or GOLIVE_ADMINS), plus superadmin stats dashboard and a JSONL audit trail (/api/admin/* JSON API for scripting)
  • 9-page admin console (v0.8.0): identity, data backends, security, global parameters — all configurable through the web UI with config-store: settings saved to the registry are live on next restart, no yaml editing required

AI agent skill (v0.7)

  • golive skill install drops a ready-made AgentSkill into your agent's skills directory (auto-detected), teaching it to probe the environment before acting, publish and update by slug, wire up TemplateAPI, and never confuse this self-hosted CLI with a hosted deployment service
  • Ships inside the wheel, so installation works offline; golive skill status flags version drift

Safety

  • Credential / PII scanning on every publish (YAML-extensible rules)
  • Refusals identify the credential without reprinting it; redact_mode: strict withholds the host/database metadata too, for CI logs (v0.9)
  • Per-publish manifests + golive doctor --site to detect a page changed outside golive (v0.9)
  • Path-traversal-hardened server and archive extraction
  • Token-protected management API (GOLIVE_TOKEN)

Architecture

┌────────────── golive core (pure logic) ───────────────────┐
│ bundle / image compress / CSS styles / clone / preview /  │
│ security scanner / slug checker                           │
└──────┬──────────────────┬──────────────────┬──────────────┘
  StorageBackend    RegistryBackend     DataBackend
  site HTML/assets  site metadata       TemplateAPI/SupabaseAPI
       │                  │                  │
  local-fs / s3 /    sqlite / postgres /   sqlite (local file) /
  supabase storage   supabase             postgres / supabase (PostgREST) / none
       │
  AuthProvider: none (default) / token (GOLIVE_TOKEN) / oidc (generic OIDC)

All data lives under GOLIVE_HOME (default ~/.golive/):

~/.golive/
├── sites/<site_id>/index.html   published content
├── backups/<site_id>/           rollback snapshots (max 10)
├── registry.db                  SQLite registry + managed superadmins
├── data.db                      SQLite data layer (TemplateAPI rows)
├── audit.log                    admin action trail
├── logs/                        operation log
└── cache/                       style backups etc.

With the default backends the three SQLite/filesystem entries above are the entire persistence story — no external service is involved. Pages using TemplateAPI reach data.db through golive serve's /api/data endpoint, so they must be loaded from the server rather than opened as file://. See docs/data-layer.md.

Configuration

Everything works with zero config. Two layers of knobs, env always wins over yaml:

golive.yaml (backend selection)

Lookup order: --config <path> → $GOLIVE_CONFIG → ./golive.yaml → $GOLIVE_HOME/golive.yaml. Full annotated example: golive.example.yaml · backend combinations: docs/backends.md

Environment variables

Variable Purpose
GOLIVE_HOME data directory (default ~/.golive/)
GOLIVE_TOKEN protect /api/sites (Bearer or X-Golive-Token)
GOLIVE_EDITOR_TOKEN online-editor save token (falls back to GOLIVE_TOKEN)
GOLIVE_WATERMARK_TEXT / GOLIVE_WATERMARK_OFF watermark text / global kill switch
GOLIVE_OIDC_CLIENT_SECRET / GOLIVE_COOKIE_SECRET OIDC client secret / session-cookie HMAC key
GOLIVE_LLM_BASE_URL / GOLIVE_LLM_MODEL / GOLIVE_LLM_API_KEY LLM security review endpoint
GOLIVE_FONT_CDN_BASE swap fonts.googleapis.com for your font mirror
GOLIVE_UPLOADER_CMD image-upload command template (mytool up {file})
GOLIVE_SUPABASE_URL / _ANON_KEY / _SERVICE_KEY Supabase backends
GOLIVE_S3_AK / GOLIVE_S3_SK S3-compatible backends
FIRECRAWL_API_KEY optional JS-heavy-page fallback for golive clone

Network behavior

golive makes no outbound calls at publish/serve time. Exceptions: golive clone <url> fetches the target page; golive preview downloads a one-time Tailwind cache from cdn.tailwindcss.com on first run (fails silently offline); injected styles reference public font CDNs (override with GOLIVE_FONT_CDN_BASE); your own uploader command and configured backends.

Data layer: give static pages a database

No server code to write. SQLite by default, so this works out of the box; point it at your own PostgreSQL or a Supabase project when you outgrow that:

golive publish app.html --data-model myapp_v1   # sqlite: nothing to set up
golive serve

Your page then simply calls:

// namespaced record store
await TemplateAPI.upsert({ templateName: 'vote:alice', templateContent: {n: 1} });
const { total, list } = await TemplateAPI.listAll();

// or direct table access
const { rows } = await SupabaseAPI.query('feedback', { limit: 50 });

Three backends, two shapes:

Backend Shape Setup
sqlite server-proxied none — the default
postgres server-proxied pip install 'html-golive[postgres]' + GOLIVE_PG_DSN
supabase page-direct Supabase project + anon key

Server-proxied backends keep the database connection on the server; the page calls golive's /api/data and no credentials (no Postgres DSN) ever reach the browser. Page-direct (Supabase) embeds the anon key in the HTML, so RLS is mandatory there.

API signatures are stable contracts — pages built on any golive deployment run unchanged on yours. Full guide, including the RLS notes: docs/data-layer.md.

Note: if no data backend is configured, --data-model publishes still succeed — the page gets a stub API that raises a clear "data backend not configured" error at call time (a warning is also printed at publish time).

Porting pages from another deployment? golive migrate-check page.html reports anything deployment-specific (migration guide).

Security scanning

Every publish is scanned against built-in rules — API keys, private keys, database connection strings, PII patterns. Strong hits block the publish; weak hits warn — and can optionally get a semantic second pass from any OpenAI-compatible LLM (security.llm.base_url; works with OpenAI / Azure / Ollama / self-hosted gateways). Unconfigured installs keep pure rule verdicts; strict_mode: true refuses to publish without AI review. Extend with your own YAML rules, or bypass a false positive for content warnings with --skip-content-scan; credentials always block. Details: docs/security.md

Docker

docker compose up -d golive                 # golive serve on :8787
docker compose --profile minio up -d        # + local S3 stack for images

Roadmap

  • WebDAV storage support.
  • Large-table aggregation and multi-instance sessions.
  • Editing conflict handling and group-based permissions.

Open an issue to help prioritise the next improvement.

Contributing

Issues and pull requests are welcome — see CONTRIBUTING.md for the development setup, code conventions and what a good bug report looks like. The whole test suite runs offline with no cloud account:

pip install -e '.[image,dev]'
python -m pytest tests/ -q

License

MIT © 2026 Songhonglei


中文文档请见 README.zh-CN.md。

Metadata

Release files for html-golive 0.9.6

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for html-golive 0.9.6
File Size Uploaded
html_golive-0.9.6.tar.gz 1.3 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for html-golive 0.9.6
File Interpreter ABI Platform
html_golive-0.9.6-py3-none-any.whl Python 3 none any Details

Total release size: 2.5 MB

Release files / html_golive-0.9.6.tar.gz

Download URL html_golive-0.9.6.tar.gz
Size 1.3 MB
Tags Source
SHA-256 checksum
How to use checksums
01002943185547a4a24064865c6c3dcbd55dd579f269fc9f4eb8ddf5106b3c77
BLAKE2b-256 checksum
How to use checksums
91ed7497c41ab434f7b79d044761d213e8ec5a1a728ea76ed0767fe9f38e7d05
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.12

Release files / html_golive-0.9.6-py3-none-any.whl

Download URL html_golive-0.9.6-py3-none-any.whl
Size 1.2 MB
Tags Python 3
SHA-256 checksum
How to use checksums
411a39ce1b85273f52dde72a95ac5af007136064c947b4207dc0cf3b582cd977
BLAKE2b-256 checksum
How to use checksums
064b427d4e3ccf99591261ea175ef266c0cd74aa8b9c5c434ea36c6fe6117ce9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.12

Release history Release notifications | RSS feed

This release

0.9.6 This release

2 release files

0.9.5

2 release files

0.9.4

2 release files

0.9.3

2 release files

0.9.2

2 release files

0.9.1

2 release files

0.9.0

2 release files

0.8.6

2 release files

0.8.5

2 release files

0.8.4

2 release files

0.8.3

2 release files

0.8.2

2 release files

0.8.1

2 release files

0.8.0

2 release files

0.7.7

2 release files

0.7.6

2 release files

0.7.5

2 release files

0.7.2

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page