Skip to content

Environments & Secrets

GrowthBook ships with three built-in environments: development, staging, and production. Each environment has its own:

  • SDK Connection — a separate clientKey your application uses per environment.
  • Feature state — a flag can be ON in development and OFF in production independently.
  • Override rules — targeting rules are per-environment, so you can release to internal users in staging without touching production.
  1. Go to Settings → Environments.
  2. Click Add Environment.
  3. Give it a name (e.g., canary) and optionally mark it as a production environment so its metrics are highlighted.
  4. Click Save.

Custom environments are useful for canary deployments or dedicated QA environments.

  1. Go to SDK Connections → Add SDK Connection.
  2. Select the target Environment from the dropdown.
  3. Copy the generated clientKey. Use this key only in that environment’s app config.

Securing secrets in self-hosted Docker Compose

Section titled “Securing secrets in self-hosted Docker Compose”

The official GrowthBook Docker Compose file exposes several secrets that must be overridden before going to production.

# docker-compose.yml (relevant excerpt)
services:
growthbook:
environment:
- MONGODB_URI=mongodb://mongo:27017/growthbook
- JWT_SECRET=dev_secret # MUST change
- ENCRYPTION_KEY=dev_key # MUST change
- NODE_ENV=production
- APP_ORIGIN=https://growthbook.yourcompany.com

Never deploy with dev_secret or dev_key. Generate strong values:

# Generate a 64-char hex JWT secret
openssl rand -hex 32

# Generate a 32-char base64 encryption key
openssl rand -base64 24

Store the output in a .env file (never committed to git) and reference it in Compose:

services:
growthbook:
env_file:
- .env

Add .env to your .gitignore immediately.

GrowthBook stores all features, experiments, metrics, and audit logs in MongoDB. A backup plan is non-negotiable.

Terminal window
docker exec growthbook-mongo-1 \
mongodump --uri="mongodb://localhost:27017/growthbook" \
--archive=/tmp/growthbook-backup.gz --gzip
docker cp growthbook-mongo-1:/tmp/growthbook-backup.gz \
./backups/growthbook-$(date +%Y%m%d).gz
Terminal window
# Add to crontab: crontab -e
0 2 * * * docker exec growthbook-mongo-1 \
mongodump --uri="mongodb://localhost:27017/growthbook" \
--archive=/tmp/gb-daily.gz --gzip && \
docker cp growthbook-mongo-1:/tmp/gb-daily.gz \
/backups/growthbook-$(date +\%Y\%m\%d).gz

For high-traffic deployments:

  • Run GrowthBook Proxy (ghcr.io/growthbook/proxy) in front of the SDK endpoint. The proxy caches the feature payload and serves it at the edge, reducing load on your GrowthBook app server.
  • Set GROWTHBOOK_PROXY_HOST in the proxy container to point to your app server.
  • The proxy respects the webhook-triggered cache invalidation described in the previous lesson.

Work through this checklist before switching DNS to production:

[ ] JWT_SECRET is a randomly generated 64-char hex string
[ ] ENCRYPTION_KEY is a randomly generated 32-char base64 string
[ ] MONGODB_URI points to a replica set or managed MongoDB (not a single node)
[ ] .env is in .gitignore — never committed
[ ] Daily mongodump cron is running and restores have been tested
[ ] APP_ORIGIN is set to your real HTTPS domain
[ ] SDK Connections have separate keys per environment
[ ] At least one Read-only API key exists for dashboards/monitoring
[ ] GrowthBook Proxy is deployed for high-traffic SDK endpoints
[ ] Webhook endpoints are verified with HMAC signature checking
What is the risk of deploying GrowthBook with the default JWT_SECRET value?
Which GrowthBook component caches the SDK feature payload at the edge to reduce app server load?
What is the correct Compose pattern for injecting secrets without hardcoding them?
Why should you test a mongodump restore before going to production?