July 31st, 2020
Zola is a static site generator, similar to Jekyll and Gatsby, built entirely in Rust.
Being built in Rust has some advantages. Zola is crazy fast and is a single binary with no dependencies. It's pretty similar to other static site generators, though, and if you're not a Rust developer interested in extending Zola at all, then the performance difference may not be enough justification for you to choose Zola over something like Jekyll.
While my examples in this post will showcase Zola, this process will work almost the same with any static site generator that you wish to use.
Cloudflare Worker Sites allow you deploy your static site directly to Cloudflare's CDN.
This is a big part of JAM Stack: moving from content generated dynamically on a server request to statically generated content delivered directly from a CDN. This removes the need to manage and maintain web servers.
Cloudflare Worker Sites are built on Cloudflare's "Workers product" and allow you to delivery your static site directly from the Cloudflare CDN.
Cloudflare Workers Sites are also pretty affordable at $5/month.
The process is incredible simple. In fact, I was able to get my site up and running in about an hour (including researching and reading documentation). To help with this, Cloudflare provides a nifty CLI tool (built using Rust!) called Wrangler.
Wrangler is a super fast CLI for Cloudflare Workers built in Rust. With Wrangler, you can initialize a site, configure it and publish. You can also preview and test your changes before publishing.
You can find the GitHub repo for Wrangler here. The full documentation can be found here.
I'll go over how to use Wrangler both locally and as a part of your CI/CD process in a moment.
Creating a site in Zola, while pretty simple, is a bit out of the scope of this post. However, Zola does provide a getting started guide that you can follow to get a site setup in minutes.
If you're familiar with something like Jekyll or Gatsby, this will all be pretty familiar for you.
Once you have a static site generated, you'll need to setup a Cloudflare Workers plan. Unfortunately, the free plan won't work for Worker Sites. You'll need the Unlimited plan, which is $5/month.
Once you've setup the plan, you'll just want to make note of your Account Id. You'll need this in a moment when you configure you're Workers site. Details on finding that here.
You'll also need to generate an API Token that Wrangler can use. You can do this from here: https://dash.cloudflare.com/profile/api-tokens. You'll want to use the Edit Workers template. Take note of this token as you won't be able to see it again later.
You can install Wrangler using NPM or Cargo: https://developers.cloudflare.com/workers/tooling/wrangler/install/.
Note: If you decide to use Cargo, it will take several minutes since cargo will compile the Wrangler binary for you.
With Wrangler installed, you can run the following command from inside your site directory:
wrangler init
This will generated a wrangler.toml
file and a workers-site
directory.
Open the wrangler.toml
file, and edit the account_id
field with the account ID you noted earlier.
Also, set the bucket
field under the [site]
category to public
. That might look something like this:
[site]
bucket = "./public"
entry-point = "workers-site"
If you're using a generator other than Zola, you'll need to use the output directory for that generator. Here's a few examples:
Then you can run
wrangler config --api-key <YOUR_API_KEY>
Replace <YOUR_API_KEY>
with the Cloudflare API key that you just generated.
A final, optional step would be to configure a production environment. By default, Wrangler will publish to a dev worker site.
This will use your free http://<your-subdomain>.workers.dev
subdomain.
If you want to use a custom, personal domain, you'll need to set that up in Cloudflare if you haven't already, and then get the Zone ID for that domain. Since the files will all be served up from Cloudflare and you won't be using any kind of web server, you can just create a dummy DNS record with a value of 1.2.3.4
. More details here: https://developers.cloudflare.com/workers/quickstart#publish-to-your-domain.
Once you have you're zone id, you can add a production environment to your workers.toml
:
[env.production]
zone_id = "your_zone_id"
route = "example.com/*"
The route should be your personal domain.
Now that you're all configured, you can easily publish you're site with the following command:
wrangler publish
This will publish to your dev workers site and allow you to test before you publish to your production zone.
When you're ready to publish to your production environment, you can use the --env
argument:
wrangler publish --env production
Now, at this point you're technically done. However, you'll have to run wrangler publish
anytime you make any changes.
We can automate this really easily, though, by creating a CI/CD workflow using Github Actions.
We can create a completely automated CI/CD pipeline in just a few minutes using Github Actions. If you're not familiar with Github actions, I highly recommend checking them out. I'll go over a simple workflow that will build your site and publish to Cloudflare with just a little bit of yaml and all for free.
First, a little configuration is needed. Just like when running locally, Wrangler needs you Cloudflare API token. You definitely don't want to put that in source control or anywhere else public. So, we'll make use of Github Secrets.
Secrets allow you to store sensitive information and pass to your actions in a safe way. These are encrypted and never exposed at any point.
Creating them are easy. Just go ton your github repository and then select Settings
> Secrets
> Add Secret
. Full documentation can be read here.
Give it descriptive name, like CF_API_TOKEN
.
Now we can create our workflow.
In your site directory, create a folder called .github
. Inside of that folder, create another folder called workflows
.
Github will automatically discover the workflows in this folder and run them.
Now inside of .github/workflows
, create a yaml file. You can name anything. For example, deploy.yml
. Github does care about the naming.
Add the following to the contents:
on:
push:
branches:
- master
jobs:
deploy:
runs-on: ubuntu-latest
name: Deploy
steps:
- uses: actions/checkout@master
- name: Install and Run Zola Build
run: |
sudo snap install --edge zola
zola build
- name: Publish to Cloudflare
uses: cloudflare/wrangler-action@1.2.0
with:
apiToken: ${{ secrets.CF_API_TOKEN }}
environment: 'production'
This workflow tells Github that we want any push to the master
branch to trigger this deployment. Pull requests will not trigger this deployment at all, neither will pushes to any other branch.
Next, we're telling Github that we want to run all of this inside an small ubuntu image with the latest version. We then take the following actions:
zola build
to generate our site in the public
folder.CF_API_TOKEN
).That's it! Now any changes that you push to the master branch will automatically build and deploy to Cloudflare.
Now would probably be a good time to ensure that you have branch protection rules on the master
branch. This is only available for Pro, Team and Enterprise users, though. So, if you're using a free account, you'll just have to be a little more careful about the master
branch.