Deployment
Choose delivery first, then storage that works on your host. CaretCMS 0.5.0 supports Astro 6 and 7 and requires Node 22.12+ for its Node/build tooling.
Choose your production setup
Section titled “Choose your production setup”| Setup | Where authors work | What visitors receive | Storage |
|---|---|---|---|
| Static CDN | Local or separate authoring environment | Built HTML; no public CMS routes | Content available to the build |
| Persistent Node server | The running site | Request-time rendering | Files/Markdown with one writer, or transactional custom adapter |
| Cloudflare Workers | The running site | Request-time rendering | Durable Object or single-writer KV, plus R2 uploads |
| Other serverless hosts | The running site | Request-time rendering | Custom remote storage and upload providers |
Static CDN
Section titled “Static CDN”import { defineConfig } from 'astro/config';import caret from '@caretcms/core';
export default defineConfig({ integrations: [caret({ delivery: 'static' })],});- Run
npm run dev, sign in at/admin, and edit. - Save drafts and Publish them to shared content.
- Make that content available to the build, then run
npm run build. - Deploy
dist/and verify the result while signed out.
A webhook starts a build request; it does not transfer local source files, push git commits, or prove a deployment finished. See Static delivery and Deployment status.
A separate authoring server can feed a static public build, but its save behavior follows its own delivery/policy configuration. Do not assume a server authoring environment is automatically draft-only.
Node or VPS
Section titled “Node or VPS”Install the Astro Node adapter compatible with your Astro version, then configure:
import { defineConfig } from 'astro/config';import node from '@astrojs/node';import caret from '@caretcms/core';
export default defineConfig({ output: 'server', adapter: node({ mode: 'standalone' }), integrations: [caret()],});Persist all state your chosen providers use, including:
- JSON
.caret/data/or your Markdown content root; - revision/history metadata
.caretcms/; - private drafts (normally
.caret/drafts/with default configuration); - uploaded files (normally
public/uploads/).
Mount persistent storage or configure roots on a persistent volume. Back up content and metadata together. Run one writer process for filesystem/Markdown; a shared volume does not make multi-process writes safe.
Set CARET_EDIT_PASSWORD and CARET_SESSION_SECRET through your host’s secret
configuration, or configure an identity provider.
Set CARET_TRUST_PROXY=true only behind a trusted proxy that supplies the real
HTTPS protocol. Then build and start the adapter’s server entrypoint:
npm run buildnode ./dist/server/entry.mjsOrdinary saves are live without an authorization policy. Configure a write policy when editing should require publication.
Cloudflare Workers
Section titled “Cloudflare Workers”Use Cloudflare storage in both development and production. The Astro Cloudflare adapter runs in workerd; filesystem/Markdown providers are not the right choice for that runtime.
For coordinated writes, follow Cloudflare Durable Object storage. It includes a custom Worker export, SQLite-backed namespace, R2 upload binding, and the generated Astro configuration used at deployment.
For an existing KV site, cloudflareStorage({ binding: 'CMS_KV' }) remains
supported for one editor at a time. Preserve the current namespace and R2 bucket
when upgrading. Switching to a Durable Object requires explicit export/import
of runtime-only KV content.
Build before deploying:
npm run buildnpx wrangler deploy --config dist/server/wrangler.jsonConfigure password/session secrets or identity authentication, and set a public
R2 URL through R2_PUBLIC_DOMAIN or r2Uploads({ publicBaseUrl }). Uploads fail
before writing if they cannot return a public image URL; core provides no R2 proxy.
Check that the generated configuration targets the intended account, Worker, namespaces and bucket. Use a test entry to verify saving, history and persistence before inviting editors.
Other serverless hosts
Section titled “Other serverless hosts”Use a custom transactional storage adapter and remote uploads. A temporary or read-only filesystem cannot preserve CMS edits across function invocations or deployments. Storage adapters explains provider wiring and the optional contracts for drafts and atomic writes.
Content Security Policy
Section titled “Content Security Policy”Core tests its editor with Astro’s production CSP through a full save flow.
Start with your adapter configuration and security: { csp: true }, then test
the built site, including Studio, uploads, and any external image hosts.
Editor assets use same-origin /__caret/ and API requests use /api/cms/ by
default. A separately supplied CSP header must account for those assets and the
injected bootstrap. Match Astro’s generated hashes rather than assuming
script-src 'self' permits an inline bootstrap. Additional CSP restrictions and
page integrations require testing against your own build.
Hiding UI versus disabling writes
Section titled “Hiding UI versus disabling writes”enableAdmin: false removes Studio routes. enableInlineEditor: false removes
the page editor bootstrap. These flags do not remove CMS API routes in server
delivery. Use authentication, authorization or host access controls to restrict
writes. Static production builds have no CMS authoring routes.
Verify the rollout
Section titled “Verify the rollout”- Confirm the deployed build contains the intended package version and content.
- Check a public page while signed out.
- Sign in, inspect Studio and the inline editor, and use controlled test content to verify saving, visibility, and history.
- For draft workflows, check that unshared changes remain private; Publish and follow build/deploy status separately.
- Verify uploaded media URLs and persistence after a redeploy.
For failures, use Troubleshooting and Publish recovery. Rotate password and session secret together when revoking all shared-password sessions.