Chuck Environment
Chuck Environment
This page lists every environment variable read by the Strapi process in
apps/chuck/meat/. Source of truth is apps/chuck/meat/.env.example plus
the four config/*.ts files. Values shown in .env.example are
development defaults committed to the repo and must not be reused in
preview, staging, or production.
For the cross-service env vocabulary (per-service *_STAGE, preview DB
mapping) see standards/deployment-env.
Server (config/server.ts)
| Variable | Default | Purpose |
|---|---|---|
HOST | 0.0.0.0 | Bind address |
PORT | 1337 (.env.example sets 1333) | Strapi HTTP port |
APP_KEYS | none | Comma-separated array of Koa session signing keys. Rotate by prepending a new key. |
Admin & Tokens (config/admin.ts)
| Variable | Purpose |
|---|---|
ADMIN_JWT_SECRET | Signs admin panel session JWTs. Rotation invalidates all admin sessions. |
API_TOKEN_SALT | Salt for API tokens issued in /admin → Settings → API Tokens. Rotation invalidates all issued API tokens — coordinate with brisket (STRAPI_TOKEN). |
TRANSFER_TOKEN_SALT | Salt for strapi transfer data export/import tokens. Ops-only. |
FLAG_NPS | Boolean — Strapi NPS prompt. Default true. |
FLAG_PROMOTE_EE | Boolean — Strapi EE upsell. Default true. |
JWT_SECRET | users-permissions end-user JWT. Currently unused by brisket; required if end-user auth is enabled. |
APP_KEYS, ADMIN_JWT_SECRET, API_TOKEN_SALT, TRANSFER_TOKEN_SALT,
and JWT_SECRET are secrets. See
standards/security-model.
Database (config/database.ts)
Strapi picks the client from DATABASE_CLIENT (default postgres).
Production should be Postgres; sqlite is a fallback for local
experimentation and ships in package.json via better-sqlite3.
Postgres (recommended)
| Variable | Default | Purpose |
|---|---|---|
DATABASE_CLIENT | postgres | Driver selector |
DATABASE_URL | none | Full connection string. If set, takes precedence over discrete fields. |
DATABASE_HOST | localhost | Host |
DATABASE_PORT | 5432 | Port |
DATABASE_NAME | strapi | Database name |
DATABASE_USERNAME | strapi | User |
DATABASE_PASSWORD | strapi | Password |
DATABASE_SCHEMA | public | Postgres schema |
DATABASE_SSL | false | Toggle TLS |
DATABASE_SSL_KEY / _CERT / _CA / _CAPATH / _CIPHER | none | TLS material |
DATABASE_SSL_REJECT_UNAUTHORIZED | true | Validate cert chain |
DATABASE_POOL_MIN | 2 | Knex pool min |
DATABASE_POOL_MAX | 10 | Knex pool max |
DATABASE_CONNECTION_TIMEOUT | 60000 | Acquire timeout (ms) |
TODO(@marty): document preview-environment naming and Neon branching
for chuck. standards/deployment-env
documents brain and sirloin preview wiring; chuck is not listed there
(grep -i chuck docs/src/content/docs/standards/deployment-env.md
returns no matches).
SQLite (local fallback only)
| Variable | Default | Purpose |
|---|---|---|
DATABASE_FILENAME | .tmp/data.db | Relative to apps/chuck/meat/ |
MySQL (declared but unused)
config/database.ts carries a MySQL block. No MySQL driver is in
package.json — assume MySQL is unsupported.
Upload — Cloudflare R2 (config/plugins.ts)
Provider: strapi-provider-cloudflare-r2.
| Variable | Purpose |
|---|---|
CF_ACCESS_KEY_ID | R2 access key |
CF_ACCESS_SECRET | R2 secret key |
CF_ENDPOINT | R2 S3-compatible endpoint (e.g. https://<account>.r2.cloudflarestorage.com) |
CF_BUCKET | Bucket name |
CF_PUBLIC_ACCESS_URL | Public CDN base URL — also added to CSP img-src and media-src in config/middlewares.ts |
Rotation note: CF_PUBLIC_ACCESS_URL is referenced by CSP middleware,
so changing the host requires a deploy, not just an env update — uploaded
assets pinned to the old host will be blocked by CSP otherwise.
Email — SMTP via Nodemailer (config/plugins.ts)
Provider: @strapi/provider-email-nodemailer.
| Variable | Purpose |
|---|---|
SMTP_HOST | SMTP server hostname |
SMTP_PORT | SMTP server port |
SMTP_USER | SMTP username |
SMTP_PASSWORD | SMTP password |
Hard-coded in config/plugins.ts: defaultFrom and defaultReplyTo
are both no-reply@foxy.ai. Change requires a code edit, not an env.
Stage / Deployment
Chuck does not appear in the per-service *_STAGE table in
standards/deployment-env, and
grep -rn 'CHUCK_STAGE' apps/chuck returns no matches — the codebase
does not read a CHUCK_STAGE variable today. TODO(@marty): decide
whether chuck should join the *_STAGE convention (the deployment-env
table currently lists sirloin, strip, brain, brisket, flank).
There is no apps/chuck/railway.json or apps/chuck/meat/railway.json
checked in (verified by find apps/chuck -name 'railway*'). TODO(@marty):
document how chuck is deployed — the @strapi/plugin-cloud plugin is
installed in apps/chuck/meat/package.json but not wired in
config/plugins.ts, and pnpm strapi deploy is referenced in the
runbook without a confirmed target host.
Consumer-side env (brisket)
apps/brisket/src/env.js declares the brisket → chuck contract:
| Variable | Required | Source |
|---|---|---|
STRAPI_URL | yes | Public base URL of the chuck deployment |
STRAPI_TOKEN | yes | API token issued in chuck admin (salted by API_TOKEN_SALT) |
When rotating chuck API_TOKEN_SALT or revoking the brisket token,
brisket must be redeployed with the new STRAPI_TOKEN.
Local .env Bootstrap
Copy apps/chuck/meat/.env.example to apps/chuck/meat/.env and replace
every value. The committed defaults for APP_KEYS,
API_TOKEN_SALT, ADMIN_JWT_SECRET, TRANSFER_TOKEN_SALT, and
JWT_SECRET are public (visible in git history) and must not be
used outside throwaway local dev. Generate fresh values with:
node -e "console.log(require('crypto').randomBytes(16).toString('base64'))"See chuck-local-dev for full setup.
Anchor Docs
- API surface: chuck-api
- Errors: chuck-errors
- Runbook: chuck-runbook
- Cross-service env: standards/deployment-env
- Secrets policy: standards/security-model