Just added a small upgrade to this website’s maintenance workflow: continuous deployment to the staging grounds.
For context, this website has a staging counterpart at https://www2.charleslanglois.dev, also hosted on fly.io. That way I can test changes without breaking the main “production” website at https://www.charleslanglois.dev . Not that anyone would notice if I broke something, but I prefer knowing my website is up and functional. If I push some changes that break things, I can leave staging broken while I fix it, without impacting the prod version, and that’s a peace of mind I appreciate.
And fly.io makes it pretty simple to manage a second deployment environment. Basically just need an additional fly app configuration file and a staging Caddyfile (reverse proxy configuration).
That being said, up until now I had no automation for the deployment of this website, though I had some minimal continuous integration that builds the website on every commit using nix.
Every deployment action to either prod or staging was done by hand, though, which is fine considering how simple that is and how rarely I push updates up to now (see the fly.io deploy commands in the repo’s makefile).
Now, with a small amount of YAML in my github actions, any updates pushed to the main branch of the git repository is automatically deployed to my staging environment:
name: CD staging
on:
push:
branches:
- main
workflow_dispatch:
jobs:
fly_to_staging:
environment: staging
name: build & deploy to staging
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: GitHub Action for flyctl
uses: superfly/flyctl-actions/setup-flyctl@1.5
- run: flyctl deploy --remote-only -c fly/staging/fly.toml
env:
FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
For production, I am still keeping it manual for now. That way, I can work fast and break things on staging, and only deploy on prod when I make a conscious decision and press the metaphorical red button. Seems like a good tradeoff between simplicity, convenience and stability.
My github actions workflows are pretty trivial to configure, thanks to existing plugins (such fly.io’s own). I only had to figure out the proper way to securely inject secrets for different environments. Took a bit of digging in the docs and trial and error, but I got it working.
Now I can trust my staging to reflect the latest buildable version of my website’s sources.
See ya in a next commit!