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

before_script:
  - apk update && apk add openssh openssl rsync git
  - wget https://github.com/gohugoio/hugo/releases/download/v0.31.1/hugo_0.31.1_Linux-64bit.tar.gz
  - 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'

deploy:
  script:
  - git clone https://allthe.codes/maiki/heather-hugo.git themes/heather-hugo
  - hugo --theme=heather-hugo --templateMetrics
  - rsync -uavh --delete -e ssh public/ $HOST_USER@$HOST:$HOST_DIR
  artifacts:
    paths:
    - public
  only:
  - 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 interi.org, which is a tiny, mostly text site. So I knocked 20 lines off my build.sh:

hugo
rsync -uavh public/ interi:interi.org/

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 interi.org 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 "http://archive.v1.talkgroup.xyz/topics/created-by/maiki.json" }}
<ul>
{{ range first 7 $url.topic_list.topics }}
<li>
        <a href="http://archive.v1.talkgroup.xyz/t/{{.slug}}/{{.id}}?u=maiki">{{ with .featured_link}}Link: {{end}}{{ .title }}</a>
</li>
{{ end }}
</ul>

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.

2 Likes

Some would say h1 tag is in order!

2 Likes

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 example.org/blackmail-example.gif. :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 build.sh, bring it to 3:

tmpwatch -m -v 24 /tmp/hugo_cache/
hugo
rsync -uavh public/ interi:interi.org/

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/
hugo
rsync -uavh public/ interi:interi.org/

to just using build and rsync by themselves:

hugo
rsync -uavh public/ interi:interi.org/

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 https://interi.org. - config/_default/config.yaml at master - web-build - allthe.codes

module:
  imports:
    - path: "allthe.codes/tule/tule"
      disabled: false
    - path: "allthe.codes/interi/web-layouts"
      disabled: false
      mounts:
      - source: "."
        target: "layouts"
    - path: "allthe.codes/interi/qtq"
      disabled: false
      mounts:
      - 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 https://allthe.codes/interi/web-build.git and enter the directory;
  2. hugo mod init interi.org
  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: