Better contact, grammar changes, etc.
This commit is contained in:
@@ -11,9 +11,21 @@
|
||||
|
||||
(setq site-nav
|
||||
"<nav>
|
||||
<a href=\"/\">Home</a>
|
||||
<a href=\"/about.html\">About</a>
|
||||
<a href=\"/blog.html\">Blog</a>
|
||||
<div class=\"nav-links\">
|
||||
<a href=\"/\">Home</a>
|
||||
<a href=\"/about.html\">About</a>
|
||||
<a href=\"/blog.html\">Blog</a>
|
||||
</div>
|
||||
<div class=\"nav-contact\">
|
||||
<a href=\"mailto:aner@zakobar.com\" class=\"contact-link\">
|
||||
<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"2\" y=\"4\" width=\"20\" height=\"16\" rx=\"2\"/><path d=\"m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7\"/></svg>
|
||||
aner@zakobar.com
|
||||
</a>
|
||||
<a href=\"https://www.linkedin.com/in/aner-zakobar/\" class=\"contact-link\" target=\"_blank\" rel=\"noopener\">
|
||||
<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M16 8a6 6 0 0 1 6 6v7h-4v-7a2 2 0 0 0-2-2 2 2 0 0 0-2 2v7h-4v-7a6 6 0 0 1 6-6z\"/><rect x=\"2\" y=\"9\" width=\"4\" height=\"12\"/><circle cx=\"4\" cy=\"4\" r=\"2\"/></svg>
|
||||
linkedin.com/in/aner-zakobar
|
||||
</a>
|
||||
</div>
|
||||
</nav>")
|
||||
|
||||
(defun blog-extract-title (file)
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
#+TITLE: Nix Selfhosting in the Age of LLMs
|
||||
#+DESCRIPTION: About me
|
||||
#+DESCRIPTION: Blog posts about selfhosting with nix and LLMs
|
||||
|
||||
* My usecase
|
||||
* My use case
|
||||
|
||||
I recently had to redo my homelab. Homelab might be a very strong word for what is just a Raspberry Pi 4 8GB hooked up to a 2TB storage drive. Regardless, lately it has been slugging along at unacceptable speeds. I don't know if it was system rot or just a buildup of dust, but my home run services were becoming slow. I wanted to run maintenence on it, but I was sort of afraid to touch anything from what I built.
|
||||
I recently had to redo my homelab. Homelab might be a very strong word for what is just a Raspberry Pi 4 8GB hooked up to a 2TB storage drive. Regardless, lately it has been slugging along at unacceptable speeds. I don't know if it was system rot or just a buildup of dust, but my home run services were becoming slow. I wanted to run maintenance on it, but I was sort of afraid to touch anything from what I built.
|
||||
|
||||
I based all my work on Helm charts to be deployed on Kubernetes (k3s to be exact). I reasoned it was the cutting edge way to self-host, it was highly secure, and that Helm made everything declarative. In the end I found it unwieldy, and the Helm charts weren't as declarative and pure as I would have hoped. The system would still get stuck mid-deployment, previous configuration options wouldn't always go away, services needed to be manually deleted... It always felt like a great beast I was trying to wrestle into submission, which is not how I want to feel about a service backing up pictures of my children.
|
||||
I based all my work on Helm charts to be deployed on Kubernetes (k3s to be exact). I reasoned it was the cutting edge way to self-host, it was highly secure, and that Helm made everything declarative. In the end I found it unwieldy, and the Helm charts weren't as declarative and pure as I would have hoped. The system would still get stuck mid-deployment, previous configuration options wouldn't always go away and services needed to be manually deleted. It always felt like a great beast I was trying to wrestle into submission, which is not how I want to feel about a service backing up pictures of my children.
|
||||
|
||||
* Starting the migration
|
||||
|
||||
It was time for a change. I wanted to restart my homelab and make it something very maintainable. This drove me to use two technologies that were new to me since my last attempt at self hosting:
|
||||
|
||||
- _The NIX ecosystem_: I migrated my own laptop to NixOS over a year ago at this point. I migrated my work setup to Nix and now almost all of my projects use Nix to manage dependencies, builds and deployments. Now, I had an opportunity to manage my homelab using NixOS and declare everything.
|
||||
- _The NIX ecosystem_: I migrated my own laptop to NixOS over a year ago at this point. I migrated my work setup to Nix and now almost all of my projects use Nix to manage dependencies, builds, and deployments. Now, I had an opportunity to manage my homelab using NixOS and declare everything.
|
||||
- _LLMs and Agentic Co-Programming_: A lot of the work I did in the past involved painstaking port definitions and reverse-proxy configurations. There was no reason to think this time would be different in this regard, but knowing I could partially rely on some form of coding agent made the process significantly less daunting.
|
||||
|
||||
* Quick success story
|
||||
@@ -28,17 +28,19 @@ The state of my homelab is set directly from my project. With the exception of s
|
||||
|
||||
** Saving tools and commands
|
||||
|
||||
Something I find myself doing for every one of my Nix projects is declaring a development shell with special commands for tooling. Every time I encounter myself writing long commands to do specific tasks (checking state of backups remotely, remote build and deploy, running commands inside podman hosted services), I just write a custom command that gets loaded into the shell.
|
||||
Something I find myself doing for everyone of my Nix projects is declaring a development shell with special commands for tooling. Every time I encounter myself writing long commands to do specific tasks (checking state of backups remotely, remote build and deploy, running commands inside Podman hosted services), I just write a custom command that gets loaded into the shell.
|
||||
|
||||
In the previous version, this was accomplished by writing a bunch of bash files. This does work and acheives the same basic principle, but this feels more approachable, and the commands feel more accessible. I find myself using this tool much more within the NIX ecosystem.
|
||||
In the previous version, this was accomplished by writing a bunch of bash files. This does work and achieves the same basic principle, but this feels more approachable, and the commands feel more accessible. I find myself using this tool much more within the NIX ecosystem.
|
||||
|
||||
* The extra benefit of the LLM
|
||||
|
||||
Of course using an agentic coding agent helps with selfhosted and automating tasks. This is true also for a kubernetes based helm-charted repo like my previous setup. But there ARE some DEFINITE benefits of using this specific combination.
|
||||
Of course using an agentic coding agent helps with self-hosting related tasks. This is true also for a Kubernetes based helm-charted repo like my previous setup. But there ARE some DEFINITE benefits of using this specific combination.
|
||||
|
||||
For starters, the fact that it is fully declarative means the LLM has direct access to information about the state of the homelab. It doesn't have to hunt around and search for active processes - it knows the file layout and can infer immediately which services are running and how they are configured. Compare this to bloating your context by first reading a bunch of YAML files in the repo and then running a bunch fo commands to make sure everything exists in the repo and making sure it matches the YAML.
|
||||
For starters, the fact that my system is fully declarative means that the LLM knows exactly what is and isn't installed just by looking at the project itself. It doesn't have to hunt around and search for active processes or guess which config file is being read - it knows the file layout and can infer immediately which services are running and how they are configured. Compare this to bloating your context by first reading a bunch of YAML files in the repo and then running a bunch fo commands to make sure everything exists in the repo and making sure it matches the YAML.
|
||||
|
||||
An additional benefit came along with all the custom commands I created for myself - turns out if they're useful for me, they're useful for the LLM! This allows it to perform routine tasks repeatably and correctly, instead of guessing what the best way to do so is. Checking on statuses of backups, for example, can be done in a few ways, but since I already have a command that checks all the relevant services and returns the information together, the LLM doesn't have to guess how to check for my backups - it does so first try every time.
|
||||
An additional benefit came along with all the custom commands I created for myself - turns out if they're useful for me, they're useful for the LLM! This allows it to perform routine tasks repeatably and correctly, instead of guessing what the best way to do so is.
|
||||
|
||||
As an example, I already have a command that does all the work for checking the state of my backups. The command queries relevant services and logs, and summarizes it for me in one output. that checks all the relevant services and returns the information together. The LLM, instead of learning about the structure of the backup service every time, can just run the command and look at the output.
|
||||
|
||||
* Words of caution
|
||||
|
||||
@@ -54,6 +56,6 @@ Even with these gripes - using an LLM saved me loads of time and allowed me to m
|
||||
|
||||
* Conclusion
|
||||
|
||||
This is an ongoing exercise in bad sys-admining - but I am enjoying it very much. Everything so far is running smoothly, and within a short amount of time I surpassed the state my homelab was in - and not once did I have to delete and re-deploy an ingress configuration. I even managed to set up services that I gave up deploying before.
|
||||
This is an ongoing exercise in bad sys-admining - but I am enjoying it very much. Everything so far is running smoothly, and within a short amount of time I surpassed the state my homelab was in - and not once did I have to delete and redeploy an ingress configuration. I even managed to set up services that I gave up deploying before.
|
||||
|
||||
I will keep using this for now. In the end, I don't want to have to rely on the LLM for every task I want to do with my homelab, and over time I am simplifying and restructuring the codebase further to make it easily maintainable by me, a silly old human. But even now it is in a very good state, and I am optimistic about the future of my selfhosted services.
|
||||
I will keep using this for now. In the end, I don't want to have to rely on the LLM for every task I want to do with my homelab. Over time, I will simplify and restructure my codebase further to make it easily maintainable by me, a silly old human. That being said, even now, it is in an excellent state, and I am optimistic about the future of my self-hosted services.
|
||||
|
||||
@@ -7,23 +7,23 @@ I created my first public Emacs package called =evil-hl-line= and it can be foun
|
||||
|
||||
* Why even make a package
|
||||
|
||||
I am an addicted evil-mode user. I mainlined vim (well, neovim) and tmux for a year before switching to Emacs, so by the time I became enlightened I was set on using vim-style keybindings, and so I found myself to be an evil man.
|
||||
I am an addicted evil-mode user. I mainlined vim (well, Neovim) and tmux for a year before switching to Emacs, so by the time I became enlightened I was set on using vim-style key bindings, and so I found myself to be an evil man.
|
||||
|
||||
A problem I faced early on in my vim journey was mode confusion. You must always know which mode you are in, as this affects the keybindings you use. This makes perfect sense, but sometimes, you just forget. Especially if you have multiple windows open, and in each one, the mode might be different.
|
||||
A problem I faced early on in my vim journey was mode confusion. You must always know which mode you are in, as this affects the key bindings you use. This makes perfect sense, but sometimes, you just forget. Especially if you have multiple windows open, and in each one, the mode might be different.
|
||||
|
||||
I know this was a nuisance because of the amount of times I started pressing keys assuming I was in one mode but I found myself to be in another. Any vim/evil user has experienced this often at some point.
|
||||
|
||||
Of course there is an already existing visual indicator for the mode - in Emacs, using evil mode introduces a little text inside the modeline that says what the current mode is (In vim such a thing exists too, of course). Yet I still found myself pressing wrongly-moded keys quite often.
|
||||
Of course, there already exists visual indicator that tells us which mode is active. In Emacs, using evil mode introduces a little text inside the mode line that says what the current mode is (In vim such a thing exists too, of course). Yet I still found myself using the wrong mode often.
|
||||
|
||||
* A fix - highly visual indicators
|
||||
|
||||
Just because something is visible doesn't mean it is seen. I don't think this is a controvertial take by any means - but it often isn't taken into account when designing user interfaces.
|
||||
Just because something is visible doesn't mean it is seen. I don't think this is a controversial take by any means - but it often isn't taken into account when designing user interfaces.
|
||||
|
||||
When using vim+tmux, one of the biggest problems was knowing which window I was in. I would start typing in one shell or window and realized that I completely trashed another window. My solution was to make the active buffer background brighter, so ithat at a glance it would be obvious which window was selected. Once moving to Emacs I had to settle for only changing the color of the modeline, along with using hl-line-mode. Either way - it worked. I was far less confused as to which window was receiving my inputs because of this journey.
|
||||
When using vim+tmux, one of the biggest problems was knowing which window I was in. I would start typing in one shell or window and realized that I completely trashed another window. My solution was to make the active buffer background brighter, so that at a glance it would be obvious which window was selected. Once moving to Emacs I had to settle for only changing the color of the mode line, along with using hl-line-mode. Either way - it worked. I was far less confused as to which window was receiving my inputs because of this journey.
|
||||
|
||||
I think my main guide is this - information that is necessary to act on at high frequency needs to be shown very visibly. There is a clear benefit to making the current state of a system not only understandable, but _clearly obvious_ at a _glance_.
|
||||
|
||||
Knowing this, it seemed only natural to fix the mode confusion with a very obvious indicator as to which mode I am in. I have been using some version of =evil-hl-line= for quite a while, and am very pleased with the results.
|
||||
Knowing this, it seemed only natural to fix the mode confusion with a very obvious indicator as to which mode I am in. I have been using some version of =evil-hl-line= for a while, and am very pleased with the results.
|
||||
|
||||
If you use evil mode in Emacs, I think you may find this approach helpful, and I hope you will find this package useful!
|
||||
|
||||
|
||||
+1
-2
@@ -5,6 +5,5 @@
|
||||
|
||||
#+INCLUDE: generated/recent-posts.org
|
||||
|
||||
* Contact me
|
||||
|
||||
Feel free to contact me!
|
||||
|
||||
|
||||
+34
-3
@@ -60,13 +60,19 @@ body {
|
||||
/* ── Navigation ──────────────────────────────────────── */
|
||||
#preamble nav {
|
||||
display: flex;
|
||||
gap: 1.5rem;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 1.25rem 0;
|
||||
border-bottom: 1px solid var(--border);
|
||||
margin-bottom: 2.5rem;
|
||||
}
|
||||
|
||||
#preamble nav a {
|
||||
.nav-links {
|
||||
display: flex;
|
||||
gap: 1.5rem;
|
||||
}
|
||||
|
||||
.nav-links a {
|
||||
color: var(--fg);
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
@@ -74,7 +80,14 @@ body {
|
||||
letter-spacing: 0.01em;
|
||||
}
|
||||
|
||||
#preamble nav a:hover { color: var(--accent); }
|
||||
.nav-links a:hover { color: var(--accent); }
|
||||
|
||||
.nav-contact {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
/* ── Content ─────────────────────────────────────────── */
|
||||
#content {
|
||||
@@ -192,3 +205,21 @@ th {
|
||||
}
|
||||
.tag { display: none; }
|
||||
#table-of-contents { margin-bottom: 2rem; }
|
||||
|
||||
/* ── Contact links ───────────────────────────────────── */
|
||||
.contact-link {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.45rem;
|
||||
color: var(--muted);
|
||||
text-decoration: none;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.contact-link svg {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.contact-link:hover { color: var(--accent); }
|
||||
|
||||
Reference in New Issue
Block a user