Making a website: KISS my deployment goodbye

This will be a small post; I just wanted to share a simplification, or rather finding the the essentials.

I used to deploy my Hugo website via a Continuous Integration server. In my case it was just a server I kept around, listening if a job came up, and if so it would build the site and upload it to my server. Wanna see?

image: alpine:latest

  - apk update && apk add openssh openssl rsync git
  - wget
  - tar zxfv hugo_0.31.1_Linux-64bit.tar.gz hugo && cp ./hugo /usr/bin/hugo
  - hugo version
  - eval $(ssh-agent -s)
  - echo "$SSH_PRIVATE_KEY" | ssh-add -
  - mkdir -p ~/.ssh
  - '[[ -f /.dockerenv ]] && echo "$SSH_HOST_KEY" > ~/.ssh/known_hosts'

  - git clone themes/heather-hugo
  - hugo --theme=heather-hugo --templateMetrics
  - rsync -uavh --delete -e ssh public/ $HOST_USER@$HOST:$HOST_DIR
    - public
  - master

This is a standard .gitlab-ci.yml, and my workflow was amazing! I’d write something, commit it to git, and push to the remote origin, and then all this stuff would happen. What happened?

  • image: alpine:latest - download a small, but entire OS, to build my site
  • before_script: - gotta do the things, such as update the OS image, install required packages, get the copy of Hugo I want, and then do some insane Docker stuff to get my private key loaded so it could rsync correctly…
  • deploy: - clone the theme, build the thing, upload it, make some copies available…?

So, what did I do all that? Easy answer: I could. I needed to know how CI works, and I know a lot about it.

I also learned about, which is a tiny, mostly text site. So I knocked 20 lines off my

rsync -uavh public/

Aaaaaaaah. Doesn’t that feel better?!

But @maiki, what about automation? What about out-of-site, out-of-mind?

Damn it all, ne? What good is all that complexity, when this works, is as fast as a human needs to be, and can be shared over SMS (I would never, but still!)?

You may have noticed (ha!) that loads some links on the front page:

Yep, those are talkgroup posts! Since I am updating here, I just wanted to give folks an easy way to find where I’m talkin’ and groupin’.

Still Hugo, and just a tiny partial (maikitalk.html):

{{ $url := getJSON "" }}
{{ range first 7 $url.topic_list.topics }}
        <a href="{{.slug}}/{{.id}}?u=maiki">{{ with .featured_link}}Link: {{end}}{{ .title }}</a>
{{ end }}

Yeah, I know, you could be doing this, too! :slight_smile:

Looks even better in lynx!

Though I wonder if I could do something to make it more helpful. Maybe a title or something.


Some would say h1 tag is in order!


Okay, better:

Eventually I’ll get past the ranty part of this and actual show what I am building. :slight_smile:

I needed to share a screenshot, but didn’t have a readily available way to do so. I actually uploaded it to Mozilla, as part of their temporary hosted screenshot service built into Firefox. It works fine, but ugh. Am I really gonna do that, send folks elsewhere to see a thing?

Well because I only upload things that have changed, it is actually really easy to share files through my website!

I could drop files in my public directory, since that is the rsync target. But I like to keep everything orderly, and also I’m gonna delete files as well, and it is “source”, so I put them instead into static. That directory gets carried over to the root of the base URL for the site, so if I drop blackmail-example.gif in hugo-project/static/, it will render at :slight_smile:

I don’t do anything special with directories, so everything is default, including cachedir, which for my system goes to /tmp/hugo_cache.

Turns out there really isn’t much of a way to clear out /tmp, and all systems do it differently, mostly on reboot. Some folks load tmpfs and write directly to RAM, but that ain’t my problem.

How do I kinda update stuff, but in a slow manner. I don’t need the latest and greatest, I just need something that goes with the human mind, enough to say, “hey, see, I update the site, this is probably relevant”, without saying, “you should refresh the page every 30 seconds, we’re doing it live!”

The KISS in the title probably stands for keep it simple silly. So I did.

I use tmpwatch, a program written specifically to discretely delete caches. I added a line to my, bring it to 3:

tmpwatch -m -v 24 /tmp/hugo_cache/
rsync -uavh public/

By default tmpwatch uses atime, or access time, which doesn’t work in my case. I use -m, --mtime:

Make  the  decision  about  deleting  a file based on the file's mtime (modification time) instead of the atime.

This makes sense, since I just want a daily update for any data feeds I have, but no more often than that.

My deployment has changed slightly, with the inclusion of module mounts in hugo.

I haven’t put it in a script yet, but basically we go from the old method:

tmpwatch -m -v 24 /tmp/hugo_cache/
rsync -uavh public/

to just using build and rsync by themselves:

rsync -uavh public/

But here’s the really neat thing: I’ve modularized the site into different repos and mount them into place. Currently I’m only creating a single page in a single section, for Q: The Q.

From interi/web-build: Build and deploy the website at - config/_default/config.yaml at master - web-build -

    - path: ""
      disabled: false
    - path: ""
      disabled: false
      - source: "."
        target: "layouts"
    - path: ""
      disabled: false
      - source: "."
        target: "content/qtq"

I just tried out the magic, and it works!

Basically, in order to deploy the site one requires go, git and hugo installed. If that’s true, then to build the site, ready for deployment:

  1. git clone and enter the directory;
  2. hugo mod init
  3. hugo

That will import and mount all the theming and content, and generate the site.

Why would I do it this way? You’ll see. :slight_smile: