Installation

Prerequisites#

RequirementMinimum VersionCheck Command
Node.js18.0.0node -v
pnpm10.xpnpm -v
Wrangler CLI4.xwrangler -v
Cloudflare accountFree tier workswrangler whoami

Install pnpm#

If you don't have pnpm yet:

npm install -g pnpm
corepack enable
corepack prepare pnpm@latest --activate

Install Wrangler#

npm install -g wrangler

Clone and install#

git clone https://github.com/jjaimealeman/flarecms.git
cd flarecms
pnpm install

This is a pnpm workspace monorepo with three packages:

PackagePathDescription
@flare-cms/corepackages/core/Engine — schema, services, routes, middleware
@flare-cms/cmspackages/cms/Backend — Cloudflare Worker application
@flare-cms/sitepackages/site/Frontend — Astro site on Cloudflare Pages

Build the core package#

The CMS imports @flare-cms/core as a workspace dependency. You must build it before running the CMS:

pnpm build
Note

You only need to rebuild core when you change files in packages/core/. The CMS and site packages don't need a separate build step for local dev.

Cloudflare account setup#

Authenticate with Cloudflare#

wrangler login

This opens a browser window to authorize Wrangler with your Cloudflare account. After authorizing, verify with:

wrangler whoami

Create a D1 database#

wrangler d1 create my-astro-cms-db

This outputs a database_id. Update packages/cms/wrangler.toml with it:

[[d1_databases]]
binding = "DB"
database_name = "my-astro-cms-db"
database_id = "your-database-id-here"

Create an R2 bucket#

wrangler r2 bucket create my-astro-cms-media

The bucket name in wrangler.toml should match:

[[r2_buckets]]
binding = "MEDIA_BUCKET"
bucket_name = "my-astro-cms-media"

KV namespace (optional)#

KV is used for rate limiting. Create one if you want rate limiting enabled:

wrangler kv namespace create CACHE_KV

Update the id in wrangler.toml:

[[kv_namespaces]]
binding = "CACHE_KV"
id = "your-kv-namespace-id"
Tip

KV is optional for local development. If it's not configured, rate limiting is simply disabled and you'll see a warning in the console.

Local development setup#

Run database migrations#

cd packages/cms
pnpm run db:migrate:local

This applies all SQL migrations from packages/core/migrations/ to your local D1 database.

Seed the admin user#

pnpm run seed

This creates the initial admin user using the scripts/seed-admin.ts script.

Set the JWT secret#

Create a .dev.vars file in packages/cms/ for local environment secrets:

JWT_SECRET=my-local-dev-secret-change-in-production
Warning

The CMS will refuse to start if JWT_SECRET is not set or is using the hardcoded default. This is a security check, not a bug.

Start the CMS dev server#

cd packages/cms
wrangler dev

The CMS is now running at http://localhost:8787:

Start the Astro site (optional)#

If you're working on the frontend too:

cd packages/site
pnpm dev

The site runs at http://localhost:4321 and fetches content from the CMS API.

Production setup#

Set secrets#

Production secrets are stored securely with Wrangler — they're never checked into version control:

cd packages/cms
wrangler secret put JWT_SECRET --env production

Deploy the CMS#

Deployment is handled by CI/CD — push to main and GitHub Actions deploys automatically. The workflow:

  1. Builds @flare-cms/core
  2. Deploys the CMS Worker (wrangler deploy --env production)
  3. Builds and deploys the Astro site to Cloudflare Pages

Run remote migrations#

cd packages/cms
wrangler d1 migrations apply DB --env production

Environment variables#

See the Environment Variables reference for all configurable values.

Troubleshooting#

"JWT_SECRET must be configured"#

The CMS blocks all requests if JWT_SECRET is missing or using the default. Create a .dev.vars file in packages/cms/ with your secret.

"Missing required bindings: DB"#

Your wrangler.toml D1 binding is misconfigured. Make sure database_id matches the output from wrangler d1 create.

Build errors in packages/cms#

Make sure you ran pnpm build from the root first. The CMS depends on the compiled @flare-cms/core package.

Migration errors#

If migrations fail locally, you can reset and start fresh:

cd packages/cms
pnpm run db:reset
pnpm run db:migrate:local
pnpm run seed

Port 8787 already in use#

Another Wrangler process is running. Kill it or use a different port:

wrangler dev --port 8788