Pinned Input
Deploy from explicit site state
Website content is applied declaratively. Git-backed workflows can still exist upstream, but the deployment step operates on explicit site state rather than “whatever was on the branch five seconds ago.”
htmlctl / Category Page
Serving a static site from your own infrastructure is easy. Building a self-hosted deployment workflow that still gives you previews, exact staging-to-production promotion, rollback discipline, runtime controls, and a clean extension boundary is where the category becomes operationally serious.
Exact
Staging to prod promote
SSH
Direct operator control
Loopback
Clean extension boundary
The actual problem
You can put a static site behind Nginx or Caddy in an afternoon. The interesting problems begin later: preview environments, release history, rollback targets, environment-specific runtime controls, and promotion without rebuild drift.
If every deployment requires custom shell glue, hand-managed directories, and environment-specific rewrites, the stack may be self-hosted, but it is not yet a coherent deployment system. The complexity just moved from vendor to operator.
What htmlctl is optimizing for
Pinned Input
Website content is applied declaratively. Git-backed workflows can still exist upstream, but the deployment step operates on explicit site state rather than “whatever was on the branch five seconds ago.”
Preview URLs
Preview environments let you inspect the exact built release, not an approximate rebuild. That matters for metadata, generated assets, and confidence when the site is about to become public.
Exact Promote
Promotion copies the release artifact exactly. There is no second build step introducing drift between what you approved in staging and what production serves.
Runtime Controls
Static content stays stable while environment-specific auth policies and backend prefixes can differ between staging and production. That separation is one of the most practical parts of the model.
Extensions
When a site needs something like a newsletter, the dynamic logic can run as an extension behind a routed prefix rather than forcing the static deployment core to become a general-purpose application runtime.
Retention
Immutable release history is useful until disk pressure turns it into an operational liability. Retention keeps rollback guarantees explicit while reclaiming space safely.
The workflow
Render the release, materialize generated assets, and activate it under staging without touching production.
Check the preview URL, metadata, release status, generated files, and any environment-specific runtime routes. This is where a deployment system proves whether it is disciplined or decorative.
Move the artifact from staging to production byte-for-byte. Roll back by release, not by reconstruction. That is the guarantee that makes the workflow worth having.
Best fit
When not to use it
Next step
If you are evaluating self-hosted static site deployment seriously, the useful next step is the product itself: previews, exact promote, auth, backends, retention, and extensions.