Environments
Tamer supports per-env configuration via local, env, and the --env flag. --env defaults to local for most commands; deploy requires it explicitly. No command silently defaults to prod.
Env override structure
defineWorker({
// base config (applies to all envs)
vars: { ENVIRONMENT: "local" },
// Declare the bare apex once — Tamer prefixes non-prod envs
// (dev → dev.app.example.com). Do not put `dev.` in the host here.
tamerRoutes: [{ host: "app.example.com", customDomain: true }],
local: {
// local-only overrides
vars: { ENVIRONMENT: "local" },
},
env: {
dev: {
// dev overrides — routes inherit base + auto `{env}.` prefix
vars: { ENVIRONMENT: "dev" },
},
prod: {
vars: { ENVIRONMENT: "prod" },
},
},
});How merging works
The merge is a shallow overlay: env-specific values replace base values by key. For vars, individual keys are merged (not replaced wholesale):
// base
vars: { TENANT_ID: "abc", ENVIRONMENT: "local", API_URL: "http://localhost:3000" }
// env.dev override
vars: { ENVIRONMENT: "dev", API_URL: "https://dev.api.example.com" }
// merged result for --env dev
vars: { TENANT_ID: "abc", ENVIRONMENT: "dev", API_URL: "https://dev.api.example.com" }Route expansion
tamerRoutes are expanded per env. Env prefixes the hostname (unlike Cloudflare resource names, which suffix -{env}). See Naming → Env placement.
| Env | Pattern | Example |
|---|---|---|
prod / production | Bare apex | app.example.com |
Any other env (incl. ephemeral pr-*) | {env}.{apex} | dev.app.example.com, pr-1234.app.example.com |
local | No route | — |
Declare host: "ca.example.com" (bare). Deploying --env dev yields dev.ca.example.com. Putting dev. in the declared host would double-prefix to dev.dev.ca.example.com.
wfp.ephemeralEnvPattern does not affect routing. It controls dispatch-namespace sharing, the ephemeral env fallback to env.dev overrides, and tamer env gc eligibility.
The local env
local is special: no Cloudflare API calls, no tamer-state row, no CLOUDFLARE_* required. Tamer writes gitignored wrangler.json + wrangler.vitest.json with synthesized binding IDs; you run wrangler dev / vite dev / Vitest. See Local Development.
Ephemeral envs
Any env matching wfp.ephemeralEnvPattern (e.g. ^pr-) gets its own resource namespace within a shared dispatch namespace. Useful for PR preview environments. Set the pattern under wfp at the stack root:
export default defineConfig({
stack: "my-app",
wfp: { ephemeralEnvPattern: "^pr-", namespaces: { /* … */ } },
// …
});Ephemeral pr-* envs are not in the default protectedEnvs list, so tamer destroy / reset do not require --confirm-env or --force unless you add them. CI often still passes both for consistency.
Protected environments
Root-level protectedEnvs gates destructive commands so a typo cannot wipe prod. Default when unset: ["prod", "production"].
export default defineConfig({
stack: "my-app",
// Widen (add qa) or opt out with []
protectedEnvs: ["prod", "production", "qa"],
// …
});| Command | Confirmation | Break-glass |
|---|---|---|
tamer destroy, tamer reset | --confirm-env <name> (must match --env) | --force |
tamer wfp tenant destroy, wfp tenant reset | --confirm-tenant <workspace> (must match --workspace) | --force |
--force only skips this typed confirmation — it does not change deletion scope (preserveOnDestroy, --wipe-metadata, --target, etc.). See Lifecycle.
${tamer:env} reference
Use ${tamer:env} in worker vars to interpolate the current env name. This eliminates per-env overrides for env-derived URLs:
vars: {
VITE_API_CLIENT_URL: "https://${tamer:env}.api.example.com/v1",
}- dev →
https://dev.api.example.com/v1 - pr-1234 →
https://pr-1234.api.example.com/v1 - prod → override with the bare apex URL
Combined with ephemeral fallback (below), PR preview envs resolve correctly without per-PR config.
Ephemeral env fallback
When an env matches wfp.ephemeralEnvPattern and has no explicit override block in env: { ... }, Tamer falls back to env.dev overrides. This means ephemeral PR envs automatically inherit dev's configuration (routes, observability, vars) with ${tamer:env} making values correct per env.