Two deploy paths: ICD for 2-second content pushes via ISR revalidation, and one-click Docker deploys to Fly.io from template.
F126 ships two separate deploy mechanisms. They solve different problems: ICD makes content go live in ~2 seconds without a full rebuild; One-Click Docker spins up an entire CMS instance on Fly.io from a template in a few clicks.
Instant Content Deployment (ICD)
What it does
When an editor saves content, ICD pings your site's revalidation endpoint with a signed webhook instead of triggering the full build+deploy pipeline. Your Next.js (or other ISR-capable) frontend regenerates the affected pages on demand. Content is live in ~2 seconds instead of 5–10 minutes.
How it works
- Editor saves a document.
- CMS computes affected paths from the collection's
urlPrefix(e.g. saving a post inpostscollection withurlPrefix: /blogaffects/blog/my-postand/blog). - A signed HMAC-SHA256 POST goes to the configured
revalidateUrlwith:
- Body: { collection, slug, action, paths, document }
- If the frontend returns 2xx, auto-deploy is skipped. If it fails, the system falls back to the full deploy pipeline.
- The last 50 deliveries are logged (timestamp, paths, status, duration) for troubleshooting.
Setup
Two settings in CMS admin:
- Settings → Revalidation — configure
revalidateUrland the signing secret. Test button verifies the endpoint responds correctly. - Settings → Deploy — toggle Deploy on Save to enable ICD.
On the frontend side, implement POST /api/revalidate that verifies the signature and calls Next.js revalidatePath(path) for each path in the payload. A reference implementation ships with next-js-boilerplate.
When ICD runs vs full deploy
| Action | Triggers |
|---|---|
| Save richtext / field edit | ICD only |
| Publish / unpublish | ICD only |
| Upload media | ICD (with media URL in payload) |
| Config change (cms.config.ts) | Full deploy |
| New collection | Full deploy |
| Theme/build.ts change | Full deploy |
Supported stacks
Any frontend with on-demand revalidation: Next.js (App Router or Pages Router), Remix with route revalidation, custom caches that expose an invalidate-by-path webhook. Works on Vercel, Netlify, Fly.io, self-hosted — the CMS doesn't care where your frontend runs.
One-Click Docker Deploy
What it does
A 4-step wizard at /admin/deploy/docker that provisions a brand-new CMS instance on Fly.io from a template. No local Docker required, no manual fly launch, no secret juggling.
The wizard
- Template picker — 12 built-in templates:
blog,landing,agency,portfolio,portfolio-squared,freelancer,boutique,studio,bridgeberg,cmsdemo,static-boilerplate,nextjs-boilerplate. Each shows a screenshot and short description. - Configure — app name, region (
arnStockholm by default, alsosea,sin, etc.), VM size (shared-cpu-1x/shared-cpu-2x/dedicated-1x), admin email. - Connect Fly.io — paste your Fly auth token; the wizard verifies it via the Fly GraphQL API.
- Deploy — real-time SSE stream showing: app creation → secret setup (
CMS_CONFIG_PATH,NEXTAUTH_SECRET, AI keys) → machine allocation → IP assignment → health check.
The wizard uses the pre-built ghcr.io/webhousecode/cms-admin image — no local Docker build required. Template files are fetched from GitHub at deploy time, so you get the latest boilerplate version without re-downloading the CMS repo.
Custom build commands (build.command)
One-Click Docker provisions CMS instances. For custom frameworks (Hugo, Laravel, Django, Rails) on your own hosts, use build.command in cms.config.ts:
build: {
command: 'hugo --minify',
outDir: 'public',
docker: 'hugo', // preset: { image: 'klakegg/hugo:ext-alpine', workdir: '/workspace' }
}Docker presets: php, laravel, python, django, ruby, rails, go, hugo, node, dotnet. Each expands to a { image, workdir } config; you can also pass the full object directly.
Build profiles
Multiple targets per site — dev vs production, JAR vs static, etc.:
build: {
profiles: [
{ name: 'dev', command: 'npm run dev', outDir: 'dist', description: 'Fast local' },
{ name: 'prod', command: 'mvn package', outDir: 'target', description: 'Production JAR' },
],
defaultProfile: 'prod',
}When profiles are configured, the Build button in CMS admin shows a dropdown to pick which profile to run. Each profile gets its own build history and output directory.
When to use which
| Task | Tool |
|---|---|
| Content edit on an existing site | ICD |
| Config/schema change | Full deploy |
| Spin up a new CMS instance | One-Click Docker |
| Build a site with a non-TS framework | build.command + Docker preset |
| Multi-environment builds | Build profiles |
ICD is on by default once a revalidation endpoint is configured. One-Click Docker is a one-time provisioning action. Build commands and profiles are per-site config — ship them in cms.config.ts and they're active immediately.