Back to Blog
Lesson 46 of the Cloudflare: Cloudflare for Developers: DNS to CDN course
Cloud NativeAugust 25, 20264 min read

Managing Multiple Environments: A Guide for Cloudflare Developers

Learn to use Wrangler environments to manage staging and production, isolate your D1 and R2 instances, and automate safe deployment workflows.

CloudflareWranglerEnvironmentsStagingProductionDevOps
Close-up of a directional signpost with city names and distances in an urban setting.

Previously in this course, we explored handling WebSockets to enable real-time features. Now that our project is feature-rich, we need a robust way to manage it across different deployment targets.

In professional software engineering, you never test code directly in production. You need a sandbox. By mastering Wrangler environments, you can ensure that your staging tests use isolated data, preventing accidental corruption of your production D1 databases or R2 storage buckets.

Understanding Wrangler Environments

Wrangler uses the wrangler.toml file to define "environments." An environment is essentially a named configuration block that overrides your default settings. This allows you to point the same codebase to different D1 databases, R2 buckets, or custom variables depending on whether you are deploying to staging or production.

Think of it as a blueprint: the code remains constant, but the "infrastructure wiring" changes based on the target.

Defining Environments in wrangler.toml

To set up staging and production, open your wrangler.toml. You’ll move your current configuration into a [default] block (or keep it at the top) and add specific environment blocks.

TOML
name = "my-project"
main = "src/index.ts"

# Default configuration (used for local development)
[vars]
ENVIRONMENT = "development"

[env.staging]
name = "my-project-staging"
routes = ["staging.example.com/*"]
[env.staging.vars]
ENVIRONMENT = "staging"
# Bind to a dedicated staging D1 database
[[env.staging.d1_databases]]
binding = "DB"
database_id = "staging-uuid-here"

[env.production]
name = "my-project-prod"
routes = ["example.com/*"]
[env.production.vars]
ENVIRONMENT = "production"
# Bind to the live production D1 database
[[env.production.d1_databases]]
binding = "DB"
database_id = "production-uuid-here"

Managing Separate D1 and R2 Instances

The key to environment isolation is ensuring that your bindings—the links between your Worker and your storage—are unique. As we learned in Schema Design for D1, migrations are tied to specific database IDs.

When you create a new environment, you must:

  1. Create a new D1 database via wrangler d1 create my-db-staging.
  2. Update the database_id in your wrangler.toml under the [env.staging.d1_databases] section.
  3. Apply migrations specifically to that database: wrangler d1 migrations apply my-db-staging --env staging

This ensures that running wrangler deploy --env staging never impacts your production data.

Automating Promotion

"Promotion" is the process of moving code from staging to production. While we covered deployment pipelines in CI/CD: Deployment Pipelines, environments add a layer of safety.

To promote code, your GitHub Action should execute two distinct steps:

  1. Deploy to Staging: Run wrangler deploy --env staging. Perform automated integration tests here.
  2. Deploy to Production: Only after tests pass, run wrangler deploy --env production.

Hands-on Exercise

  1. Modify your wrangler.toml: Add a [env.staging] block.
  2. Provision: Create a new D1 database instance for staging.
  3. Deploy: Run wrangler deploy --env staging and verify that the Worker is accessible at your staging route.
  4. Inspect: Use wrangler d1 execute <db_name> --env staging --command "SELECT * FROM users" to verify you are hitting the correct, isolated database.

Common Pitfalls

  • Shared IDs: Never reuse the same database_id or bucket_name across environments. If you accidentally point staging to the production database, your tests will destroy real user data.
  • Secret Mismatch: Remember that wrangler secret commands are also environment-aware. You must run wrangler secret put API_KEY --env staging to set secrets for the staging environment; the production secrets will not be available there.
  • Forgot Migrations: Always remember to run your migrations against the correct environment before deploying code that expects a specific database schema.

FAQ

Can I use environments for local development? Yes. Running wrangler dev --env staging will start a local server using the configurations defined in your [env.staging] block.

How many environments can I have? Technically, there is no hard limit, but keep it simple. Usually, development (local), staging, and production cover 99% of use cases.

Do I need different domains for each? It is highly recommended. Using subdomains like staging.example.com keeps your production analytics clean and prevents search engines from indexing your test environment.

Recap

Managing multiple environments is the foundation of professional deployment workflows. By using Wrangler environments, you isolate your D1 and R2 resources, protect your production data, and create a repeatable path for shipping features. Always verify your bindings and secrets before triggering a deployment.

Up next: We'll dive into Optimizing SQL Queries to ensure our production databases remain performant as our data grows.

Similar Posts