This post is mostly a note for myself, but maybe it can be of use for others. I just need to write this down before I forget and spend time relearning it over and over. This is how I set up new self-hosted applications on my home server. The gist of it is per-app Linux users with user level Systemd services that run containerized apps. This guide presupposes that you have an Ubuntu Server or…
The past year Shai-Hulud et al have wreaked havoc on NPM, PyPI, and other package ecosystems. I have traditionally developed my hobby projects under my own user, managing tooling with asdf or mise , but this has now become untenable. A compromise in a single one of the countless dependency packages would allow access to my full home environment. To help put my mind at least somewhat at ease, I've…
I hate that so many car repair instructions are hidden in closed forums or lost in the memory hole that is YouTube, so here's some notes on repairs we recently did ourselves on our 2021 Volkswagen ID.4. You are responsible for working on your own car! These instructions worked for us, but may not work for you. You might break something and cause more damage than you started with! Replacing the…
Christmas Eve, 2012. When you came to us, I was mildly interested. I wouldn't say dis interested, but I was never a dog person. Now that you're gone, it feels like everything else has lost meaning. The way you showed your love and enthusiasm towards us and all things around you every day was unrelenting. I really needed that this past year, and I'm not sure how I'll do without you. Is it better to…
I use my devices in English. This is because lots of apps have only half-implemented, or downright terrible Finnish translations. And yet, I use a Finnish keyboard layout, and Finnish formats for dates, times, numbers, etc. Sometimes this is too much for software engineers to handle, such as in Teams, where the date format was up until recently tied to the used language. Not to mention being…
Disclaimer! This is a rant that contains my strong opinions. So remember: I'm a nobody, and you don't have to listen to me. Open source maintainers have enough on their plate already, and owe nothing to people who aren't paying them any money. Additionally, this post is about SemVer as defined by its specification. If you're not doing SemVer, that's just fine, and this doesn't apply to you. That…
Here's a little JavaScript/TypeScript pop quiz: how can signal in the following code be undefined , leading to a failure when you try to add the event listener? class CancelablePromise<T> extends Promise<T> { constructor( callback: (resolve, reject) => void, signal: AbortSignal ) { super((resolve, reject) => { function cancelHandler(_ev: Event) { reject(new Error("Canceled via signal.", { cause:…
A new blog requires new styles, and the biggest change this time was that I changed the font to New Computer Modern . It might give a jump scare to some ex academic types, but I always liked it personally. Even my crummy university lecture notes seemed something special when typeset with LaTeX. New Computer Modern, being an extension of Computer Modern, contains a lot of stuff though. I converted…
It's somewhat of a rule for me to rewrite my blog in a new blog engine every couple of years. Now it was that time again. Last time it was because I had gotten into Gleam, and of course I need to have my blog in the language I like playing with. While Scriptorium turned out just fine , it didn't turn out awesome and didn't attract much of a following. Which I understand, because it was very…
For the past 4 days — and probably more since I don't have logs beyond that — Facebook has been hitting the /robots.txt of my self-hosted Forgejo instance several times per second. The user-agent is facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php) . I expected the UA header to be nontrustworthy, but all the requests are also coming from Meta's IP address ranges. The…
I got some noise-cancelling headphones last spring — the Sennheiser Momentum 4 to be exact — and while I did do some cursory research into them, it turns out my knowledge was limited and I had some perhaps silly preconceptions. These revelations are based on my pair of Sennheisers, since I don't have any comparison, so it might be that I'm still out of the loop on some things. But here's some…
After making websites for more than 20 years, I still keep finding new HTML elements. <meter> was one that I noticed yesterday, and it turned out handy for my project . The issue was that it looked awful: So 2006, so Web 2.0. Turned out this was due to Tailwind's CSS reset that sets — along with a bunch of other stuff — a border style on the element: border: 0 solid; Turns out doing this…
We recently swapped our biogas powered Volkswagen Golf to a 2021 ID.4, a battery-electric vehicle from the same manufacturer. Imagining the savings of charging at home during times when electricity is cheap, we got a smart charger — a Kotilaturi Buusti Box, which is a rebranded cFos Power Brain Wallbox . It's definitely smart, but also super difficult to configure. Maybe I'll write more about that…
I was notified yesterday that email sending was failing in Code::Stats . The service uses Mailgun 's API via the Bamboo library for this functionality. Reproducing the issue locally, I got the following error: ** (Bamboo.ApiError) {:tls_alert, {:handshake_failure, ~c"TLS client: In state certify at ssl_handshake.erl:2186 generated CLIENT ALERT: Fatal - Handshake Failure {bad_cert,…
I have a pair of Sennheiser Momentum 4 noise canceling headphones. They of course work over Bluetooth, the protocol that has more warts than features. One of these warts is "absolute volume", which purports to tie the volume of the headphones and your source device together in the name of convenience. The problem is that with absolute volume, even the lowest volume setting on my laptop is…
Elixir has a configuration system that supports configuring projects at runtime but also at compile time. This is an issue for programs like Gleam's build tool, which would also need to support that system to configure some dependencies that require compile time configuration. At one point, compile time configuration was all the rage in the Elixir community and it still remains in use in some…
A long time ago, my grandpa gave me his pocket watch. It was passed down in the family to him, then from him to me, and it's one of my most prized possessions. The only thing I knew about it was that it said Zenith on the front, and it had an inscription explaining it was given as a 60th birthday gift to someone in 1939. It runs, but poorly so, having a drift of around 7 minutes per day. Turn up…
In last September, I wrote about my home server being aggressively scraped by AI companies . Turns out that was only the beginning. The Incident I noticed the other day that my Mastodon streaming API sockets weren't connecting. This lead to the UI working slower and refreshing periodically. As explained in the earlier post, I self-host my repositories on my own Forgejo instance on the same server…
I feel so old. This blog is my "new" blog, to replace the old one I wrote as a teenager. And now it's 10 years old . I've been proficient in writing blog engines, this being the fifth iteration: Måsøya, not available anywhere. A frontend-only SPA blog made in JS. This was replaced before the blog was even published. Laine , similar to the former, using KnockoutJS . Mebe , my first Elixir blog…
As Firefish , my fediverse instance software, had gone into maintenance mode and wouldn't be updated in the future, I needed to move off of it. I settled on Mastodon for my new instance. I set up a new account for myself and added the old account as an alias there, which is required to migrate to it. In essence, the new account must pre-approve the migration by adding this alias. This is to…
As I logged in to my fediverse instance running on my home server today, I was thinking it was running strangely slow. Opening htop painted an ugly picture: all the CPU cores were at 100 %. The reason was that my Forgejo instance was being scraped. The instance contains a couple copies of the QMK firmware , because I've made a couple of my own firmwares and the easiest way is to copy the repo and…
We have a battery powered automatic soap dispenser that you can use without touching it. Sure, it's a stupid item that probably shouldn't exist, but since it already exists, it would be reasonable to keep it working as long as possible. The upside is that it stays clean, but the downside is that it eats through batteries like nobody's business. The thing requires 4 AA batteries and, crucially,…
I got a new ISP recently and for the first time ever, a possibility of using IPv6 on a wired home network. IPv6 is still a novel thing in Finland in 2024. I started by dragging my Ubiquiti EdgeRouter X to as close to the present day as possible with the stock firmware, upgrading to 2.0.9-hotfix.7 . Then I wasted a whole evening trying to fiddle with the IPv6 configuration in the config tree. The…
This is a post about how I set up the Valheim dedicated server for socket activation with Systemd, so that it can be started and shut down on demand. This helps it use less resources, keeping the server and the environment happier. If you just want to grab the codes, you might skip directly to the repository , but keep in mind that it requires understanding of Systemd and Linux system…
Using Gleam packages in an Elixir project is not as simple as adding {:lib, "1.2.3"} to your mix.exs , but it's pretty close. There are two issues preventing this simple usage: Elixir's Mix doesn't know how to compile a Gleam package, which does not have any build setup. It's literally a bunch of Erlang files in a folder. I'm not sure if there is an issue about this. Gleam writes dev dependencies…
I've been moving stuff to my new home server and been setting up services with Caddy . It has been a breath of fresh air after my messy Nginx configurations and Let's Encrypt setup. But I found the default logs to contain waaay more information than I needed. So here's a snippet to configure logging to stdout (for Systemd's journald) and remove some extraneous stuff that I don't need to see:…
This week I encountered a post by Matti Vuori on the fediverse, and its 320 by 200 pixel photo with 16 colours intrigued me. I went for a walk with our dog and took a couple of boring snaps to try it out for myself. I first tried the "Posterize" and "Dither" filters in GIMP, and created pretty good images. Being a programmer, I of course wanted to automate it, and using ImageMagick and the WebP…
Here's a short Gleam trick – that I'm actually removing from Scriptorium since it's no longer used there – but that I think deserves a little post anyway. When you call external functions in the JavaScript target, it is likely they might throw an exception. At least much more likely than in the Erlang target, due to the differences in API design and error handling in the languages. A thrown…
I use my bicycles to commute to work year round. The wet, muddy, and slushy seasons really take a toll on the powertrain, and I get tired of the constant need to clean and lubricate the chain. Especially as the oil based lubricants attract grime to the chain. A coworker hinted almost a year ago that he waxes his bike's chain and it has been less work, so I finally decided to try it. Guides said I…
It's a rite of passage for a programmer to write a blog engine. It's lunacy to keep writing blog engines when there was nothing wrong with the previous ones. This blog is now in its fifth incarnation, if I have kept count correctly. Starting in 2015 with a couple of JavaScript based no-backend engines, following up with the Elixir & Phoenix based Mebe, and then with Elixir & Raxx based Mebe 2. Now…
Coordinated Universal Time (UTC) is one of the greatest helps to programmers when dealing with datetime values. UTC makes my life easier, and thus raises my quality of life. Yet, it is plagued by a fallacy that I've seen many times in programmers' discussions online. This is the UTC everywhere fallacy . Even for all the nice things UTC gives us, it just doesn't solve everything. Most developers…
I first came upon Elixir in 2013 (wow, it's been 8 years?). I was looking at Erlang and a friend of mine said that there's this new language being built on the same VM, you should look at it. I gave it a whirl and the rest is history, as they say. I've written it on and off, sadly never professionally, resulting in lots of stuff, some even in production. Elixir gave me a new joy in programming.…
When we recently moved to a new home, I had to get a lawnmower. Having experience with petrol powered ones, I knew I wanted an electric powered mower. It has worked well and I enjoy not having to smell exhaust fumes. But the Makita designers have made an odd design choice. The safety handle that needs to be held for the mower to keep running is just incredibly stiff. When using the mower, my hands…
The grave accent, or more commonly in programmer circles, the backtick . A tiny character with so many uses. With the advent of computers, it has diversified its traditional role as an àccent with new purposes. It marks code in Markdown and Markdown-ish syntaxes. It delimits template literals in JavaScript. It executes code in shells and PHP. And it drives me up the wall. There is nothing wrong…
Five years ago, I was using a web service called Codeivate to track my programming habits. After some on–off, it finally went offline in the spring of 2016. So, during my company's next hacking event, I started a new project to replace the missing service. That project became Code::Stats . Now, five years later, it's still running and I'm still focused on improving it. I'm quite proud of what it…
I've written about Elixir configuration in an earlier post , describing the differences in the configuration styles. If you don't know how Elixir configuration works, I suggest reading it also. In this post, I will demonstrate a system for configuring an Elixir project using the config/runtime.exs system introduced in Elixir 1.11. This system is how I configure my projects, so feel free take it as…
My latest musical find is an Australian sister duo of Mabel and Ivy Windred-Wornes, who play chamber folk, or "haunted folk" as they like to call it. Now a sister duo playing folk songs, where have I heard that before ? This is not to say that they are a dime a dozen, but rather that they share qualities with First Aid Kit, who I also love: beautiful harmonies, performing talent, and versatile…
Last week I got a very curious email in my inbox. It supposedly came from Microsoft and was a report about Code::Stats 's compatibility on Edge and what modern browsers it suggests as a replacement for Internet Explorer. I will quote the key parts: We are reaching out to you on the behalf of the Microsoft browser team. […] We were doing compatibility testing on Internet Explorer and noticed that…
After setting up AhlCode and figuring out the taxing and accounting, I'm able to start selling Code::Stats stickers again. Read on to find out the specs! I have ordered two rolls of stickers from Stickermule that proudly carry the C::S logo. These are perfect for your laptop, desktop tower, bicycle, or whatever you want to add some geek factor to! They are durable, weatherproof, and dishwasher…
On the 11th of May I set up a sole proprietorship with the name AhlCode . It is meant to legitimise and properly handle any income coming from my side businesses. The main aim at this point is to get some money back to compensate the server costs of things I host. But I wouldn't complain if it resulted in some little profit also. Code::Stats is a passion project of mine that I run for free for…
Configuring Elixir applications is a common problem point for new developers and I've seen many questions about it in the community chats. So I thought to write down my knowledge in case it helps anyone. tl;dr for those on Elixir v1.11: Use config/runtime.exs for your configuration needs. Read on for more details / nuance. UPDATED 6th Oct 2020 : Elixir 1.11 was released and the post has been…
This morning I was contacted by a Code::Stats user from China in our Gitter channel, asking if the website was down. Of course I quickly checked and it was not. Turns out Code::Stats is now blocked by the Great Firewall of China , and so are my other sites, like this blog. I don't know how to feel about this. Notorious, maybe? I also don't know what myself or others involved in Code::Stats have…
I've long had certain issues with modern web development, and I even wrote a little tool of my own to help me manage such an environment. So I look for ways to minimise the complexity of my setups while still maintaining some modern conveniences. Now I've started to use a setup that relies on TypeScript and modern browsers' builtin features. This is a very minimal setup consisting just of…
After moving Code::Stats to its own server, the old Online.net box this blog was running on was going to waste, and more importantly, wasting my money. So I got a new tiny box from Hetzner and finally got over to dumping the blog on it. But of course I had to use the opportunity to also refactor it a bit… In addition to the bumped deps and overall cleanup in the backend, the frontend has been…
Unicode contains a lot of great and useful things. And as things tend to go, people find creative uses for them. It's currently trendy to use some of Unicode's special characters for "font effects", 𝕝𝕚𝕜𝕖 𝕥𝕙𝕚𝕤 𝕖𝕩𝕒𝕞𝕡𝕝𝕖 (assuming you have good font support, you should see cool double struck letters reading "like this example"). There are easy converters available for finding out the…
I was doing some Node.js V8 profiling work at the office near the end of the day and noticed my profile processing was taking a long time. I figured it is just processor intensive and left it running for the day while I went home. To my surprise, the next day it was still running! htop showed me it had accumulated 12 hours of CPU time and was still not finished. This led me to track down a related…