Flying with this blog

Posted on Aug 22, 2022

Inspired by others, I decided to try out fly.io for hosting this blog, and deploying automagically after pushing to my repository at sr.ht. It was surprisingly simple and I only leaked my access token for fly.io once, great success!

A TL;DR summary:

  1. Create a new app in your repository, flyctl launch
  2. Update your fly.toml
  3. Create a Dockerfile in your repository
  4. Update your .build.yml
  5. Write a new blog entry about it to test the entire chain

fly.toml

The only necessary change is to update the internal_port directive under the services section, change it to reflect the port your web server is running on (for gostatic, it's 8043). This is how fly.io determines if the deployment was successful or not, and if your webserver doesn't reply on the specified port then the deployment will be rolled back.

Here's my complete fly.toml:

  # fly.toml file generated for solitary-thunder-2257 on 2022-08-22T00:23:50+02:00

  app = "solitary-thunder-2257"
  kill_signal = "SIGINT"
  kill_timeout = 5
  processes = []

  [env]

  [experimental]
    allowed_public_ports = []
    auto_rollback = true

  [[services]]
    http_checks = []
    # Change this port if necessary!
    internal_port = 8043
    processes = ["app"]
    protocol = "tcp"
    script_checks = []

    [services.concurrency]
      hard_limit = 25
      soft_limit = 20
      type = "connections"

    [[services.ports]]
      force_https = true
      handlers = ["http"]
      port = 80

    [[services.ports]]
      handlers = ["tls", "http"]
      port = 443

    [[services.tcp_checks]]
      grace_period = "1s"
      interval = "15s"
      restart_limit = 0
      timeout = "2s"

Dockerfile

This is the entire file:

FROM klakegg/hugo:0.101.0-ext-onbuild AS hugo
FROM pierrezemb/gostatic
COPY --from=hugo /target/ /srv/http/

The first container builds the site when started, and then we just copy the result to /srv/http from where the webserver will serve it. I was planning to use nginx for this, but tried gostatic due to reasons and it seems…fine?

Update - static-web-server

So I got curious (bored) and changed the webserver from goStatic to static-web-server (sws), which is basically the same but written in another language (with an amazing evangelism strike force!).

The entire migration was tough, look at this!

FROM klakegg/hugo:0.101.0-ext-onbuild AS hugo
FROM joseluisq/static-web-server:2
COPY --from=hugo /target/ /public

sws runs on port 80, so update the internal_port = 8043 to internal_port = 80 in your fly.toml. And yes, that's it.

Building and deploying from builds.sr.ht

First, define your secrets for your build. I've just defined my secrets as a file in which looks something like this, and is saved to ~/.flyio_secrets:

  export FLY_ACCESS_TOKEN=access-token-goes-here
  export FLY_APP=app-name-goes-here

You can find your access token by running flyctl auth token, and the app name is found in your fly.toml (or by running flyctl apps list).

When saving your secret, it will get an UUID. Copy that into this build manifest (which in turn is saved as .build.yml in your repository root folder), and update the git repository address and the path you cd into:

  image: alpine/latest
  packages:
    - hugo
    - go
  secrets:
    - <secret-uuid-goes-here>
  sources:
    # - git@git.sr.ht:~monotux/monotux.srht.site
    - <git-repository-goes-here>
  tasks:
    - deploy: |
        curl -L https://fly.io/install.sh | sh
        export FLYCTL_INSTALL="/home/build/.fly"
        export PATH="$FLYCTL_INSTALL/bin:$PATH"
        # CHANGEME
        cd monotux.srht.site/
        set +x
        source ~/.flyio_secrets
        flyctl deploy >/dev/null 2>&1        

Commit, push and see how your site is built and deployed automagically after pushing to your repository.