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"
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"
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"
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
Alternatively, you could promote to prod when a tag is pushed:
name: Deploy
on:
push:
branches:
- main
tags:
- '*'
And then add a step to deploy to prod:
- name: Automatic deploy to prod from tag
if: $false
run: wrangler deploy --env=prod
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=$
Encrypted vars, integrations, etc
These must individually be set for each environment via the dashboard. 😞
Top comments (0)