Skip to content

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.

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
astro.config.mjs
import { defineConfig } from 'astro/config';
import caret from '@caretcms/core';
export default defineConfig({
integrations: [caret({ delivery: 'static' })],
});
  1. Run npm run dev, sign in at /admin, and edit.
  2. Save drafts and Publish them to shared content.
  3. Make that content available to the build, then run npm run build.
  4. 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.

Install the Astro Node adapter compatible with your Astro version, then configure:

astro.config.mjs
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:

Terminal window
npm run build
node ./dist/server/entry.mjs

Ordinary saves are live without an authorization policy. Configure a write policy when editing should require publication.

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:

Terminal window
npm run build
npx wrangler deploy --config dist/server/wrangler.json

Configure 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.

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.

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.

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.

  1. Confirm the deployed build contains the intended package version and content.
  2. Check a public page while signed out.
  3. Sign in, inspect Studio and the inline editor, and use controlled test content to verify saving, visibility, and history.
  4. For draft workflows, check that unshared changes remain private; Publish and follow build/deploy status separately.
  5. 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.