<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Thomas Koch – Posts tagged "nix"</title>
    <link href="https://blog.koch.ro/tags/nix.atom.xml" rel="self" />
    <link href="https://blog.koch.ro" />
    <id>https://blog.koch.ro/tags/nix.atom.xml</id>
    <author>
        <name>Thomas Koch</name>
        
        <email>thomas+blog@koch.ro</email>
        
    </author>
    <updated>2025-07-10T13:30:23Z</updated>
    <entry>
    <title>Epiphany from 38c3 sixos talk</title>
    <link href="https://blog.koch.ro/posts/2025-01-05-epiphany-38c3-sixos-talk.html" />
    <id>https://blog.koch.ro/posts/2025-01-05-epiphany-38c3-sixos-talk.html</id>
    <published>2025-01-05T00:00:00Z</published>
    <updated>2025-07-10T13:30:23Z</updated>
    <summary type="html"><![CDATA[<div class="info">
    Posted on January  5, 2025
    
</div>
<div class="info">
    
    Tags: <a title="All pages tagged &#39;debian&#39;." href="/tags/debian.html" rel="tag">debian</a>, <a title="All pages tagged &#39;nix&#39;." href="/tags/nix.html" rel="tag">nix</a>
    
</div>

<p>There are so many new insights from this talk, that I need to pin them down.</p>
<p><a href="https://media.ccc.de/v/38c3-sixos-a-nix-os-without-systemd">sixos: a nix os without systemd</a> by Adam Joseph (<a href="https://events.ccc.de/congress/2024/hub/de/event/sixos-a-nix-os-without-systemd/">Fahrplan</a>)</p>
<p><a href="https://codeberg.org/amjoseph/sixos">sixos</a> is much like <a href="https://nixos.org">NixOS</a> but uses <a href="https://www.skarnet.org/software/s6/overview.html">s6</a> instead of systemd and an alternative
configuration mechanism for services called “<a href="https://codeberg.org/amjoseph/infuse.nix">infusion</a>” instead of nixos’
modules. s6 is a set of small tools that together provide the functionality of
process supervision, service dependency mangagement and more.</p>
<p>The s6 site provides A LOT of insight about how to do all of this conforming
to the UNIX philosophy. Especially new and interesting to me were the bits
about “chain loading” and this <a href="https://skarnet.org/lists/supervision/0422.html">rant about systemd</a>. The latter finally
convinced me, that systemd is a bad thing and that I should try to get rid of
it. - Sorry for being a bit late to the party.</p>
<p>I’ve a dream of creating a replacement for kubernetes. I don’t need such a
thing right now, but it would heal some post-traumatic syndroms after two
years of kubernetes support. The small and simple tools from s6 together with
nix would already cover a lot of ground.</p>
<p>More interesting bits discoverd:</p>
<ul>
<li>“chain loading” aka “<a href="http://www.catb.org/~esr/writings/taoup/html/ch06s06.html">Bernstein chaining</a>” are terms to describe a chain of
processes exec’ing into each other. I didn’t know there are names for
this. It’s actually so powerful that one can build a programming language on
top of it: <a href="https://skarnet.org/software/execline/grammar.html">execline</a>.</li>
<li><a href="https://github.com/illiliti/libudev-zero">libudev-zero</a> - daemonless replacement for libudev
<ul>
<li><a href="https://github.com/illiliti/respectful-software">respectful-software</a> - alternatives to CoCs and CLAs and more good advice</li>
<li><a href="https://kisscommunity.bvnf.space/">KISS Linux Community</a> - I love KISS</li>
</ul></li>
<li><a href="https://www.brain-dump.org/projects/abduco/">abduco</a> - lighter alternative to SCREEN and TMUX</li>
</ul>
<p>This find quote I want to learn by heart:</p>
<blockquote>
<p>“If the users don’t control the program, the program controls the users. With
proprietary software, there is always some entity, the “owner” of the program,
that controls the program and through it, exercises power over its users. A
nonfree program is a yoke, an instrument of unjust power.” — Richard Stallman<a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a></p>
</blockquote>
<p>There is no hint to any communication channel for discussions about sixos. But
Adam pointed to the <a href="https://tvl.fyi">tvl</a> channel on <a href="https://hackint.org">hackint</a> during his talk for people
interested in improving Nix and he is actually operator of a channel #six on
hackint. He is amjoseph on IRC.</p>
<p>Now I’m just curious whether there is a story behind the slogan “ca-bundle.crt
is malware” that Adam had on his shirt during the talk.</p>
<section id="footnotes" class="footnotes footnotes-end-of-document" role="doc-endnotes">
<hr />
<ol>
<li id="fn1"><p><a href="https://archive.org/details/stallman-programs-controlling-users">https://archive.org/details/stallman-programs-controlling-users</a><a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>
]]></summary>
</entry>
<entry>
    <title>Minimal overhead VMs with Nix and MicroVM</title>
    <link href="https://blog.koch.ro/posts/2024-03-17-minimal-vms-nix-microvm.html" />
    <id>https://blog.koch.ro/posts/2024-03-17-minimal-vms-nix-microvm.html</id>
    <published>2024-03-17T00:00:00Z</published>
    <updated>2025-07-10T13:30:23Z</updated>
    <summary type="html"><![CDATA[<div class="info">
    Posted on March 17, 2024
    
</div>
<div class="info">
    
    Tags: <a title="All pages tagged &#39;debian&#39;." href="/tags/debian.html" rel="tag">debian</a>, <a title="All pages tagged &#39;free software&#39;." href="/tags/free%20software.html" rel="tag">free software</a>, <a title="All pages tagged &#39;nix&#39;." href="/tags/nix.html" rel="tag">nix</a>
    
</div>

<p>Joachim Breitner wrote about a <a href="https://www.joachim-breitner.de/blog/812-Convenient_sandboxed_development_environment">Convenient sandboxed development environment</a>
and thus reminded me to blog about <a href="https://github.com/astro/microvm.nix">MicroVM</a>. I’ve toyed around with it a little
but not yet seriously used it as I’m currently not coding.</p>
<p>MicroVM is a nix based project to configure and run minimal VMs. It can mount
and thus reuse the hosts nix store inside the VM and thus has a very small
disk footprint. I use MicroVM on a debian system using the nix package
manager.</p>
<p>The MicroVM author uses the project to host production services. Otherwise I
consider it also a nice way to learn about NixOS after having started with the
nix package manager and before making the big step to NixOS as my main system.</p>
<p>The guests root filesystem is a tmpdir, so one must explicitly define folders
that should be mounted from the host and thus be persistent across VM reboots.</p>
<p>I defined the VM as a nix flake since this is how I started from the MicroVM
projects example:</p>
<pre><code>{
  description = &quot;Haskell dev MicroVM&quot;;

  inputs.impermanence.url = &quot;github:nix-community/impermanence&quot;;
  inputs.microvm.url = &quot;github:astro/microvm.nix&quot;;
  inputs.microvm.inputs.nixpkgs.follows = &quot;nixpkgs&quot;;

  outputs = { self, impermanence, microvm, nixpkgs }:
    let
      persistencePath = &quot;/persistent&quot;;
      system = &quot;x86_64-linux&quot;;
      user = &quot;thk&quot;;
      vmname = &quot;haskell&quot;;
      nixosConfiguration = nixpkgs.lib.nixosSystem {
          inherit system;
          modules = [
            microvm.nixosModules.microvm
            impermanence.nixosModules.impermanence
            ({pkgs, ... }: {

            environment.persistence.${persistencePath} = {
                hideMounts = true;
                users.${user} = {
                  directories = [
                    &quot;git&quot; &quot;.stack&quot;
                  ];
                };
              };
              environment.sessionVariables = {
                TERM = &quot;screen-256color&quot;;
              };
              environment.systemPackages = with pkgs; [
                ghc
                git
                (haskell-language-server.override { supportedGhcVersions = [ &quot;94&quot; ]; })
                htop
                stack
                tmux
                tree
                vcsh
                zsh
              ];
              fileSystems.${persistencePath}.neededForBoot = nixpkgs.lib.mkForce true;
              microvm = {
                forwardPorts = [
                  { from = &quot;host&quot;; host.port = 2222; guest.port = 22; }
                  { from = &quot;guest&quot;; host.port = 5432; guest.port = 5432; } # postgresql
                ];
                hypervisor = &quot;qemu&quot;;
                interfaces = [
                  { type = &quot;user&quot;; id = &quot;usernet&quot;; mac = &quot;00:00:00:00:00:02&quot;; }
                ];
                mem = 4096;
                shares = [ {
                  # use &quot;virtiofs&quot; for MicroVMs that are started by systemd
                  proto = &quot;9p&quot;;
                  tag = &quot;ro-store&quot;;
                  # a host&#39;s /nix/store will be picked up so that no
                  # squashfs/erofs will be built for it.
                  source = &quot;/nix/store&quot;;
                  mountPoint = &quot;/nix/.ro-store&quot;;
                } {
                  proto = &quot;virtiofs&quot;;
                  tag = &quot;persistent&quot;;
                  source = &quot;~/.local/share/microvm/vms/${vmname}/persistent&quot;;
                  mountPoint = persistencePath;
                  socket = &quot;/run/user/1000/microvm-${vmname}-persistent&quot;;
                }
                ];
                socket = &quot;/run/user/1000/microvm-control.socket&quot;;
                vcpu = 3;
                volumes = [];
                writableStoreOverlay = &quot;/nix/.rwstore&quot;;
              };
              networking.hostName = vmname;
              nix.enable = true;
              nix.nixPath = [&quot;nixpkgs=${builtins.storePath &lt;nixpkgs&gt;}&quot;];
              nix.settings = {
                extra-experimental-features = [&quot;nix-command&quot; &quot;flakes&quot;];
                trusted-users = [user];
              };
              security.sudo = {
                enable = true;
                wheelNeedsPassword = false;
              };
              services.getty.autologinUser = user;
              services.openssh = {
                enable = true;
              };
              system.stateVersion = &quot;24.11&quot;;
              systemd.services.loadnixdb = {
                description = &quot;import hosts nix database&quot;;
                path = [pkgs.nix];
                wantedBy = [&quot;multi-user.target&quot;];
                requires = [&quot;nix-daemon.service&quot;];
                script = &quot;cat ${persistencePath}/nix-store-db-dump|nix-store --load-db&quot;;
              };
              time.timeZone = nixpkgs.lib.mkDefault &quot;Europe/Berlin&quot;;
              users.users.${user} = {
                extraGroups = [ &quot;wheel&quot; &quot;video&quot; ];
                group = &quot;user&quot;;
                isNormalUser = true;
                openssh.authorizedKeys.keys = [
                  &quot;ssh-rsa REDACTED&quot;
                ];
                password = &quot;&quot;;
              };
              users.users.root.password = &quot;&quot;;
              users.groups.user = {};
            })
          ];
        };

    in {
      packages.${system}.default = nixosConfiguration.config.microvm.declaredRunner;
    };
}
</code></pre>
<p>I start the microVM with a templated systemd user service:</p>
<pre><code>[Unit]
Description=MicroVM for Haskell development
Requires=microvm-virtiofsd-persistent@.service
After=microvm-virtiofsd-persistent@.service
AssertFileNotEmpty=%h/.local/share/microvm/vms/%i/flake/flake.nix

[Service]
Type=forking
ExecStartPre=/usr/bin/sh -c &quot;[ /nix/var/nix/db/db.sqlite -ot %h/.local/share/microvm/nix-store-db-dump ] || nix-store --dump-db &gt;%h/.local/share/microvm/nix-store-db-dump&quot;
ExecStartPre=ln -f -t %h/.local/share/microvm/vms/%i/persistent/ %h/.local/share/microvm/nix-store-db-dump
ExecStartPre=-%h/.local/state/nix/profile/bin/tmux new -s microvm -d
ExecStart=%h/.local/state/nix/profile/bin/tmux new-window -t microvm: -n &quot;%i&quot; &quot;exec %h/.local/state/nix/profile/bin/nix run --impure %h/.local/share/microvm/vms/%i/flake&quot;
</code></pre>
<p>The above service definition creates a dump of the hosts nix store db so that
it can be imported in the guest. This is necessary so that the guest can
actually use what is available in /nix/store. There is an <a href="https://github.com/NixOS/rfcs/pull/152#issuecomment-1979117890">effort for an overlayed nix store</a> that would be preferable to this hack.</p>
<p>Finally the microvm is started inside a tmux session named “microvm”. This way
I can use the VM with SSH or through the console and also access the qemu
console.</p>
<p>And for completeness the virtiofsd service:</p>
<pre><code>[Unit]
Description=serve host persistent folder for dev VM
AssertPathIsDirectory=%h/.local/share/microvm/vms/%i/persistent

[Service]
ExecStart=%h/.local/state/nix/profile/bin/virtiofsd \
 --socket-path=${XDG_RUNTIME_DIR}/microvm-%i-persistent \
 --shared-dir=%h/.local/share/microvm/vms/%i/persistent \
 --gid-map :995:%G:1: \
 --uid-map :1000:%U:1:
</code></pre>
]]></summary>
</entry>
<entry>
    <title>Using nix package manager in Debian</title>
    <link href="https://blog.koch.ro/posts/2024-01-16-using-nix-package-manager-in-debian.html" />
    <id>https://blog.koch.ro/posts/2024-01-16-using-nix-package-manager-in-debian.html</id>
    <published>2024-01-16T00:00:00Z</published>
    <updated>2025-07-10T13:30:23Z</updated>
    <summary type="html"><![CDATA[<div class="info">
    Posted on January 16, 2024
    
</div>
<div class="info">
    
    Tags: <a title="All pages tagged &#39;debian&#39;." href="/tags/debian.html" rel="tag">debian</a>, <a title="All pages tagged &#39;free software&#39;." href="/tags/free%20software.html" rel="tag">free software</a>, <a title="All pages tagged &#39;nix&#39;." href="/tags/nix.html" rel="tag">nix</a>, <a title="All pages tagged &#39;life&#39;." href="/tags/life.html" rel="tag">life</a>
    
</div>

<p>The <a href="https://nixos.org">nix</a> package manager is <a href="https://tracker.debian.org/pkg/nix">available in Debian</a> since <a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=877019">May 2020</a>. Why would one
use it in Debian?</p>
<ul>
<li>learn about nix</li>
<li>install software that might not be available in Debian</li>
<li>install software without root access</li>
<li>declare software necessary for a user’s environment inside <code>$HOME/.config</code></li>
</ul>
<p>Especially the last point nagged me every time I set up a new Debian
installation. My emacs configuration and my Desktop setup expects certain
software to be installed.</p>
<p>Please be aware that I’m a beginner with nix and that my config might not
follow best practice. Additionally many nix users are already using the new
flakes feature of nix that I’m still learning about.</p>
<p>So I’ve got this file at <code>.config/nixpkgs/config.nix</code><a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a>:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode nix"><code class="sourceCode nix"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">with</span> <span class="op">(</span><span class="bu">import</span> &lt;nixpkgs&gt; <span class="op">{});</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>  <span class="va">packageOverrides</span> <span class="op">=</span> <span class="va">pkgs</span><span class="op">:</span> <span class="kw">with</span> pkgs<span class="op">;</span> <span class="op">{</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>    <span class="va">thk-emacsWithPackages</span> <span class="op">=</span> <span class="op">(</span>pkgs<span class="op">.</span>emacsPackagesFor emacs<span class="op">-</span>gtk<span class="op">).</span>emacsWithPackages <span class="op">(</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>      <span class="va">epkgs</span><span class="op">:</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>      <span class="op">(</span><span class="kw">with</span> epkgs<span class="op">.</span>elpaPackages<span class="op">;</span> <span class="op">[</span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>        ace-window</span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a>        company</span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a>        org</span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a>        use-package</span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a>      <span class="op">])</span> <span class="op">++</span> <span class="op">(</span><span class="kw">with</span> epkgs<span class="op">.</span>melpaPackages<span class="op">;</span> <span class="op">[</span></span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a>        editorconfig</span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a>        flycheck</span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a>        haskell-mode</span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a>        magit</span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a>        nix-mode</span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a>        paredit</span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a>        rainbow-delimiters</span>
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a>        treemacs</span>
<span id="cb1-20"><a href="#cb1-20" aria-hidden="true" tabindex="-1"></a>        visual-fill-column</span>
<span id="cb1-21"><a href="#cb1-21" aria-hidden="true" tabindex="-1"></a>        yasnippet-snippets</span>
<span id="cb1-22"><a href="#cb1-22" aria-hidden="true" tabindex="-1"></a>      <span class="op">])</span> <span class="op">++</span> <span class="op">[</span>    <span class="co"># From main packages set</span></span>
<span id="cb1-23"><a href="#cb1-23" aria-hidden="true" tabindex="-1"></a>      <span class="op">]</span></span>
<span id="cb1-24"><a href="#cb1-24" aria-hidden="true" tabindex="-1"></a>    <span class="op">);</span></span>
<span id="cb1-25"><a href="#cb1-25" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-26"><a href="#cb1-26" aria-hidden="true" tabindex="-1"></a>    <span class="va">userPackages</span> <span class="op">=</span> buildEnv <span class="op">{</span></span>
<span id="cb1-27"><a href="#cb1-27" aria-hidden="true" tabindex="-1"></a>      <span class="va">extraOutputsToInstall</span> <span class="op">=</span> <span class="op">[</span> <span class="st">&quot;doc&quot;</span> <span class="st">&quot;info&quot;</span> <span class="st">&quot;man&quot;</span> <span class="op">];</span></span>
<span id="cb1-28"><a href="#cb1-28" aria-hidden="true" tabindex="-1"></a>      <span class="va">name</span> <span class="op">=</span> <span class="st">&quot;user-packages&quot;</span><span class="op">;</span></span>
<span id="cb1-29"><a href="#cb1-29" aria-hidden="true" tabindex="-1"></a>      <span class="va">paths</span> <span class="op">=</span> <span class="op">[</span></span>
<span id="cb1-30"><a href="#cb1-30" aria-hidden="true" tabindex="-1"></a>        ghc</span>
<span id="cb1-31"><a href="#cb1-31" aria-hidden="true" tabindex="-1"></a>        git</span>
<span id="cb1-32"><a href="#cb1-32" aria-hidden="true" tabindex="-1"></a>        <span class="op">(</span>pkgs<span class="op">.</span>haskell<span class="op">-</span>language<span class="op">-</span>server<span class="op">.</span>override <span class="op">{</span> <span class="va">supportedGhcVersions</span> <span class="op">=</span> <span class="op">[</span> <span class="st">&quot;94&quot;</span> <span class="op">];</span> <span class="op">})</span></span>
<span id="cb1-33"><a href="#cb1-33" aria-hidden="true" tabindex="-1"></a>        nix</span>
<span id="cb1-34"><a href="#cb1-34" aria-hidden="true" tabindex="-1"></a>        stack</span>
<span id="cb1-35"><a href="#cb1-35" aria-hidden="true" tabindex="-1"></a>        thk-emacsWithPackages</span>
<span id="cb1-36"><a href="#cb1-36" aria-hidden="true" tabindex="-1"></a>        tmux</span>
<span id="cb1-37"><a href="#cb1-37" aria-hidden="true" tabindex="-1"></a>        vcsh</span>
<span id="cb1-38"><a href="#cb1-38" aria-hidden="true" tabindex="-1"></a>        virtiofsd</span>
<span id="cb1-39"><a href="#cb1-39" aria-hidden="true" tabindex="-1"></a>      <span class="op">];</span></span>
<span id="cb1-40"><a href="#cb1-40" aria-hidden="true" tabindex="-1"></a>    <span class="op">};</span></span>
<span id="cb1-41"><a href="#cb1-41" aria-hidden="true" tabindex="-1"></a>  <span class="op">};</span></span>
<span id="cb1-42"><a href="#cb1-42" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Every time I change the file or want to receive updates, I do:</p>
<div class="sourceCode" id="cb2" data-org-language="sh"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ex">nix-env</span> <span class="at">--install</span> <span class="at">--attr</span> nixpkgs.userPackages <span class="at">--remove-all</span></span></code></pre></div>
<p>You can see that I install nix with nix. This gives me a newer version than
the one available in Debian stable. However, the nix-daemon still runs as the
older binary from Debian. My dirty hack is to put this override in
<code>/etc/systemd/system/nix-daemon.service.d/override.conf</code>:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode ini"><code class="sourceCode ini"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">[Service]</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="dt">ExecStart</span><span class="ot">=</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="dt">ExecStart</span><span class="ot">=</span><span class="st">@/home/thk/.local/state/nix/profile/bin/nix-daemon nix-daemon --daemon</span></span></code></pre></div>
<p>I’m not too interested in a cleaner way since I hope to fully migrate to Nix
anyways.</p>
<section id="footnotes" class="footnotes footnotes-end-of-document" role="doc-endnotes">
<hr />
<ol>
<li id="fn1"><p>Note the <code>nixpkgs</code> in the path. This is not a config file
for <code>nix</code> the package manager but for the <a href="https://github.com/NixOS/nixpkgs">nix package collection</a>. See the
<a href="https://nixos.org/manual/nixpkgs/stable/#chap-packageconfig">nixpkgs manual</a>.<a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>
]]></summary>
</entry>

</feed>
