+10
content/posts/2025-12-28-marius-toolbox-issue-1.md
+10
content/posts/2025-12-28-marius-toolbox-issue-1.md
···
1
+
---
2
+
title: "Marius Toolbox - issue #1"
3
+
date: 2025-12-28T11:51:32Z
4
+
description: "An Introduction"
5
+
draft: false
6
+
---
7
+
8
+
*Originally published at [Leaflet](https://toolbox.leaflet.pub/3mb2azrbokk2k)*
9
+
10
+
<div class="postContent flex flex-col"><p><span class=" ">Welcome dear Reader,</span></p><p><span class=" ">I am Marius and I've been a bit obsessed with developer tooling and workflows for a while now. There is a certain feeling that you get from things that work really well and exactly the way you want them to.</span></p><p><span class=" "></span></p><p><span class=" ">I've been working as a Software Engineer & DevOps Engineer (I know I hate that title too) for ~7 years now. I've figured out pretty early on in my career that what interests me the most are all the things around the code, such as production deployments, observability, infrastructure, scaling, databases and development workflows. Especially since these things became more & more codified through Infrastructure as Code and the like.</span></p><p><span class=" "></span></p><p><span class=" ">In this newsletter I'll document my journey of adopting new tools, improving workflows as well as sharing what didn't work for me. How often I am going to publish, how long these articles will be and what I am going to focus on the most, that we'll all figure out together. I don't have clear plan laid out just yet.</span></p><p><span class=" "></span></p><p><span class=" ">Here are some of the tools I am currently using to give you an idea of what might be coming next:</span></p><p><span class=" "></span></p><ul><li class="pb-0! flex flex-row gap-2"><div class="listMarker shrink-0 mx-2 z-1 mt-[14px] h-[5px] w-[5px] rounded-full bg-secondary"></div><div class="flex flex-col"><p><span class=" ">Neovim</span></p></div></li><li class="pb-0! flex flex-row gap-2"><div class="listMarker shrink-0 mx-2 z-1 mt-[14px] h-[5px] w-[5px] rounded-full bg-secondary"></div><div class="flex flex-col"><p><span class=" ">Ghostty</span></p></div></li><li class="pb-0! flex flex-row gap-2"><div class="listMarker shrink-0 mx-2 z-1 mt-[14px] h-[5px] w-[5px] rounded-full bg-secondary"></div><div class="flex flex-col"><p><span class=" ">Tmux</span></p></div></li><li class="pb-0! flex flex-row gap-2"><div class="listMarker shrink-0 mx-2 z-1 mt-[14px] h-[5px] w-[5px] rounded-full bg-secondary"></div><div class="flex flex-col"><p><span class=" ">Lazygit</span></p></div></li><li class="pb-0! flex flex-row gap-2"><div class="listMarker shrink-0 mx-2 z-1 mt-[14px] h-[5px] w-[5px] rounded-full bg-secondary"></div><div class="flex flex-col"><p><span class=" ">Terraform / Opentofu</span></p></div></li><li class="pb-0! flex flex-row gap-2"><div class="listMarker shrink-0 mx-2 z-1 mt-[14px] h-[5px] w-[5px] rounded-full bg-secondary"></div><div class="flex flex-col"><p><span class=" ">Fish (shell)</span></p></div></li><li class="pb-0! flex flex-row gap-2"><div class="listMarker shrink-0 mx-2 z-1 mt-[14px] h-[5px] w-[5px] rounded-full bg-secondary"></div><div class="flex flex-col"><p><span class=" ">Docker / Podman</span></p></div></li><li class="pb-0! flex flex-row gap-2"><div class="listMarker shrink-0 mx-2 z-1 mt-[14px] h-[5px] w-[5px] rounded-full bg-secondary"></div><div class="flex flex-col"><p><span class=" ">kind (kubernetes in docker)</span></p></div></li><li class="pb-0! flex flex-row gap-2"><div class="listMarker shrink-0 mx-2 z-1 mt-[14px] h-[5px] w-[5px] rounded-full bg-secondary"></div><div class="flex flex-col"><p><span class=" ">k9s</span></p></div></li><li class="pb-0! flex flex-row gap-2"><div class="listMarker shrink-0 mx-2 z-1 mt-[14px] h-[5px] w-[5px] rounded-full bg-secondary"></div><div class="flex flex-col"><p><span class=" ">Obsidian (notes)</span></p></div></li><li class="pb-0! flex flex-row gap-2"><div class="listMarker shrink-0 mx-2 z-1 mt-[14px] h-[5px] w-[5px] rounded-full bg-secondary"></div><div class="flex flex-col"><p><span class=" ">Go</span></p></div></li></ul><p><span class=" "></span></p><p><span class=" ">This is not an exhaustive list but I hope it gives you an Idea of the kind of things this newsletter will be all about. You can probably already tell that I am a terminal geek and that's where I plan on staying throughout all of this.</span></p><p><span class=" "></span></p><p><span class=" ">You can also find my current configurations in my </span><a href="https://github.com/mariuskimmina/.dotfiles" class="text-accent-contrast hover:underline " target="_blank">.dotfiles repo</a><span class=" "> - currently only on Github I am considering moving it over to Tangled and keeping Github as a readonly mirror.</span></p><p><span class=" "></span></p><p><span class=" ">Some tools I am particularly excited about exploring at the moment</span></p><p><span class=" "></span></p><ul><li class="pb-0! flex flex-row gap-2"><div class="listMarker shrink-0 mx-2 z-1 mt-[14px] h-[5px] w-[5px] rounded-full bg-secondary"></div><div class="flex flex-col"><p><span class=" ">jj (jujutsu vcs)</span></p></div></li><li class="pb-0! flex flex-row gap-2"><div class="listMarker shrink-0 mx-2 z-1 mt-[14px] h-[5px] w-[5px] rounded-full bg-secondary"></div><div class="flex flex-col"><p><span class=" ">nix / NixOS</span></p></div></li></ul><p><span class=" "></span></p><p><span class=" ">I might also sneak in some less technical articles around how I manage work and personal projects with Obsidian and note taking - if there is interests in this kind of thing too.</span></p><p><span class=" "></span></p><p><span class=" ">I'd be beyond happy to have people reach out with suggestions, you can always message me on BlueSky.</span></p><p><span class=" "></span></p><p><span class=" "></span></p><p><span class=" "></span></p><p><span class=" "></span></p><p><span class=" "></span></p></div>
+10
content/posts/2026-01-02-making-sense-of-nixos-with-nixos-anywhere-issue-2.md
+10
content/posts/2026-01-02-making-sense-of-nixos-with-nixos-anywhere-issue-2.md
···
1
+
---
2
+
title: "Making sense of NixOS with nixos-anywhere - issue #2"
3
+
date: 2026-01-02T17:22:48Z
4
+
description: "Using nix as an IaC tool"
5
+
draft: false
6
+
---
7
+
8
+
*Originally published at [Leaflet](https://toolbox.leaflet.pub/3mbhfupgzu22l)*
9
+
10
+
<div class="postContent flex flex-col"><p><span class=" ">Now, this might just be me, but I was trying to love nix & nixos for a while already but whenever I tired to use for my personal projects or as a operating system for my personal computer but then I always felt like it got in the way at times.</span></p><p><span class=" ">On a personal computer I might spontaneously have to install proprietary software, like zoom, to get my work done and NixOS makes that a pain. I always went back to arch after a while but the thought of it's declarative beauty was still lingering in my mind.</span></p><p><span class=" ">I recently heard more and more people using NixOS for their servers and production workloads and, thinking about it, that makes perfect sense. I will never ever need to install zoom or the like on a server. But I do care a lot about being in control of exactly what is installed on it, especially when running production workloads. Being able to define everything in a declarative configuration and check it into version control.</span></p><p><span class=" ">The problem with that at first seemed to be that most cloud providers simply don't offer NixOS (yet) but that also appears to be a very solvable problem since there is </span><a href="https://github.com/nix-community/nixos-anywhere" class="text-accent-contrast hover:underline " target="_blank">nixos-anywhere</a><span class=" ">. This tool turns any cloud VM into a NixOS machine using </span><code class=" inline-code ">kexec</code><span class=" ">. I tried it today and I am blown away by how well it works.</span></p><p><span class=" ">I have followed the setup of </span><a href="https://github.com/nix-community/nixos-anywhere-examples" class="text-accent-contrast hover:underline " target="_blank">nixos-anywhere-examples</a><span class=" "> and turned a Hetzner Ubuntu machine into NixOS in just a few minutes and a single command</span></p><div class="w-full min-h-[42px] rounded-md border-border-light outline-border-light selected-outline"><pre class="shiki github-light" style="background-color:#fff;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#6F42C1">nix</span><span style="color:#032F62"> run</span><span style="color:#032F62"> nixpkgs#nixos-anywhere</span><span style="color:#005CC5"> --</span><span style="color:#005CC5"> --flake</span><span style="color:#032F62"> .generic</span><span style="color:#005CC5"> --generate-hardware-config</span><span style="color:#032F62"> nixos-generate-config</span><span style="color:#032F62"> ./hardware-configuration.nix</span><span style="color:#032F62"> root@</span><span style="color:#D73A49"><</span><span style="color:#032F62">your-i</span><span style="color:#24292E">p</span><span style="color:#D73A49">></span></span></code></pre></div><p><span class=" ">And now all configuration files for this machine are on my local computer, I can edit them and check them into version control. And when I want to apply a change it's again just one command</span></p><div class="w-full min-h-[42px] rounded-md border-border-light outline-border-light selected-outline"><pre class="shiki github-light" style="background-color:#fff;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#6F42C1">nix</span><span style="color:#032F62"> run</span><span style="color:#032F62"> nixpkgs#nixos-rebuild</span><span style="color:#005CC5"> --</span><span style="color:#032F62"> switch</span><span style="color:#005CC5"> --flake</span><span style="color:#032F62"> .#generic</span><span style="color:#005CC5"> --target-host</span><span style="color:#032F62"> root@</span><span style="color:#D73A49"><</span><span style="color:#032F62">your-i</span><span style="color:#24292E">p</span><span style="color:#D73A49">></span></span></code></pre></div><p><span class=" "></span></p><p><span class=" ">You can find the config here: <br/></span><a href="https://tangled.org/mariuskimmina.com/nix-hetzner-lab" class="text-accent-contrast hover:underline " target="_blank">https://tangled.org/mariuskimmina.com/nix-hetzner-lab</a><span class=" "><br/><br/>For now it's just a minimal edit of the example repo but I have some plans for a project I want to host this way and to see how nix as IaC tool will hold up.</span></p><p><span class=" "></span></p><p><span class=" ">... maybe someday I will also get back to it for my personal computer once again ...</span></p></div>
+7
flake.nix
+7
flake.nix
···
37
37
38
38
installPhase = "true"; # output already in $out
39
39
};
40
+
41
+
sync-leaflet = pkgs.writeShellScriptBin "sync-leaflet" ''
42
+
${pkgs.python3}/bin/python3 ${./scripts/sync_leaflet.py}
43
+
'';
40
44
41
45
in {
42
46
packages = {
43
47
default = site;
44
48
blog = site;
49
+
sync-leaflet = sync-leaflet;
45
50
};
46
51
47
52
devShells.default = pkgs.mkShell {
48
53
buildInputs = with pkgs; [
49
54
hugo
50
55
git
56
+
python3
57
+
sync-leaflet
51
58
];
52
59
53
60
shellHook = ''
+99
scripts/sync_leaflet.py
+99
scripts/sync_leaflet.py
···
1
+
import os
2
+
import urllib.request
3
+
import xml.etree.ElementTree as ET
4
+
from datetime import datetime
5
+
import re
6
+
import json
7
+
8
+
# Configuration
9
+
RSS_URL = "https://toolbox.leaflet.pub/rss"
10
+
POSTS_DIR = "content/posts"
11
+
12
+
def slugify(text):
13
+
text = text.lower()
14
+
text = re.sub(r'[^a-z0-9]+', '-', text)
15
+
return text.strip('-')
16
+
17
+
def sync():
18
+
if not os.path.exists(POSTS_DIR):
19
+
os.makedirs(POSTS_DIR)
20
+
21
+
print(f"Fetching RSS feed from {RSS_URL}...")
22
+
try:
23
+
with urllib.request.urlopen(RSS_URL) as response:
24
+
rss_data = response.read()
25
+
except Exception as e:
26
+
print(f"Error fetching RSS: {e}")
27
+
return
28
+
29
+
try:
30
+
root = ET.fromstring(rss_data)
31
+
except ET.ParseError as e:
32
+
print(f"Error parsing XML: {e}")
33
+
return
34
+
35
+
items = root.findall(".//item")
36
+
37
+
# Namespaces
38
+
ns = {
39
+
'content': 'http://purl.org/rss/1.0/modules/content/',
40
+
'dc': 'http://purl.org/dc/elements/1.1/'
41
+
}
42
+
43
+
for item in items:
44
+
title = item.find("title").text
45
+
link = item.find("link").text
46
+
pub_date_str = item.find("pubDate").text
47
+
description = item.find("description").text if item.find("description") is not None else ""
48
+
49
+
# Extract content:encoded if available
50
+
content_encoded = item.find("content:encoded", ns)
51
+
content = content_encoded.text if content_encoded is not None else description
52
+
53
+
# Parse date
54
+
# Sun, 28 Dec 2025 11:51:32 GMT or similar
55
+
try:
56
+
pub_date = datetime.strptime(pub_date_str, "%a, %d %b %Y %H:%M:%S %Z")
57
+
except ValueError:
58
+
try:
59
+
# Fallback for different formats
60
+
pub_date = datetime.strptime(pub_date_str[:25].strip(), "%a, %d %b %Y %H:%M:%S")
61
+
except ValueError:
62
+
print(f"Could not parse date: {pub_date_str}")
63
+
continue
64
+
65
+
date_iso = pub_date.strftime("%Y-%m-%d")
66
+
slug = slugify(title)
67
+
filename = f"{date_iso}-{slug}.md"
68
+
filepath = os.path.join(POSTS_DIR, filename)
69
+
70
+
if os.path.exists(filepath):
71
+
# print(f"Post already exists: {filename}")
72
+
continue
73
+
74
+
print(f"Creating new post: {filename}")
75
+
76
+
# Hugo front matter (JSON dumped for safety with quotes)
77
+
safe_title = json.dumps(title)
78
+
safe_description = json.json.dumps(description)
79
+
80
+
front_matter = [
81
+
"---",
82
+
f'title: {safe_title}',
83
+
f"date: {pub_date.isoformat()}Z",
84
+
f'description: {safe_description}',
85
+
"draft: false",
86
+
"---",
87
+
"",
88
+
f"*Originally published at [Leaflet]({link})*",
89
+
"",
90
+
content
91
+
]
92
+
93
+
with open(filepath, "w", encoding="utf-8") as f:
94
+
f.write("\n".join(front_matter))
95
+
96
+
print("Sync complete.")
97
+
98
+
if __name__ == "__main__":
99
+
sync()