| name | env-variable-management |
| description | Guide for adding environment variables. Use when adding new env vars to ensure all 5 locations are updated (code, env files, Coolify, workflow, GitHub secrets). |
Environment Variable Management Skill
Purpose
Ensure environment variables are properly configured across ALL required locations. Missing a location causes production runtime crashes.
⚠️ CRITICAL: 5 Locations Must Stay in Sync
When adding ANY new environment variable, you MUST update ALL applicable locations:
| # | Location | Purpose | Where |
|---|
| 1 | Code | Read the variable | process.env.VAR_NAME |
| 2 | Env files | Local dev/build via env-cmd | .env.development, .env.staging, .env.production |
| 3 | Coolify | Container runtime env | Coolify dashboard → Application → Environment |
| 4 | Deploy Workflow | CI/CD build secrets | .github/workflows/deploy-coolify.yml |
| 5 | GitHub Secrets | Actual secret values | GitHub repo settings |
Note: NEXT_PUBLIC_API_URL must be present in .env.* files because it affects the service worker registration and test runs (build:development, build:staging, etc. use env-cmd).
Required vs Optional Pattern
Required Variables (Fail Fast)
For variables that MUST exist in production, validate at startup or usage:
const myVar = process.env.MY_REQUIRED_VAR;
if (!myVar) {
throw new Error("MY_REQUIRED_VAR environment variable must be set");
}
Optional Variables (Graceful Fallback)
For variables with defaults or optional features:
const myVar = process.env.MY_OPTIONAL_VAR ?? "default-value";
Current Required Secrets
These MUST be set in the location(s) indicated:
| Secret | Purpose | Location |
|---|
NEXT_PUBLIC_API_URL | Backend API URL | Coolify + GitHub Secrets |
HMAC_SECRET | API request signing | Coolify + GitHub Secrets |
SENTRY_DSN | Error tracking | Coolify + GitHub Secrets |
DEEPL_API_KEY | Translation service | Coolify |
STRIPE_SECRET_KEY | Payment processing | Coolify |
STRIPE_WEBHOOK_SECRET | Webhook verification | Coolify |
REVALIDATE_SECRET | Cache revalidation | Coolify + GitHub Secrets |
COOLIFY_TOKEN | Deployment trigger | GitHub Secrets only |
COOLIFY_WEBHOOK_URL | Deployment trigger | GitHub Secrets only |
Current Optional Secrets
| Secret | Purpose | Fallback |
|---|
NEXT_PUBLIC_GOOGLE_ANALYTICS | Analytics | Disabled |
NEXT_PUBLIC_GOOGLE_ADS | Ads | Disabled |
NEXT_PUBLIC_GOOGLE_MAPS | Maps | Disabled |
SENTRY_AUTH_TOKEN | Source maps | Warning only |
CLOUDFLARE_ZONE_ID | CDN purge | Skipped |
CLOUDFLARE_API_TOKEN | CDN purge | Skipped |
GOOGLE_PLACES_API_KEY | Places API | Disabled |
REDIS_URL | Redis cache | Filesystem |
Step-by-Step: Adding a New Environment Variable
Step 1: Add to Code
const myVar = process.env.MY_NEW_VAR;
if (!myVar) {
}
Step 2: Add to .env.* files
This project uses env-cmd for local builds. Add the variable to all applicable env files:
.env.development — used by yarn build:development, yarn start:development
.env.staging — used by yarn build:staging, yarn start:staging
.env.production — used by yarn build:production, yarn start:production
Important: NEXT_PUBLIC_* vars (especially NEXT_PUBLIC_API_URL) MUST be in these files because they're inlined at build time and affect the service worker registration and test runs.
Step 3: Add to Coolify
- Go to Coolify dashboard → your application
- Go to Environment Variables tab
- Add
MY_NEW_VAR with the production value
- Check "Build Variable" if needed during Docker build (e.g.,
NEXT_PUBLIC_* vars)
- Redeploy for changes to take effect
Step 4: Add to deploy-coolify.yml
If the variable is needed during CI build/test (e.g., NEXT_PUBLIC_* vars baked at build time):
- name: Build Next.js application
env:
MY_NEW_VAR: ${{ secrets.MY_NEW_VAR }}
run: yarn build
Step 5: Add to GitHub Secrets
- Go to GitHub repo → Settings → Secrets and variables → Actions
- Click "New repository secret"
- Add
MY_NEW_VAR with the actual value
Step 6: Update Documentation (Optional but Recommended)
Add to the tables in this skill file.
NEXT_PUBLIC_ Prefix Rules
| Prefix | Visibility | Use Case |
|---|
NEXT_PUBLIC_* | Client + Server | Analytics IDs, public URLs |
| No prefix | Server only | API keys, secrets, tokens |
Security: Never expose secrets to the client. API keys like STRIPE_SECRET_KEY must NOT have NEXT_PUBLIC_ prefix.
Important: NEXT_PUBLIC_* vars are inlined at build time. They must be available both in Coolify (as build variables) and in the GitHub Actions workflow (for CI builds).
Local Development
Create .env.local (gitignored) for overrides, and ensure .env.development has the variable:
HMAC_SECRET=dev-secret-for-testing
NEXT_PUBLIC_API_URL=https://api.esdeveniments.cat/api
Common Mistakes
- Adding to code but not Coolify → Runtime crash in container
- Adding to Coolify but not GitHub Secrets → CI build fails
- Adding to workflow but not GitHub Secrets → Empty value, validation fails
- Using
NEXT_PUBLIC_ for secrets → Exposed to browser
- Forgetting
.env.* files → build:development/build:staging broken
- Not marking
NEXT_PUBLIC_* as build variable in Coolify → Variable undefined in client bundle
Checklist for New Env Variable
Auth (Logto) env vars
LOGTO_* are runtime auth secrets. Per-environment secrets use the _STAGING
suffix in GitHub (e.g. LOGTO_APP_SECRET_STAGING), matching the existing
COOLIFY_TOKEN / COOLIFY_TOKEN_STAGING convention. Best practice is one
Logto instance per environment (not per-env apps in one instance). Full
setup, the var table, and the CI guard are in
docs/logto-auth-setup.md.
Files to Reference
.env.development, .env.staging, .env.production — local/CI builds via env-cmd
- .github/workflows/deploy-coolify.yml — CI/CD workflow
- Coolify dashboard → Application → Environment Variables
- GitHub repo → Settings → Secrets → Actions
Testing Your Changes
After adding a new env var:
- Local: Add to
.env.development, run yarn dev or yarn build:development
- CI dry-run: Push to branch, check workflow logs
- Production: Add to Coolify +
.env.production, merge to main, verify via /api/health endpoint