<?xml version="1.0" encoding="UTF-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:base="/feed.atom" xml:lang="en-GB"><title>Andreas Voss</title><id>https://anvo.dk</id><link href="https://anvo.dk/feed.atom" rel="self"/><link rel="alternate" href="https://anvo.dk/"/><updated>2026-03-30T08:37:00+0000</updated><author><name>Andreas Voss</name><email>andreas@anvo.dk</email><uri>https://anvo.dk</uri></author><entry><title>I've Decided to Stop Trusting Big Tech With My Data</title><link rel="alternate" type="text/html" href="https://anvo.dk/blog/i-have-decided-to-stop-trusting-big-tech-with-my-data"/><id>https://anvo.dk/blog/i-have-decided-to-stop-trusting-big-tech-with-my-data</id><published>2026-03-30T08:37:00+0000</published><updated>2026-03-30T08:37:00+0000</updated><summary>Alright. In hindsight I might've been a bit too optimistic committing to publishing a post every few weeks. How long has it been at this point? Five months. Time really does fly by, but better late than never I suppose. I really want to write quality posts for you, but that takes time, effort, and the right motivation. I finally found all three and here I am again, writing about something as interesting as backups. No, please don't leave. I swear it'll be good!
</summary><content type="html">&lt;![CDATA[&lt;p&gt;
Alright. In hindsight I might’ve been a bit too optimistic committing to publishing a post every few weeks. How long has it been at this point? Five months. Time really does fly by, but better late than never I suppose. I really want to write quality posts for you, but that takes time, effort, and the right motivation. I finally found all three and here I am again, writing about something as interesting as backups. No, please don’t leave. I swear it’ll be good!&lt;/p&gt;
&lt;h2&gt;
Whom would you entrust with your deepest thoughts&lt;/h2&gt;
&lt;p&gt;
For as long as I can remember, I’ve been concerned about privacy. Not for any particular reason, I just believe that it’s a basic right for everyone and the &lt;a class="hover:text-secondary" href="https://fra.europa.eu/en/law-reference/european-convention-human-rights-article-8-0" target="_blank"&gt;European Convention on Human Rights&lt;/a&gt; backs me up (pun intended). Data has become a highly valued commodity used for everything from advertising and training large language models to oppression by nation states. It seems like anyone who can get their hands on my data will try to monetise it or otherwise abuse it.&lt;/p&gt;
&lt;p&gt;
All these seemingly free services I’ve enjoyed for years have notoriously exploited my data to make money. While I acknowledge that I’ve gained some value from these services, &lt;a class="hover:text-secondary" href="https://proton.me/blog/what-is-your-data-worth" target="_blank"&gt;it’s likely that I got the short end of the stick&lt;/a&gt;. Given the current political situation, with wannabe dictators rising to power and corporations finding new ways to monetise my data, I think it’s due time I did something about it, and I’ll start by bringing my data home and hosting it myself.&lt;/p&gt;
&lt;p&gt;
That doesn’t sound too difficult. I’ll just download all my data, delete my accounts, and slam bam, job done. Well, not quite. One thing these cloud services have provided me was the peace of mind that if I were to lose my laptop or phone, the data I care about, such as pictures or source code would not be lost. So I need a way to back up my data without giving large tech companies any control over it. That’s the goal of today’s post.&lt;/p&gt;
&lt;h2&gt;
Narrowing down the options&lt;/h2&gt;
&lt;p&gt;
Before this, I’d never really thought of backing up my data explicitly. I’d used one service for synchronising important files on my desktop, another one for keeping my photo library safe and a third one for hosting source code. I had no control over these services. I didn’t know how they were implemented, and I couldn’t verify that they would actually keep my data safe and private. In order to remedy this, I’ll have to find a backup solution I can trust or verify - preferably both.&lt;/p&gt;
&lt;p&gt;
Since I’m already using Proton for e-mail, I first considered just using Proton Drive which is their cloud storage product. However, a few things deterred me. Mainly the fact that their &lt;a class="hover:text-secondary" href="https://github.com/ProtonDriveApps/sdk/commit/7c75b462a4fe5d8042cb8b4fa3b33cdd06f4533f#diff-b335630551682c19a781afebcf4d07bf978fb1f8ac04c6bf87428ed5106870f5R7" target="_blank"&gt;SDK is not ready for production&lt;/a&gt; and that I couldn’t get the &lt;a class="hover:text-secondary" href="https://rclone.org/protondrive/" target="_blank"&gt;Rclone Proton Drive backend&lt;/a&gt; to work properly, which would be important for  automating the process. The steep price of €10 for 500 GB also didn’t help. Then I started considering what I actually needed:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;
a vendor agnostic solution   &lt;/li&gt;
  &lt;li&gt;
that I can easily automate   &lt;/li&gt;
  &lt;li&gt;
which encrypts my data  &lt;/li&gt;
  &lt;li&gt;
with no proprietary client  &lt;/li&gt;
  &lt;li&gt;
that supports incremental backups  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
With those requirements in mind, I had another look at &lt;a class="hover:text-secondary" href="https://rclone.org/" target="_blank"&gt;Rclone&lt;/a&gt;. It supports lots of providers and protocols, and it even has virtual providers for encryption and compression, which seemed really promising. Unfortunately it’s not designed for backups. While I could probably make it work with a bit of hacking and scripting, I would rather not have a fragile and potentially complicated backup solution to maintain. That meant going back to the drawing board and researching alternatives. I found a few tools that looked promising like &lt;a class="hover:text-secondary" href="https://github.com/rsnapshot/rsnapshot" target="_blank"&gt;rsnapshot&lt;/a&gt; but the one that really caught my eye was the purpose-built and modern backup program &lt;a class="hover:text-secondary" href="https://restic.net" target="_blank"&gt;Restic&lt;/a&gt;. It ticked off all the boxes and is highly configurable while still looking quite simple to use, so I decided to evaluate whether it could work for me.&lt;/p&gt;
&lt;p&gt;
Restic supports a bunch of different storage options including using a local directory. This meant I could play around with it without needing any cloud storage. I’ll go through the process in more detail in the next section. For now, I installed the binary, ran a few commands, and ended up with an encrypted backup stored locally. Being able to create a local backup repository means that even if Restic doesn’t support the storage medium I want, I can just copy the repository anywhere.&lt;/p&gt;
&lt;p&gt;
With that in mind, I proceeded to look at hosting options. I just wanted something cheap, hosted in the EU. It didn’t take long before I stumpled upon &lt;a class="hover:text-secondary" href="https://www.hetzner.com/storage/storage-box/" target="_blank"&gt;Hetzner’s Storage Box&lt;/a&gt;, a simple storage server that supports a few different modes of transfer including SFTP, which provides me with 1 TB for €4 per month - a much better deal than what I would get from Proton. I’m not affiliated with Hetzner, I chose it because it seemed like a decent, cheap option that satisfied my requirements.&lt;/p&gt;
&lt;h2&gt;
Restic in practice&lt;/h2&gt;
&lt;p&gt;
Once the &lt;code class="inline"&gt;restic&lt;/code&gt; binary is installed on the system I want to back up, I can either initialise a new repository or execute commands on an existing one. I’ll go through the entire flow of setting up a new repository for the sake of completeness.&lt;/p&gt;
&lt;p&gt;
Since I’ve decided on using SFTP for my backup I’ll add the public part of my SSH key for authenticating to the server, then initialise my repository. When initialising the repository I’m prompted to enter a password. This password is used to encrypt my data and will be required for any subsequent commands. I need to keep the password safe. If I were to lose it, I wouldn’t be able to access my backup again. Ever.&lt;/p&gt;
&lt;pre&gt;&lt;code class="sh language-sh"&gt;# For an SFTP server - more connectors available here: https://restic.readthedocs.io/en/stable/030_preparing_a_new_repo.html
➜ restic init -r sftp:user@server.com:/backup

# Alternative: for a simple directory repository
➜ restic init -r ~/backup&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
The largest annoyance I found when using Restic, and especially when using a non-local repository, is the fact that I have to provide the repository and password for every single command. Luckily, this can be remedied by setting a few environment variables, and as long as you don’t have a lot of different repositories to manage, this makes everything extremely simple. Since I’m using Nix I’ll use &lt;a class="hover:text-secondary" href="https://github.com/Mic92/sops-nix" target="_blank"&gt;sops-nix&lt;/a&gt; to create two files, one with the repository path and one with the repository password and set the following environment variables.&lt;/p&gt;
&lt;pre&gt;&lt;code class="sh language-sh"&gt;➜ export RESTIC_REPOSITORY_FILE=&amp;#39;/run/secrets/restic-repo&amp;#39;
➜ export RESTIC_PASSWORD_FILE=&amp;#39;/run/secrets/restic-pass&amp;#39;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
Now I can just issue the commands without thinking about the repository or the password. &lt;/p&gt;
&lt;p&gt;
There are other ways to resolve the password including providing Restic with a command it will run instead of asking for the password. It will then use the stdout from that command to authenticate. That means you could get the password straight from your password manager if it has a CLI. I’m using Bitwarden so something like this would resolve the password directly from there&lt;/p&gt;
&lt;pre&gt;&lt;code class="sh language-sh"&gt;➜ export RESTIC_PASSWORD_COMMAND=&amp;#39;bw get password 00000000-0000-0000-0000-000000000000&amp;#39;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
That’s pretty cool.&lt;/p&gt;
&lt;p&gt;
There are a more options for passing the parameters to Restic, so you’re not limited to what I’ve covered. Run &lt;code class="inline"&gt;restic --help&lt;/code&gt; to explore the alternatives.&lt;/p&gt;
&lt;p&gt;
I think that’s enough plumbing for now, let’s start backing something up. One of my most precious directories is &lt;code class="inline"&gt;~/photos&lt;/code&gt;, so let’s back it up.&lt;/p&gt;
&lt;pre&gt;&lt;code class="sh language-sh"&gt;➜ restic backup ~/photos&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
Wait, what? Is it that simple? Yes it is! I now have a snapshot I can view using &lt;code class="inline"&gt;restic snapshots&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class="sh language-sh"&gt;➜ restic snapshots
ID        Time                 Host        Tags        Paths                     Size
------------------------------------------------------------------------------------------
36b31249  2026-03-30 10:17:16  argon                   /home/andreasvoss/photos  4.716 GiB
------------------------------------------------------------------------------------------
1 snapshots&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
In case I were to accidentally delete some files in the &lt;code class="inline"&gt;~/photos&lt;/code&gt; directory, I would be able to recover them from the snapshot using the &lt;code class="inline"&gt;restic restore&lt;/code&gt; command providing it with a snapshot ID along with a target. So let’s delete some files then restore them from the snapshot!&lt;/p&gt;
&lt;pre&gt;&lt;code class="sh language-sh"&gt;➜ ls ~/photos
birthday-party  wildflower-ultra
➜ rm -rf ~/photos/wildflower-ultra
➜ ls ~/photos
birthday-party&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
I’ve deleted one of my valued photo albums, so I really hope restoring it from the snapshot is going to work. In this case I just want to place the files where they were originally, so I’ll give the &lt;code class="inline"&gt;/&lt;/code&gt; directory as my target. Depending on the situation, you might not want to restore in place though.&lt;/p&gt;
&lt;pre&gt;&lt;code class="sh language-sh"&gt;➜ restic restore 36b31249 --target /
➜ ls ~/photos
birthday-party  wildflower-ultra&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
That’s it. Simple. Elegant. I have only just scratched the surface of the possibilities you have when using &lt;code class="inline"&gt;restic&lt;/code&gt;, so I encourage you to dive into &lt;a class="hover:text-secondary" href="https://restic.readthedocs.io/en/stable/010_introduction.html" target="_blank"&gt;their documentation&lt;/a&gt; and give it a whirl. Here are a few commands I’ve found really useful&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;
&lt;code class="inline"&gt;restic diff&lt;/code&gt; - get the difference between two snapshots, useful if you notice a significant change in snapshot size  &lt;/li&gt;
  &lt;li&gt;
&lt;code class="inline"&gt;restic forget&lt;/code&gt; - delete snapshots and can be used to delete snapshots that are older than a specified age  &lt;/li&gt;
  &lt;li&gt;
&lt;code class="inline"&gt;restic check&lt;/code&gt; - check the backup repository for errors to ensure you’ll be able to restore from your snapshots  &lt;/li&gt;
  &lt;li&gt;
&lt;code class="inline"&gt;restic ls&lt;/code&gt; - list the files in the given snapshot  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Now that I’ve set up my backup repository I just need to automate it.&lt;/p&gt;
&lt;h2&gt;
Reducing the cognitive load through automation&lt;/h2&gt;
&lt;p&gt;
Backing up files manually isn’t ideal, and since I’m only human, I might forget. There are a couple of options to choose from when looking to automate the process, mainly using either &lt;code class="inline"&gt;crontab&lt;/code&gt; or &lt;code class="inline"&gt;systemd-timers&lt;/code&gt;. When using Nix, it’s recommended to use &lt;code class="inline"&gt;systemd-timers&lt;/code&gt;, so that’s what I’ll do. I’m pretty sure that most of you won’t be using Nix, so here’s an example you can use without it. It’s not too bad. It’s just a couple of simple unit files and an executable script, let’s walk through it.&lt;/p&gt;
&lt;p&gt;
The &lt;code class="inline"&gt;backup.service&lt;/code&gt; unit file is just a &lt;code class="inline"&gt;oneshot&lt;/code&gt; service that points to the script I’ve made to execute the &lt;code class="inline"&gt;restic backup&lt;/code&gt; command.&lt;/p&gt;
&lt;pre&gt;&lt;code class="unit language-unit"&gt;[Unit]
Description=Backup

[Service]
ExecStart=%h/backup-service/backup.sh
Type=oneshot
User=andreasvoss&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
The &lt;code class="inline"&gt;backup.timer&lt;/code&gt; will start the &lt;code class="inline"&gt;backup.service&lt;/code&gt; on the schedule defined by the &lt;code class="inline"&gt;OnCalendar&lt;/code&gt;. I’m interested in a daily backup, so I’ve set this value to &lt;code class="inline"&gt;daily&lt;/code&gt;. You can make pretty advanced schedules with &lt;code class="inline"&gt;systemd-timers&lt;/code&gt;. In case you need that &lt;a class="hover:text-secondary" href="https://wiki.archlinux.org/title/Systemd/Timers" target="_blank"&gt;the ArchWiki&lt;/a&gt; is a great resource for learning about the options.&lt;/p&gt;
&lt;pre&gt;&lt;code class="unit language-unit"&gt;[Unit]
Description=Backup

[Timer]
OnCalendar=daily
Persistent=true
Unit=backup.service

[Install]
WantedBy=timers.target&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
Finally &lt;code class="inline"&gt;backup.sh&lt;/code&gt; will do the actual work using Restic. There is not much to explain that I haven’t already covered , with the exception of the &lt;code class="inline"&gt;--tag&lt;/code&gt; flag I am passing. I want to be able to differentiate between manual backups and automatic ones, so I’ve added a couple to tags my automatic backups. You can use these tags to filter snapshots when listing them, which is pretty neat.&lt;/p&gt;
&lt;pre&gt;&lt;code class="sh language-sh"&gt;#!/bin/sh

restic backup /home/andreasvoss/photos \
    --tag daily,automatic \
    --repository-file /run/secrets/restic-repo \
    --password-file /run/secrets/restic-pass&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
The files in my example are stored in &lt;code class="inline"&gt;~/backup-service&lt;/code&gt; so I’ll create symbolic links to &lt;code class="inline"&gt;~/.config/systemd/user&lt;/code&gt;, make the script executable then enable and start the timer&lt;/p&gt;
&lt;pre&gt;&lt;code class="sh language-sh"&gt;➜ ln -sf /home/andreasvoss/backup-service/backup.service /home/andreasvoss/.config/systemd/user/backup.service
➜ ln -sf /home/andreasvoss/backup-service/backup.timer /home/andreasvoss/.config/systemd/user/backup.timer

➜ chmod +x /home/andreasvoss/backup-service/backup.sh

➜ systemctl --user daemon-reload
➜ systemctl --user enable backup.timer
➜ systemctl --user start backup.timer&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
There we go, my backup is now automated and my important data is safely stored.&lt;/p&gt;
&lt;h2&gt;
So what’s next?&lt;/h2&gt;
&lt;p&gt;
Now that I know my data is backed up securely at a secondary location, I can think about how to conveniently access my data like I was able to with cloud services I’ve now replaced. I have looked at a couple of really cool projects I want to self-host like &lt;a class="hover:text-secondary" href="https://github.com/immich-app/immich" target="_blank"&gt;Immich&lt;/a&gt;, &lt;a class="hover:text-secondary" href="https://about.gitea.com/" target="_blank"&gt;Gitea&lt;/a&gt; and &lt;a class="hover:text-secondary" href="https://github.com/syncthing/syncthing" target="_blank"&gt;Syncthing&lt;/a&gt;. I’m going to explore these further, so stay tuned for more blog posts once I’ve had time to experiment a bit.&lt;/p&gt;
]]&gt;</content><guid>https://anvo.dk/blog/i-have-decided-to-stop-trusting-big-tech-with-my-data</guid></entry><entry><title>Why in the World Do We Need Another Programming Blog</title><link rel="alternate" type="text/html" href="https://anvo.dk/blog/why-in-the-world-do-we-need-another-programming-blog"/><id>https://anvo.dk/blog/why-in-the-world-do-we-need-another-programming-blog</id><published>2025-10-19T12:00:00+0000</published><updated>2025-10-29T12:00:00+0000</updated><summary>Well, the short answer would probably be that we don't. However, in the era of LLM-slop (you know those uncanny articles 
that look vaguely helpful but somehow says nothing), it's sometimes nice to get the perspective from an actual person. 
I hope I can provide interesting, useful - and occasionally funny - posts about the challenges I face and the 
solutions I find to solve them. This can hopefully help you with whatever you are struggling with, present you something 
worth considering or perhaps just give you a brief smile on your face as I wade through yet another 'great' (read: frustrating)
experience with a Microsoft product 'wink wink'.
</summary><content type="html">&lt;![CDATA[&lt;p&gt;
Well, the short answer would probably be that we don’t. However, in the era of LLM-slop (you know those uncanny articles 
that look vaguely helpful but somehow says nothing), it’s sometimes nice to get the perspective from an actual person. 
I hope I can provide interesting, useful – and occasionally funny – posts about the challenges I face and the 
solutions I find to solve them. This can hopefully help you with whatever you are struggling with, present you something 
worth considering or perhaps just give you a brief smile on your face as I wade through yet another ‘great’ (read: frustrating)
experience with a Microsoft product &lt;em&gt;wink wink&lt;/em&gt;.&lt;/p&gt;
&lt;h2&gt;
Before you expect life-changing productivity tips&lt;/h2&gt;
&lt;p&gt;
First of all I want to say that I don’t believe those even exist. The life-changing productivity tips that is. To truly 
become good at anything even being productive you just need to work hard at it – that might sound boring, but to me it’s 
very rewarding working towards something to eventually get to the place you want to be. Whether it’s a video game, an academic or
physical accomplishments, learning new programming tools or something completely different, the reward for working at 
something just feels amazing. &lt;/p&gt;
&lt;p&gt;
And this blog will definitely not be your “10 productivity tips to boost your performance” kind of place. It’ll be messy,
opinionated, and honest — the way programming tends to be. I might write a guide once in a while, but mostly to be able 
to reproduce something for myself in the future — in case I forget. But hey, if it can help you as well that’d also be
a very nice bonus.&lt;/p&gt;
&lt;p&gt;
Anyway, enough about what this blog isn’t – let me tell you why I decided to start it.&lt;/p&gt;
&lt;h2&gt;
So really, why?&lt;/h2&gt;
&lt;p&gt;
I actually have several reasons for starting this blog. I’ve been thinking about it for a while, and what finally pushed
me to do it was an event about a month ago – when I had to deal with managed certificates for Azure App Services.
I already know what you are thinking: who in their right mind would work with Azure? Honestly, I have no idea -
but that’s where life has taken me for now.&lt;/p&gt;
&lt;p&gt;
Anyway, one of my co-workers and I made a proof of concept in Bicep - some infrastructure as code that would
automatically create a DNS record in a predefined DNS zone, and then request a Microsoft-managed certificate for that
address. It actually went very smoothly. Everything seemed to work perfectly, I was able to get a certificate for
each of our environments for the application we were testing with, and in case we manually removed the certificate in the
portal, we could just run our IaC and it would be fixed. &lt;/p&gt;
&lt;p&gt;
Great, we thought. So I started rolling it out to all our applications on a Friday (I know - offensive to some people).
And then suddenly, my pipeline failed with some obtuse error that I can’t quite remember, but it was something along the
lines of&lt;/p&gt;
&lt;pre&gt;&lt;code class="json language-json"&gt;{
  &amp;quot;code&amp;quot;: &amp;quot;ResourceDeploymentFailure&amp;quot;,
  &amp;quot;details&amp;quot;: [
    {
      &amp;quot;code&amp;quot;: &amp;quot;BadRequest&amp;quot;,
      &amp;quot;message&amp;quot;: &amp;quot;Pending managed certificate failed: Pending certificate expired. Please try again. Refer to the documentation for more info ...&amp;quot;
    }
  ]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
However, the certificate resource just kept spinning in the Azure portal for hours before finally failing to be created
there. Weird.&lt;/p&gt;
&lt;p&gt;
Meanwhile when trying to stop the deployment and create the certificate through the &lt;code class="inline"&gt;az&lt;/code&gt; CLI, we got an entirely
different error about the certificate already existing. Alright I thought, if there is a conflict I might be able to 
fetch it or delete it through the CLI. Once again I was left disappointed with a ‘Not found’ error.&lt;/p&gt;
&lt;pre&gt;&lt;code class="sh language-sh"&gt;# Real parameters anonymized
az webapp config ssl create --hostname sub.webapp-host.com -n webapp-name -g webapp-resource-group 
# Operation returned an invalid status &amp;#39;Conflict&amp;#39;

az webapp config ssl show -g webapp-resource-group --certificate-name sub.webapp-host.com
# Operation returned an invalid status &amp;#39;Not found&amp;#39;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
We spent hours trying to figure out if we’d hit some undocumented limit, or if there were outages at Azure or DigiCert -
the entity that provides the certificates. Nothing.
In desperation, we even asked an LLM for help - only to have it confidently hallucinate a completely imaginary limit of
custom domain certificates for app services (we knew it was imaginary because we can count – and we’d already exceeded that limit).&lt;/p&gt;
&lt;p&gt;
Eventually, we gave up for the day. Luckily it wasn’t critical and could easily wait until Monday. Of course, I couldn’t
wait. I ran the pipeline a few times Friday night, a few more on Saturday, and finally – on Sunday morning – I
saw the green bliss of a pipeline that hadn’t failed. Our solution worked, the one we also thought worked a few days
earlier. Our cloud provider and a chatbot had just successfully convinced us that we were the problem.
That whole ordeal wasted a significant amount of time – and caused more than a little frustration.&lt;/p&gt;
&lt;p&gt;
The episode also made me realise I wanted (or maybe even needed) a place to vent, reflect and maybe laugh about it later – hence, this blog.&lt;/p&gt;
&lt;h2&gt;
A professional procrastinator looking for purpose&lt;/h2&gt;
&lt;p&gt;
A few weeks later, I finally had the time – and excuse – to get started. I had three weeks of vacation without anything particular planned.
I figured it would be nice to work on a project instead of just endlessly procrastinating by scrolling Reddit, or 
watching an absurd number of videos on everything from how a dehumidifier works (in excruciating detail, I might add) to 
urban planning. Since I had just gone through that Azure experience, it was the perfect opportunity to get started on my blog.&lt;/p&gt;
&lt;p&gt;
I didn’t feel like just creating a generic Wordpress site – not that there is anything wrong with that, I’m just a
control-freak. I wanted to build my own site from scratch and preferably learn something along the way. &lt;/p&gt;
&lt;p&gt;
I started looking into &lt;code class="inline"&gt;React&lt;/code&gt; and &lt;code class="inline"&gt;Next.js&lt;/code&gt; for my stack, mostly because I was vaguely familiar with those already. 
But I quickly realised working with those JavaScript frameworks just isn’t fun. There are so many dependencies for even
the simplest things – and the recent supply-chain attack on &lt;code class="inline"&gt;npm&lt;/code&gt; didn’t exactly boost my confidence in that ecosystem. &lt;/p&gt;
&lt;p&gt;
So instead, I started looking for alternatives and soon stumbled upon Elixir and Phoenix. I’d heard really great things 
about Elixir, and getting some more hands-on experience with a functional programming language seemed like a fun
challenge – especially since I’ve barely touched functional programming since coding in &lt;code class="inline"&gt;SML&lt;/code&gt; and &lt;code class="inline"&gt;Scheme&lt;/code&gt; back in university.&lt;/p&gt;
&lt;p&gt;
I started small – solving a few programming exercises to get my hands dirty while going through the &lt;a class="hover:text-secondary" href="https://hexdocs.pm/elixir/1.18.4/introduction.html" target="_blank"&gt;Getting Started section of the Elixir
hexdocs&lt;/a&gt;. The documentation is genuinely excellent, I rarely needed
to look anything up elsewhere.&lt;/p&gt;
&lt;p&gt;
I wrote a few scripts, some modules to play with functions and structs, experimented with maps and collections and the 
Elixir concurrency model. Before long, I found myself remembering both the excitement and confusion of functional 
programming from back in the day – especially when diving back into recursion.&lt;/p&gt;
&lt;p&gt;
After a few days, I’d built up some familiarity with this (to me) new and exciting language, Elixir. I know it
takes a long time to really get good at a new language, but in my opinion, there’s no better way to learn
than by building something real.&lt;/p&gt;
&lt;p&gt;
So I decided to jump into the deep end and try my hand at the Phoenix Framework - a web framework for Elixir. The very 
first thing you’ll see when you go to &lt;a class="hover:text-secondary" href="https://www.phoenixframework.org/" target="_blank"&gt;their website&lt;/a&gt; is a bold tagline promising&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;
Peace of mind from prototype to production  &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;
That’s exactly what I needed – a framework that is stable, opinionated, and fun to build with! A few weeks (and an
undisclosed number of coffees) later, this blog was up and running.&lt;/p&gt;
&lt;p&gt;
I don’t want to go into too much technical detail in this post, since I might write another one about it, but I drew 
a lot of inspiration from &lt;a class="hover:text-secondary" href="http://www.sebastianseilund.com/static-markdown-blog-posts-with-elixir-phoenix" target="_blank"&gt;this post&lt;/a&gt; by 
Sebastian Seilund from 2016. It really helped me kick-start my development and have a solid foundation to keep building
on.&lt;/p&gt;
&lt;p&gt;
Of course, there were other technologies I had to brush up on as well. I really hadn’t touched &lt;code class="inline"&gt;HTML&lt;/code&gt; and &lt;code class="inline"&gt;CSS&lt;/code&gt; in any
meaningful way for years. I’d of course heard of Tailwind, but never actually used it to style anything properly. And
even though I said I don’t really enjoy working with the JavaScript ecosystem, I still ended up installing &lt;code class="inline"&gt;highlight.js&lt;/code&gt; 
through &lt;code class="inline"&gt;npm&lt;/code&gt; in order to have nice looking code blocks in my blog posts  – and some JavaScript will be required if I 
ever want to work with the Phoenix JavaScript interoperability. &lt;/p&gt;
&lt;p&gt;
So, everything isn’t always quite so clean-cut.&lt;/p&gt;
&lt;h2&gt;
Wrapping up (before I break something)&lt;/h2&gt;
&lt;p&gt;
This site is my playground, and from time to time I’ll probably break it (by accident) – but that’s alright. It’ll just
give me something to write about, and let’s be honest, development horror stories are always the most entertaining ones. 
On a serious note, I’ll do my best to post once every couple of weeks for a start, while also continuing to tinker with
and improve the site along the way. I’m not exactly where this little project will go yet, but I’m excited to work on it
nonetheless – and to bring you along for the ride.&lt;/p&gt;
&lt;p&gt;
  &lt;img src="/images/posts/work-work.JPG" alt="Perhaps working on my next post?" title="Perhaps working on my next post?"&gt;
&lt;/p&gt;
&lt;p&gt;
My excursion into Elixir gave me quite a few ideas, and right now I am going through the book ‘Writing An Interpreter In Go’
by Thorsten Ball – except I am not writing it in Go, I am however having a go at implementing it using Elixir (sorry not sorry).&lt;/p&gt;
&lt;p&gt;
Please don’t hesitate to get in touch with me – either in case you want us to work together, or you have a suggestion for
something you’d just love to see me dive into (or just want to say hi), I’d love to hear from you. You can find my contact information &lt;a class="hover:text-secondary" data-phx-link="redirect" data-phx-link-state="push" href="/contact"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;
So, do we really need another programming blog? Probably not. But this one exists – and that’s good enough for me.&lt;/p&gt;
]]&gt;</content><guid>https://anvo.dk/blog/why-in-the-world-do-we-need-another-programming-blog</guid></entry></feed>