DEV Community

Justin Poehnelt
Justin Poehnelt

Posted on • Originally published at justin.poehnelt.com on

Cloudflare workers with Wrangler for dev, staging, and prod

Cloudflare workers are configured using a tool called wrangler combined with a wrangler.toml file. This file contains the configuration for the worker, including the name, routes, vars, and much more.

A recent challenge I had was to deploy a worker to a dev environment and then promote it to staging and prod and the combine this with GitHub actions for continuous deployment.

This post assumes you have a basic understanding of Cloudflare workers and wrangler. Some configuration options may be omitted for brevity.

Basic Wrangler configuration in TOML

The base wrangler.toml file looks like this:

name = "my-worker"
route = "example.com/*"
[var]
  foo = "bar"
Enter fullscreen mode Exit fullscreen mode

This will deploy a worker, when using Wrangler deploy, named my-worker to a route of example.com/* and set a variable foo to bar that can be accessed in the worker code.

This does not automatically create the domain in Cloudflare. You will need to do that manually or use the Cloudflare API to create the domain.

Adding environments for dev, staging, and prod

This configuration file can be extended to include a dev environment:

[env.dev]
name = "my-worker-dev"
route = "dev.example.com/*"

[env.dev.var]
  foo = "bar"
Enter fullscreen mode Exit fullscreen mode

This will deploy a worker named my-worker-dev to a route of dev.example.com/* and set a variable foo to bar that can be accessed in the worker code.

See the Wrangler deploy documentation for more information on deploying to different environments and the documentation on Cloudflare workers environments.

I removed the default route, name, and var from the base configuration and added a new section for dev. This forces me to call wrangler deploy --env dev to deploy to the dev environment and will throw an error if I try to deploy to the default environment because there isn’t one.

To promote the worker to staging and prod, I can add additional sections to the wrangler.toml file:

[env.staging]
name = "my-worker-staging"
route = "staging.example.com/*"
[env.staging.var]
  foo = "bar"
[env.prod]
name = "my-worker-prod"
route = "example.com/*"
[env.prod.var]
  foo = "bar"
Enter fullscreen mode Exit fullscreen mode

This enables me to call wrangler deploy --env staging and wrangler deploy --env prod to deploy to the staging and prod environments respectively.

Some fields are not inheritable across environments such as vars and kv-namespaces. You will need to set these for each environment.

GitHub actions

To automate the deployment of the worker to the dev, staging, and prod environments, I can use GitHub actions. Here is an example of a GitHub action that deploys the worker to the correct environment based upon the context of the action, such as a push to the main branch or a manual trigger.

name: Deploy
on:
  push:
    branches:
      - main
  workflow_dispatch:
    inputs:
      environment:
        description: 'Environment'
        required: true
        type: choice
        options:
          - prod
          - staging
        default: staging
jobs:
  deploy:
    concurrency:
      group: ${{ github.workflow }}-${{ github.ref }}
    runs-on: ubuntu-latest
    env:
      CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
      CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
    steps:
      # other steps to checkout/build/test/etc
      - name: Manual deploy
        if: ${{ github.event_name == 'workflow_dispatch' }}
        run: wrangler deploy --env=${{ github.event.inputs.environment }}
      - name: Automatic deploy to staging
        if: ${{ github.ref == 'refs/heads/main' && github.event_name == 'push' }}
        run: wrangler deploy --env=staging
  promote:
    if: ${{ github.ref == 'refs/heads/main' }}
    runs-on: ubuntu-latest
    needs: deploy
    env:
      CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
      CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
    steps:
      # verify staging deployment through integration tests
      - run: wrangler deploy  --env=staging
Enter fullscreen mode Exit fullscreen mode

Alternatively, you could promote to prod when a tag is pushed:

name: Deploy
on:
  push:
    branches:
      - main
    tags:
      - '*'
Enter fullscreen mode Exit fullscreen mode

And then add a step to deploy to prod:

      - name: Automatic deploy to prod from tag
        if: $false
        run: wrangler deploy  --env=prod
Enter fullscreen mode Exit fullscreen mode

All of this omits the hard part of knowing when to promote from staging to prod. The above demonstrates patterns for using tags, testing, or a manual dispatch to promote to prod.

Other considerations

Here are some other considerations when deploying workers to different environments.

Git commit, tag, etc. in worker code

In any of these cases, you may want to consider injecting a variable into the worker code to indicate the current Git commit, tag, etc.

      - name: Automatic deploy to prod from tag
        if: $false
        run: wrangler deploy  --env=prod --var GIT_COMMIT=$
Enter fullscreen mode Exit fullscreen mode

Encrypted vars, integrations, etc

These must individually be set for each environment via the dashboard. 😞

Top comments (0)