Environments
Wrangler allows you to use environments to create different configurations for the same Worker application. Environments are configured in the Worker's Wrangler configuration file.
When you create an environment, Cloudflare effectively creates a new Worker with the name <top-level-name>-<environment-name>. For example, a Worker project named my-worker with an environment dev would deploy as a Worker named my-worker-dev.
Use Wrangler environments for persistent Workers such as staging or development. Use Previews when you want every branch or pull request to get a URL. For the difference between these workflows, refer to Compare workflows.
Review the following environments flow:
-
Create a Worker, named
my-workerfor example. -
Create an environment, for example
dev, in the Worker's Wrangler configuration file, by adding a[env.<ENV_NAME>]section.{ "name": "my-worker", "env": { "<ENV_NAME>": { // environment-specific configuration goes here } } }name = "my-worker" [env."<ENV_NAME>"] -
You can configure the
devenvironment with different values to the top-level environment. Refer here for how different options are inherited - or not inherited - between environments. For example, to set a different route for a Worker in thedevenvironment:{ "$schema": "./node_modules/wrangler/config-schema.json", "name": "your-worker", "route": "example.com", "env": { "dev": { "route": "dev.example.com", }, }, }"$schema" = "./node_modules/wrangler/config-schema.json" name = "your-worker" route = "example.com" [env.dev] route = "dev.example.com" -
Environments are used with the
--envor-eflag on Wrangler commands. For example, you can develop the Worker in thedevenvironment by runningnpx wrangler dev -e=dev, and deploy it withnpx wrangler deploy -e=dev.Alternatively, you can use the
CLOUDFLARE_ENVenvironment variable to select the active environment. For example,CLOUDFLARE_ENV=dev npx wrangler deploywill deploy to thedevenvironment. The--envcommand line argument takes precedence over theCLOUDFLARE_ENVenvironment variable.Note
If you're using the Cloudflare Vite plugin, you select the environment at dev or build time via the
CLOUDFLARE_ENVenvironment variable rather than the--envflag. Otherwise, environments are defined in your Worker config file as usual. For more detail on using environments with the Cloudflare Vite plugin, refer to the plugin documentation.
Non-inheritable keys and environments
Non-inheritable keys are configurable at the top-level, but cannot be inherited by environments and must be specified for each environment.
For example, bindings and environment variables are non-inheritable, and must be specified per environment in your Wrangler configuration file.
Review the following example Wrangler file:
{
"$schema": "./node_modules/wrangler/config-schema.json",
"name": "my-worker",
"vars": {
"API_HOST": "example.com",
},
"kv_namespaces": [
{
"binding": "<BINDING_NAME>",
"id": "<KV_NAMESPACE_ID_DEV>",
},
],
"env": {
"production": {
"vars": {
"API_HOST": "production.example.com",
},
"kv_namespaces": [
{
"binding": "<BINDING_NAME>",
"id": "<KV_NAMESPACE_ID_PRODUCTION>",
},
],
},
},
}"$schema" = "./node_modules/wrangler/config-schema.json"
name = "my-worker"
[vars]
API_HOST = "example.com"
[[kv_namespaces]]
binding = "<BINDING_NAME>"
id = "<KV_NAMESPACE_ID_DEV>"
[env.production.vars]
API_HOST = "production.example.com"
[[env.production.kv_namespaces]]
binding = "<BINDING_NAME>"
id = "<KV_NAMESPACE_ID_PRODUCTION>"
Service bindings
To use a service binding that targets a Worker in a specific environment, you need to append the environment name to the target Worker name in the service field. This should be in the format <worker-name>-<environment-name>.
In the example below, we have two Workers, both with a staging environment. worker-b has a service binding to worker-a. Note how the service field in the staging environment points to worker-a-staging, whereas the top-level service binding points to worker-a.
{
"$schema": "./node_modules/wrangler/config-schema.json",
"name": "worker-a",
"vars": {
"FOO": "<top-level-var>",
},
"env": {
"staging": {
"vars": {
"FOO": "<staging-var>",
},
},
},
}"$schema" = "./node_modules/wrangler/config-schema.json"
name = "worker-a"
[vars]
FOO = "<top-level-var>"
[env.staging.vars]
FOO = "<staging-var>"
{
"$schema": "./node_modules/wrangler/config-schema.json",
"name": "worker-b",
"services": {
"binding": "<BINDING_NAME>",
"service": "worker-a",
},
// Note how `service = "worker-a-staging"`
"env": {
"staging": {
"service": {
"binding": "<BINDING_NAME>",
"service": "worker-a-staging",
},
},
},
}"$schema" = "./node_modules/wrangler/config-schema.json"
name = "worker-b"
[services]
binding = "<BINDING_NAME>"
service = "worker-a"
[env.staging.service]
binding = "<BINDING_NAME>"
service = "worker-a-staging"
Secrets for production
You may assign environment-specific secrets by running the command wrangler secret put <KEY> -env. You can also create dotenv type files named .dev.vars.<environment-name>.
Like other environment variables, secrets are non-inheritable and must be defined per environment.
Secrets in local development
Caution
Do not use vars to store sensitive information in your Worker's Wrangler configuration file. Use secrets instead.
Put secrets for use in local development in either a .dev.vars file or a .env file, in the same directory as the Wrangler configuration file.
Note
You can use the secrets configuration property to declare which secret names your Worker requires. When defined, only the keys listed in secrets.required are loaded from .dev.vars or .env. Additional keys are excluded and missing keys produce a warning.
:::info
Choose to use either .dev.vars or .env but not both. If you define a .dev.vars file, then values in .env files will not be included in the env object during local development.
:::
These files should be formatted using the dotenv syntax. For example:
SECRET_KEY="value"
API_TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"Do not commit secrets to git
The .dev.vars and .env files should not be committed to git. Add .dev.vars* and .env* to your project's .gitignore file.
To set different secrets for each Cloudflare environment, create files named .dev.vars.<environment-name> or .env.<environment-name>.
When you select a Cloudflare environment in your local development, the corresponding environment-specific file will be loaded ahead of the generic .dev.vars (or .env) file.
- When using
.dev.vars.<environment-name>files, all secrets must be defined per environment. If.dev.vars.<environment-name>exists then only this will be loaded; the.dev.varsfile will not be loaded. - In contrast, all matching
.envfiles are loaded and the values are merged. For each variable, the value from the most specific file is used, with the following precedence:.env.<environment-name>.local(most specific).env.local.env.<environment-name>.env(least specific)
Controlling `.env` handling
It is possible to control how .env files are loaded in local development by setting environment variables on the process running the tools.
- To disable loading local dev vars from
.envfiles without providing a.dev.varsfile, set theCLOUDFLARE_LOAD_DEV_VARS_FROM_DOT_ENVenvironment variable to"false". - To include every environment variable defined in your system's process environment as a local development variable, ensure there is no
.dev.varsand then set theCLOUDFLARE_INCLUDE_PROCESS_ENVenvironment variable to"true". This is not needed when using thesecretsconfiguration property, which loads fromprocess.envautomatically.
Examples
Staging and production environments
The following Wrangler file adds two environments, [env.staging] and [env.production], to the Wrangler file. If you are deploying to a Custom Domain or route, you must provide a route or routes key for each environment.
{
"$schema": "./node_modules/wrangler/config-schema.json",
"name": "my-worker",
"route": "dev.example.com/*",
"vars": {
"ENVIRONMENT": "dev",
},
"env": {
"staging": {
"vars": {
"ENVIRONMENT": "staging",
},
"route": "staging.example.com/*",
},
"production": {
"vars": {
"ENVIRONMENT": "production",
},
"routes": ["example.com/foo/*", "example.com/bar/*"],
},
},
}"$schema" = "./node_modules/wrangler/config-schema.json"
name = "my-worker"
route = "dev.example.com/*"
[vars]
ENVIRONMENT = "dev"
[env.staging]
route = "staging.example.com/*"
[env.staging.vars]
ENVIRONMENT = "staging"
[env.production]
routes = [ "example.com/foo/*", "example.com/bar/*" ]
[env.production.vars]
ENVIRONMENT = "production"
You can pass the name of the environment via the --env flag to run commands in a specific environment.
With this configuration, Wrangler will behave in the following manner:
npx wrangler deployUploaded my-worker
Published my-worker
dev.example.com/*npx wrangler deploy --env stagingUploaded my-worker-staging
Published my-worker-staging
staging.example.com/*npx wrangler deploy --env productionUploaded my-worker-production
Published my-worker-production
example.com/*Any defined environment variables (the vars key) are available via the env object in your Worker.
With this configuration, the env.ENVIRONMENT variable can be used to call specific code depending on the given environment:
export default {
async fetch(request, env, ctx) {
if (env.ENVIRONMENT === "staging") {
// staging-specific code
} else if (env.ENVIRONMENT === "production") {
// production-specific code
}
},
};Staging environment with *.workers.dev
To deploy your code to your *.workers.dev subdomain, include workers_dev = true in the desired environment. Your Wrangler file may look like this:
{
"$schema": "./node_modules/wrangler/config-schema.json",
"name": "my-worker",
"route": "example.com/*",
"env": {
"staging": {
"workers_dev": true,
},
},
}"$schema" = "./node_modules/wrangler/config-schema.json"
name = "my-worker"
route = "example.com/*"
[env.staging]
workers_dev = true
With this configuration, Wrangler will behave in the following manner:
npx wrangler deployUploaded my-worker
Published my-worker
example.com/*npx wrangler deploy --env stagingUploaded my-worker
Published my-worker
https://my-worker-staging.<YOUR_SUBDOMAIN>.workers.devCaution
When you create a Worker via an environment, Cloudflare automatically creates an SSL certification for it. SSL certifications are discoverable and a matter of public record. Be careful when naming your environments that they do not contain sensitive information, such as, migrating-service-from-company1-to-company2 or company1-acquisition-load-test.