{
  "slug": "icd-and-docker",
  "title": "Instant Content Deployment & Docker Deploy (F126)",
  "description": "Two deploy paths: ICD for 2-second content pushes via ISR revalidation, and one-click Docker deploys to Fly.io from template.",
  "category": "guides",
  "order": 20,
  "locale": "en",
  "translationGroup": "e9e13705-bb0c-4559-a6e5-3b93a0530c8f",
  "helpCardId": null,
  "content": "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.\n\n## Instant Content Deployment (ICD)\n\n### What it does\n\nWhen 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.\n\n### How it works\n\n1. Editor saves a document.\n2. CMS computes affected paths from the collection's `urlPrefix` (e.g. saving a post in `posts` collection with `urlPrefix: /blog` affects `/blog/my-post` and `/blog`).\n3. A signed HMAC-SHA256 POST goes to the configured `revalidateUrl` with:\n   - Headers: `X-CMS-Event: content.revalidate`, `X-CMS-Signature: sha256=<hash>`\n   - Body: `{ collection, slug, action, paths, document }`\n4. If the frontend returns 2xx, auto-deploy is skipped. If it fails, the system falls back to the full deploy pipeline.\n5. The last 50 deliveries are logged (timestamp, paths, status, duration) for troubleshooting.\n\n### Setup\n\nTwo settings in CMS admin:\n\n- **Settings → Revalidation** — configure `revalidateUrl` and the signing secret. Test button verifies the endpoint responds correctly.\n- **Settings → Deploy** — toggle **Deploy on Save** to enable ICD.\n\nOn 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`.\n\n### When ICD runs vs full deploy\n\n| Action | Triggers |\n|---|---|\n| Save richtext / field edit | ICD only |\n| Publish / unpublish | ICD only |\n| Upload media | ICD (with media URL in payload) |\n| Config change (cms.config.ts) | Full deploy |\n| New collection | Full deploy |\n| Theme/build.ts change | Full deploy |\n\n### Supported stacks\n\nAny 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.\n\n## One-Click Docker Deploy\n\n### What it does\n\nA 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.\n\n### The wizard\n\n1. **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.\n2. **Configure** — app name, region (`arn` Stockholm by default, also `sea`, `sin`, etc.), VM size (`shared-cpu-1x` / `shared-cpu-2x` / `dedicated-1x`), admin email.\n3. **Connect Fly.io** — paste your Fly auth token; the wizard verifies it via the Fly GraphQL API.\n4. **Deploy** — real-time SSE stream showing: app creation → secret setup (`CMS_CONFIG_PATH`, `NEXTAUTH_SECRET`, AI keys) → machine allocation → IP assignment → health check.\n\nThe 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.\n\n### Custom build commands (`build.command`)\n\nOne-Click Docker provisions CMS instances. For custom frameworks (Hugo, Laravel, Django, Rails) on your own hosts, use `build.command` in `cms.config.ts`:\n\n```typescript\nbuild: {\n  command: 'hugo --minify',\n  outDir: 'public',\n  docker: 'hugo',  // preset: { image: 'klakegg/hugo:ext-alpine', workdir: '/workspace' }\n}\n```\n\nDocker 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.\n\n### Build profiles\n\nMultiple targets per site — dev vs production, JAR vs static, etc.:\n\n```typescript\nbuild: {\n  profiles: [\n    { name: 'dev',     command: 'npm run dev',  outDir: 'dist',   description: 'Fast local' },\n    { name: 'prod',    command: 'mvn package',  outDir: 'target', description: 'Production JAR' },\n  ],\n  defaultProfile: 'prod',\n}\n```\n\nWhen 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.\n\n## When to use which\n\n| Task | Tool |\n|---|---|\n| Content edit on an existing site | ICD |\n| Config/schema change | Full deploy |\n| Spin up a new CMS instance | One-Click Docker |\n| Build a site with a non-TS framework | `build.command` + Docker preset |\n| Multi-environment builds | Build profiles |\n\nICD 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.",
  "excerpt": "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.\n\n Instant Content Deployment (ICD)\n\n What it does\n\nWhen an editor saves",
  "seo": {
    "metaTitle": "ICD & Docker Deploy (F126) — webhouse.app Docs",
    "metaDescription": "Instant Content Deployment for 2-second content pushes via ISR; One-Click Docker Deploy for new CMS instances on Fly.io from template.",
    "keywords": [
      "webhouse",
      "cms",
      "deploy",
      "icd",
      "instant-content-deployment",
      "docker",
      "fly.io",
      "revalidation",
      "isr",
      "f126"
    ]
  },
  "createdAt": "2026-04-15T20:55:00.000Z",
  "updatedAt": "2026-04-15T20:55:00.000Z"
}