Deploying websites with Cloudflare Workers and Gitlab CI/CD
There are plenty of ways to deploy a front-end application. Like on a hosted virtual machine, docker, and Kubernetes. But nowadays, the cheapest, and the easiest is hosting a static website. There is a lot of platforms to do it: Github Pages, Firebase, Surge, Netlify, and Cloudflare Workers, the tool that will be shown in this article.
And it’s easy to build modern static websites with generators, such as Gatsby, Nuxt.js, and Next.js.
Cloudflare Workers
👉 The project that will be used as an example in this tutorial is a simple website made in Vue.js with Next.js. You can check the repository here.
- Once you created an account on Cloudflare, you need to choose a subdomain on Workers.
- Now you can install Wrangler CLI:
npm i @cloudflare/wrangler -g
3. Login with:
wrangler login
4. Get your Account ID:
wrangler whoami
5. Create a file called wrangler.toml
with:
name = "app"
type = "webpack"
account_id = "ACCOUNT_ID"
workers_dev = true
[site]
bucket = "dist"
Just replace ACCOUNT_ID
with your Account ID. And the bucket
field refers to the directory that contains the static files of your websites. In this case, I used Next.js to build the static website, and the output folder is dist
.
6. To publish run:
wrangler publish --env website
Then you’ll see a success message with the URL of your application.
Environments
You can create different environments, with specific settings to publish your website with wrangler. To create new environments just add a line with [env.my-environment]
and its settings below.
Take a look at the official documentation to know all the possible settings.
Gitlab CI/CD
Something really cool and useful to do using those environments is to publish different versions of your app based on the branches from your git repository. So let’s set up a Gitlab CI/CD.
The first thing you need to do is to set two environment variables on your Gitlab repository. Go to settings on the right sidebar, go to CI/CD section, at variables, click on the expand button, add CF_ACCOUNT_ID
variable with your Account ID of Cloudflare, and CF_API_TOKEN
with your API Token. Make sure that the Protected variable flag is not marked.
Then, create a bash script that will publish an environment based on your current branch. Create a new file called deploy.sh
:
#!/usr/bin/env sh
NAME=$(echo "$1" | tr '[:upper:]' '[:lower:]' | sed 's/_/-/g')
cp wrangler.toml wrangler.toml.tmp
printf "\\n[env.$NAME]\\nname=\\"$NAME\\"\\n" >> wrangler.toml
echo $NAME
yarn generate
npx wrangler publish --env $NAME
mv wrangler.toml.tmp wrangler.toml
This script gets the argument from the command, transforms it to lower case, and replaces underscores with dashes. This is will be used to create a new environment with this name on wrangler.toml
. Then executes yarn generate
to generate the website bundle on dist
directory, and publish to Workers sites with wrangler. Finally, wrangler.toml
is reverted to the original state.
Make sure this file is executable. Case not, just run:
chmod +x deploy.sh
And add it as a script on package.json
:
{
...,
"scripts": {
...,
"deploy": "./deploy.sh",
},
...
}
Create the gitlab-ci.yml
, where you configure the CI/CD pipelines:
# .gitlab-ci.ymlstages:
- Deploy on Cloudflaredeploy:
- stage: Deploy on Cloudflare
- image: node:12-alpine
script:
- export USER=$(whoami)
- yarn
- yarn deploy $CI_COMMIT_REF_NAME
only:
- merge_request
This file sets up one job that installs the project dependencies, then executes the deploy
script, from the file deploy.sh
passing the current branch name, or tag, as the argument. The tag only
is where you choose when this job will be triggered, in this case, it will be triggered on every new merge request.
Conclusion
All done! Now try it, creating a merge request! You will see a job running in a few seconds, then a new environment will be published on Cloudflare Workers with the changes that you made. This is great to test new features that are being developed. Also, you can use Cloudflare Workers with another front-end framework or set a CI/CD with another platform, the concepts still the same.