I don't program in ruby. I do reluctantly use it as a tool for a few things (Mostly jekyll static site generation and apt-listbugs) but when I compare something to nodejs and nodejs wins something is very very wrong.

Gem

Nodejs is another one of those things I try to avoid programming with, and npm is my go-to example for how not to do dependency management (How long did it take to get a lockfile again? 6 years?) Unfortunately, npm is miles beyond the nightmare spawn ruby comes equipped with.

When you default to installing dependencies in root owned system folders, and have to install different versions of each dependency for each version of ruby, you have a fucking nightmare on your hands.

It's like someone looked at the worst dependency managers, the worst parts of compiled languages, and the worst possible place to put them on the filesystem, and decided to see how long it would take for people to realize it was an april fools day joke. No-one caught on.

Bundler

Now supposedly bundler is supposed to fix this by installing dependencies in the project folder like we learned from recent programming developments like ANSI C (1989) – In fact that's even what they say on their website:

Bundler is an exit from dependency hell

And yet, bundler makes things worse. Trying to install jekyll with bundler gives me a nice 403 error from one of the dependency urls. What causes it? Cosmic radiation for all I know!

Gem::RemoteFetcher::FetchError bad response Forbidden 403

But if you want to use the dependencies in the project folder you have to prefix your commands with bundle exec and if bundler doesn't like your dependencies it will complain on start.

So it's not like there is any way of even getting my local files into a state where they will reliably run jekyll, since every time I try to run it bundler goes out and finds something new on the internet to break my build with.

Now you (presumably being a ruby dev led here by an angry mob) may know exactly what's going on but I sure as shit don't want to dig through 15 levels of arcane documentation and sacrifice a chicken to Nyarlathotep every time I try to build a local site.

And no, I'm not putting ruby specific environment variables in my bashrc. It doesn't deserve a single line in there.

Docker

So I finally had an example of something to use my fresh docker knowledge on. If I use a version of jekyll from a docker image I can actually build my site.

The command goes from bundle install to docker run -v "$(pwd):/srv/jekyll:Z" -it jekyll/jekyll:3.8 bundle install and that's a bit of a mouthful. (And jekyll serve is even worse)

Using docker-compose you can even boil the lengthy command down to a slightly lengthy command, a config file, and baseless trust in the security of someone else's docker image!

services:
  serve:
    image: bretfisher/jekyll-serve
    volumes:
      - .:/site
    ports:
      - '4000:4000'
    profiles: ["serve"]
  build:
    image: bretfisher/jekyll-serve
    volumes:
      - .:/site
    command: ["bundle", "exec", "jekyll", "build"]
    profiles: ["build"]
    environment:
      JEKYLL_ENV: production
$ docker-compose up build
Starting example_build_1 ... done
Attaching to example_build_1

Well that's all pretty bad but at least it works. Or rather, it used to work… Today bundler won't install in docker either:

Temporary failure in name resolution

But the temporary failure is persistent, and searching for the error led me to believe it has something to do with IPv6 DNS.

Fucking with network settings eventually lead to a cleaner error message:

Could not reach host index.rubygems.org. Check your network connection and try again.

Well fuck. Here I am messing with IPv6 settings to run a program I ostensibly already installed (Oh wait it's in a different ruby version's gem folder silly me) and I finally figured out I have to explicitly create a network for my docker container and disable ipv6 in it for it to work…

services:
  serve:
    ...
    networks: [n]
  build:
    ...
    networks: [n]

networks:
  n:
    driver: bridge
    enable_ipv6: false

Hugo

I remember years ago looking at hugo and thinking "Huh, this looks better than jekyll. Too bad github pages only support jekyll so it'll never take off". I wasn't even thinking of dependency issues at the time, because it was somehow easy to run jekyll at the time (In other words it's gotten worse since then)

Well at some point the addition of github actions made that distinction moot and now hugo is the most popular static site generator in the world. I'm sure the fact that it's a statically compiled binary that just works has nothing to do with it.

/rant