Removing CI from my website project and going bare-bones
This day marks the day that I decided to free myself of the chains of continuous integration for building my static site. For the longest time I found CI services to be of great convenience for me when publishing a static website like this one, but I've decided to remove CI from my publishing altogether for a couple of reasons.
This post will explain my reasoning, and the process I went through before settling down on my current setup.
It all started once upon a time when Drew DeVault, owner of SourceHut wrote a post about how cryptocurrency is a terrible thing in the world. This comes after a series of blog posts about how cryptocurrency farmers are eating away at all the free services on the internet, and trying their hardest to come up with ways to infect other peoples' computers to do cryptohashing for them so they earn a profit.
My website, which originally ran off GitLab CI, used the automated pipelines to "deploy" my website. In reality all it did was use Docker and run some Racket scripts. I think it best for me to take myself off automated deployment builds like this and go back to the good old days of building things myself and pushing it through Git commits. That seems much nicer and better for the world.
But while I'm at it, I've been meaning to ditch my old Racket code and maybe try experimenting with new systems, so let's find a suitable replacement.
Previously, I had written my own Racket website publishing system. It was convoluted, messy, wasn't very standard, and it was sloppy in so many places I deemed it almost unfixable at times. I didn't create any kind of API docs in mind when building it, everything was thrown together. Truly it was a mess. But it was neat and customizable.
; It's pretty cool being able to turn S-exrpessions
; into full web-pages like this
(define (xexpr->file xexpr-t fname)
(define fpath (string->path fname))
(define-values (dir fp _) (split-path fpath))
(unless (directory-exists? dir) (make-directory* dir))
(call-with-output-file fpath #:exists 'replace
(parameterize ([current-output-port output-port])
(when (string=? "html" (last (string-split fname ".")))
(display "<!doctype html>"))
(write-xml/content (xexpr->xml xexpr-t)))))
(vprint (format "Wrote file to '~a'" (path->string fpath))))
I value the Racket language as a toolkit, but it's runtime is massive and memory heavy. It's not a necessarily fast runtime either. When you build with CI, you use Docker to pull in container images of an environment to execute some code inside of. For me, I pulled a container that had Racket, so it was more or less an Alpine Linux plus Racket environment.
However, the Docker image sizes can be massive. Racket is already a whopping 700MB in size, but the Docker image is larger. If the CI system doesn't keep this between builds, it's downloading almost a gigabyte each time.
Either way, I was totally okay with this before, but now I am not. I want to keep my environment small and minimal as possible, so I wanted to look at all the possibilities available.
In brief, here's my run-down of a few:
stack for whatever reason, too large
Zola hits the right areas because it does what I want, is very compact, and does what I need it to. Comes with SASS, image processing, a bunch of other features, shortcode macros, and I could contribute back to it since it is written in Rust (as other languages are rather foreign to me, I am less likely to do so).
A Zola project site is pretty minimal and easy to maintain. The main content sits in an aptly-named folder
content at the root of the project. Then there's a few supplemental folders and files.
➜ sleibrock.github.io git:(main) ✗ tree
│ └── blog
│ ├── _index.md
│ └── 2021-08-03-no-ci
│ ├── index.md
│ └── racket_is_fat.png
│ └── home.scss
│ └── <bunch of random favicon/web stuff>
│ ├── base.html
│ ├── blog.html
│ ├── blog-page.html
│ └── index.html
This is how I currently have my blog set up. I decided on this approach because I felt it was a bit more organized. Initially before all of this, I was using raw semi-Markdown files to write my posts; in reality they were actually Racket code scripts.
The Racket code I was using would be able to link to images wherever I want, but I do not have that luxury with Markdown in Zola. Files must be either be fully typed out, or linked relative to the directory.
# Which of these is more convenient for writing?
My issue was that I wanted to store images for use in my blog posts, but I didn't want to litter my directory with my Markdown files. So instead I would rather create a folder like
images/ and dump everything in there. But over time, that can be a bad idea, because the
images/ folder would start to look like a dumpster, and you wouldn't be able to tell what image is used where without proper naming schemes. And personally I don't want to have to apply naming conventions to my images in every post.
Instead what you should probably do, is create folders instead and create sub-files inside that to represent blog posts. Create a new folder, like
2021-08-03-no-ci using a rather typical naming format. Then create an
index.md inside of that to act as the index page for that directory. Afterwards, you can lump all your image assets into that folder, and then they're all relative to the HTML page and won't litter your directories.
I can't stress how neat it is to finally have a site generator that supports SASS. I'm not a SASS power-user at all. In fact I started briefing myself on it with W3Schools' section. But let me tell you: storing colors in variables is a lifesaver that I wish CSS had normally. Even if all it does is basic text replacement for me to pop in colors attached to variable names, I'll take that over normal CSS any day of the week.
A lot of minimalist sites often stick to 3 or 4 color palettes. It's pretty easy to create a palette using basic tools, but it's much harder to manage those and change them later on when the color codes have been used dozens of times in (possibly multiple) sheets.
SASS adds inheritance and imports to CSS, which is a pretty neat feature to have. Granted this would never work in normal CSS, but as a pre-processor it's a great feature to have to build fleshed-out websites without pulling your hair out over declarative rules. And if you're a theme developer for Zola, I can only imagine SASS will save you and your future editors so much pain and toil.
I described earlier how Racket is fat. Racket isn't just fat, it's also pretty slow in comparison. It needs to start up a runtime environment based off Chez Scheme and import additonal Racket bindings and macros. Then after that you can run your programs. Let's do some comparisons of timings and sizes.
I don't plan on using Docker peronsally for Zola, but that is always an option. Below I pulled fresh images of
racket/racket. We already know Racket's size from before, but let's compare it against Zola.
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
j1mc/docker-zola latest da31b5cb2e78 2 weeks ago 32.6MB
racket/racket latest 761b81b2fdfe 2 weeks ago 932MB
Zola is one thirtieth of Racket's size. CI builds would finish way sooner with that kind of image size.
I have old code that built my site. Granted it has a few more pages and code, but let's see using
(oldsite) $ time make
racket Builder2.rkt build --prod
Running all actions
make 0.87s user 0.09s system 99% cpu 0.955 total
(newsite) $ zola build
> Successfully checked 0 internal link(s) with anchors.
-> Creating 1 pages (0 orphan), 1 sections, and processing 0 images
Done in 41ms.
zola build 0.03s user 0.01s system 101% cpu 0.047 total
Pretty impressive. Granted it's only one page I'm building versus a handful of pages on my old site, but the difference in time is pretty large already. My code doesn't even have any of the features Zola brings in.
Granted none of this should be a surprise. I'm comparing a VM-based language to that of a language that compiles to binary executables. But overall I have been enjoying my time with Zola in this transitioning stage.
I plan on doing more writing pieces, but I also want to expand and develop a new art portfolio. That being said, I also want to create what is known as "photo essay" pieces, where story-telling is combined with photography. There's many features to Zola and I think it can help me accomplish many of these goals (and if not, hello Python scripting!).
For now I have some minor goals I would like to accomplish:
For now, I am going to get this up and running, and this will be the first blog post on my new Zola-based website.