Welcome to my blog

Sometimes, I feel the need to write, and this is a place where I can share what I write with others. I hope you find something interesting here. To learn more about me, you can visit the about page, or perhaps you want to take a look at my projects.

No-ops linux part 3: It puts the data in the pond. Nightly.

This post is part of the series on no-ops linux deployment. The first post covered local development of linux server configuration and essential configuration. The previous installment covers a janky podman installation and configures a reverse proxy to send traffic to a simple container deployment. This is the final post. It covers a more challenging deployment with jobs and rolling restarts, and discusses the strengths and weaknesses of this approach to hosting. After the previous post, we know how to deploy a container that requires absolutely no configuration and restarts almost instantly. Most of the applications I work on in my daytime job aren’t like that. Let’s take a look at a more complex example. ...

May 14, 2025 · 22 min · 4516 words · Robin Kåveland

No-ops linux part 2: Hosting a simple container on a lean mean systemd machine

This post is part of the series on no-ops linux deployment. The previous post covered local development of linux server configuration and essential configuration. This installment covers a janky podman installation and configures a reverse proxy to send traffic to a simple container deployment. The final post covers a more challenging deployment with jobs and rolling restarts, and discusses the strengths and weaknesses of this approach to hosting. At the completion of the previous post, we had automatic installation of a functional Ubuntu server with the bare essentials installed. We did this by writing a base-install ansible role. There’s still a missing ingredient before we can start deploying containers, though! ...

May 14, 2025 · 15 min · 3112 words · Robin Kåveland

No-ops Linux part 1: Automation, security and essentials

In Running containers on no-ops linux in 2025 I wrote about moving my hobby projects to a European cloud provider. I did an initial, manual setup in Hetzner, which I’ve now automated. This weekend, I tested the setup. It takes me a few minutes now to get everything moved to a new host, and most of that has to do with DNS. I’ve got a reproducible setup, I can quickly provision up a machine locally or in any cloud that has Ubuntu 24.04. Reproducible infrastructure is ✨liberating✨ ...

May 13, 2025 · 12 min · 2444 words · Robin Kåveland

To create, or be consumed? That is the question

This is a note to myself about how to prioritize wisely. Or perhaps, it is an effort to commit to text a healthy mindset for myself. I have been trying to get into this mindset over a timeframe of some years now. I am making some progress, but it’s slow and not without setbacks. You can read it if you’d like, but this is my own advice for me. It may not apply to you. ...

May 6, 2025 · 8 min · 1536 words · Robin Kåveland

That join sure is a natural

Working with SQL can sometimes be painful, especially when you have composite keys and many tables to join. Today I want to write a helpful tip for designing data models with such keys, to make it less painful to handwrite SQL for them. TIP: Introduce a consistent naming standard for all columns that take part in a primary key, so that the column has the same name in all tables it is used, also where it’s on the referencing side of a foreign key. ...

April 30, 2025 · 4 min · 823 words · Robin Kåveland

It's okay to have no idea what you're doing and try anyway

When I was a kid, I thought adults knew everything there was to know. When I was a junior developer, I thought the senior developers knew everything there was to know about software. As anyone who has made some progression in life knows, nobody gives you the big manual with all the answers when you level up. You’ll still be you. Just with more responsibility and more experience. But the experience does not come from age, it comes from actually having to try. It’s okay to have no idea what you’re doing and try anyway. It will make you better. ...

April 26, 2025 · 4 min · 832 words · Robin Kåveland

Deploying to BunnyCDN and protecting Norway from drop bears

Not long ago, I wrote about running containers as part of moving my hobby projects to European cloud providers. That post was focused on running good old Linux servers. I briefly mentioned BunnyCDN but didn’t dive into the details. It’s time to dive into the details! What the flark is a CDN? A content delivery network is a geographically distributed network of servers that can deliver content to your users, close to where they are. It’s useful, because the speed of light isn’t fast enough to make pages load quickly across the other side of the globe. Seriously, the fastest thing in the universe cannot deliver cat pictures to people quickly enough. By using a CDN, you can geographically distribute assets like cat pictures, HTML, CSS, JavaScript, video files, fonts and much more. ...

April 20, 2025 · 8 min · 1609 words · Robin Kåveland

Checking SQL migrations with eugene

It’s been almost a year since I last posted an update on eugene, the CLI tool I’m building to help people write safer SQL migration scripts for postgres. I announced this tool in Careful with That Lock, Eugene: Part 2. At the time, eugene would execute a single SQL script, recording all the locks acquired and warn about possible downtime due to migrations. It could produce JSON suitable for automated tooling and Markdown suitable for human reading and using in CI comments/checks. That version was already good enough for me to start using in real projects — but it’s improved a lot since then, it’s now easy to run with almost no setup. ...

April 16, 2025 · 4 min · 658 words · Robin Kåveland

Running containers on no-ops linux in 2025

Back in February, I decided that I wanted to move hosting of my hobby projects to a european cloud provider. At this time, I don’t feel like spending more energy on why, but maybe someone can learn something from the how. I have pretty simple requirements, so I figured I should be able to find simple and inexpensive hosting too. It turns out that there are many european cloud providers in 2025, but none that were really a perfect fit for what I was looking for. Here’s what I wanted: ...

April 14, 2025 · 8 min · 1679 words · Robin Kåveland

Finding foreign keys missing indexes

Last week I was made aware that we had some foreign keys not backed by indexes in the system we’re developing at work. Foreign keys in postgres must be backed by an index only on the side they refer to, not necessarily the side they refer from. Here’s an example: create table author( id bigint generated always as identity primary key, name text not null ); create table book( id bigint generated always as identity primary key, author bigint not null references author(id), title text not null ); In this example, there’s a foreign key from the book table to the author table. Since author refers to a primary key in the author table, inserts into book can validate very quickly. There’s no index on the author column in the book table though. The consequence of this is that delete on author must check every single row in book to check if it’s safe to actually delete. The really annoying part of this is that the scan does not show up in query plans: ...

April 4, 2025 · 7 min · 1468 words · Robin Kåveland