Az

Continuous Deploy Of Gopher Site

A few months back I built a tool to cross-compile my Hugo blog into one that can be accessed via the Gopher protocol.

More recently, I built a CI/CD pipeline on my GitLab* instance which automatically compiled and uploaded my website to AWS. I won’t cover that here, but I found a wonderful and perfect guide for it.

Sometime yesterday I decided to take this all one step further and integrate my hugogopher into that CI/CD pipeline. This means every time I commit a new post, not only does the blog get uploaded to the world wide web, but another version of it is compiled to a Gopher site and uploaded to the server that I have running.

Prerequisies

You’ll need a .gitlab-ci.yml file already in your Hugo project, this should be configured to upload your compiled HTML site to your hosting provider of choice. Here’s a redacted version of mine as an example:

stages:
  - build_html
  - deploy_html

variables:
  AWS_DEFAULT_REGION: ap-southeast-2
  BUCKET_NAME: example.com
  CLOUDFRONT_DIST_ID: XXXXXXXXXXXXXX
  GIT_SUBMODULE_STRATEGY: recursive

buildHugoSite:
  image: monachus/hugo
  stage: build_html
  script:
    - hugo
  artifacts:
    paths:
      - public
  only:
    - master

deploys3:
  image: garland/aws-cli-docker
  stage: deploy_html
  dependencies:
    - buildHugoSite
  script:
    - aws configure set preview.cloudfront true
    - aws s3 sync ./public s3://$BUCKET_NAME --delete;
    - aws cloudfront create-invalidation --distribution-id $CLOUDFRONT_DIST_ID  --paths "/*";
  only:
    - master

Create an account on your Gopher server that the GitLab Runner can access to upload the gopher files. Make sure it has the right groups to modify the directory where your Gopher files are stored. Also make sure that the Gopher files have permissions set recursively to allow writing by the group (traditionally 775 permissions on a POSIX system).

You’ll need to generate an SSH key and store the public key in the ~/.ssh/authorized_keys file on your Gopher server for the GitLab user account.

Compiling Gopher

Add build_gopher as a stage to .gitlab-ci.yml, then append the following:

buildGopherSite:
  image: node:lts-alpine
  stage: build_gopher
  script:
    - apk update && apk upgrade && apk add --no-cache bash git
    - git clone https://github.com/judges119/hugogopher.git
    - cd hugogopher
    - node index.js '../content'
  artifacts:
    paths:
      - hugogopher/gopher
  only:
    - master

This stage will do the following:

  1. Use a tiny Alpine Linux image with Node.js.
  2. Install bash and git.
  3. Clone the hugogopher repo.
  4. Compile the project as a Gopher site.
  5. Store the compiled files as an artifact.

Uploading Gopher

Copy the contents of the private key you have generated, then go to your project repository on your GitLab instance and click Settings -> CI/CD, then open the Variables section. Create a new variable and call it SSH_PRIVATE_KEY, and set the value to be the contents of the private key. Save the updated variables.

Add a deploy_gopher stage to your .gitlab-ci.yml, then append the following:

deployGopher:
  image: alpine:latest
  stage: deploy_gopher
  dependencies:
    - buildGopherSite
  before_script:
    - apk update && apk upgrade && apk add --no-cache bash openssh-client
    - eval $(ssh-agent -s)
    - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
    - mkdir -p ~/.ssh
    - chmod 700 ~/.ssh
  script:
    - scp -o StrictHostKeyChecking=no -r ./hugogopher/gopher gitlab@example.com:/var/gopher

This stage does the following:

  1. Relies on the previous build_gopher stage (and it’s artifacts).
  2. Uses a minimal Alpine Linux image
  3. Installed bash and an SSH client
  4. Uses ssh-agent to add and manage the private key
  5. Uses scp to transfer the artifact files to the Gopher server

Finishing Off

Commit the updated .gitlab-ci.yml file in your Hugo project and upload it to GitLab and very soon you should have your Gopher site uploaded and running!

If you want, you can check mine out at gopher://gopher.judges119.me:70 or http://gopher.judges119.me:70/.

* Buy my book on GitLab! Available on Packt or on Amazon.