<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Guix on Linux Maxxing dot com</title>
    <link>https://linuxmaxxing.com/tags/guix/</link>
    <description>Recent content in Guix on Linux Maxxing dot com</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <copyright>No Copyright</copyright>
    <lastBuildDate>Wed, 01 Jul 2026 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://linuxmaxxing.com/tags/guix/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Guix Part 2: Desktop Setup</title>
      <link>https://linuxmaxxing.com/posts/10_guix/</link>
      <pubDate>Wed, 01 Jul 2026 00:00:00 +0000</pubDate>
      <guid>https://linuxmaxxing.com/posts/10_guix/</guid>
      <description>&lt;div id=&#34;outline-container-headline-1&#34; class=&#34;outline-2&#34;&gt;&#xA;&lt;h2 id=&#34;headline-1&#34;&gt;&#xA;Correction&#xA;&lt;/h2&gt;&#xA;&lt;div id=&#34;outline-text-headline-1&#34; class=&#34;outline-text-2&#34;&gt;&#xA;&lt;p&gt;&#xA;One of the best features of any GNU project is the Reference Manual&#xA;which typically ships in the texinfo format, commonly called info pages.&lt;/p&gt;&#xA;&lt;p&gt;&#xA;Prior to using Emacs I absolutely hated info pages.&#xA;The terminal info viewer is basically a stripped-down version of emacs similar to &lt;code&gt;mg&lt;/code&gt; and does not provide a great reading experience compared to &lt;code&gt;man&lt;/code&gt; pages.&lt;/p&gt;&#xA;&lt;p&gt;&#xA;But within Emacs info pages are fantastic, especially when you&#xA;leverage Emacs features like bookmarks. So as I cracked open the Guix&#xA;Info Page I found this blurb:&lt;/p&gt;</description>
      <content:encoded><![CDATA[
<div id="outline-container-headline-1" class="outline-2">
<h2 id="headline-1">
Correction
</h2>
<div id="outline-text-headline-1" class="outline-text-2">
<p>
One of the best features of any GNU project is the Reference Manual
which typically ships in the texinfo format, commonly called info pages.</p>
<p>
Prior to using Emacs I absolutely hated info pages.
The terminal info viewer is basically a stripped-down version of emacs similar to <code>mg</code> and does not provide a great reading experience compared to <code>man</code> pages.</p>
<p>
But within Emacs info pages are fantastic, especially when you
leverage Emacs features like bookmarks. So as I cracked open the Guix
Info Page I found this blurb:</p>
<blockquote>
<p>(2) We used to refer to Guix System as “Guix System Distribution” or
“GuixSD”.  We now consider it makes more sense to group everything under
the “Guix” banner since, after all, Guix System is readily available
through the ‘guix system’ command, even if you’re using a different
distro underneath!</p>
</blockquote>
<p>
This must have been a recent change, I did not realize Guix System and GuixSD just became Guix. I referred to Guix (the distro) as Guix System in my last post.
There are other parts of the manual that still refer to Guix System when differentiating from Guix the package manager on &#34;foreign distros,&#34; so perhaps the change has not propagated.</p>
<hr>
<hr>
</div>
</div>
<div id="outline-container-headline-2" class="outline-2">
<h2 id="headline-2">
Default Programs
</h2>
<div id="outline-text-headline-2" class="outline-text-2">
<p>I failed to mention this in my first post, but Guix ships with a couple nice packages.
The first is <code>mg</code>, also known as microemacs, as mentioned above.
As an Emaxxer I am mildly hampered by the fact that your default out-of-the-box editor is almost always <code>vi</code>.
Sometimes nano is installed as well.</p>
<p>
<code>mg</code> is to Emacs what <code>vi</code> is to vim. It is an emacs-like environment with vanilla bindings and basic features (e.g. dired) maintained by the OpenBSD team.</p>
<p>
It reminds me a ton of the default <code>info</code> page reader (which is why most do not like reading <code>info</code> pages).
However the editing experience is much closer to emacs than <code>vi</code> is to vim and I have zero issues using it when on a server or container and don&#39;t want the full Emacs package, or when already in a terminal and don&#39;t want to fire up Emacs.
It is not surprising that Guix ships with it considering guix is basically a convoluted way of Emaxxing an entire distro.</p>
<p>
Guix ships with the <code>findutils</code> package which contains the <code>locate</code> and <code>updatedb</code> commands. On other distros this is usually found in the <code>plocate</code> package.
I prefer <code>plocate</code> for speed reasons, but having the same functionality out of the box is nice since it is pretty much a must-have on guix unless you are a <code>find</code> command wizard.</p>
<p>
In order to use <code>plocate</code> on guix it appears the <code>plocate</code> group is required.
Additionally there is an <code>updatedb</code> cron/herd timer service, so with that in mind I will just
stick with the default <code>findutils</code> version rather than bloating up my system with a single extra group and package</p>
<hr>
</div>
</div>
<div id="outline-container-headline-3" class="outline-2">
<h2 id="headline-3">
Dollar Path
</h2>
<div id="outline-text-headline-3" class="outline-text-2">
<div id="outline-container-headline-4" class="outline-3">
<h3 id="headline-4">
Shebangs
</h3>
<div id="outline-text-headline-4" class="outline-text-3">
<p>I have followed <a href="https://blog.daveeddy.com/">Dave Eddy</a> for a while and love his bash content. One
thing he is adamant about is not calling bash with
<code>#!/bin/bash</code> and instead using <code>#!/usr/bin/env bash</code>. This is because the
<code>bash</code> executable is not located in <code>/bin</code> in macOS and it potentially renders the script unable to call locally-installed versions
of bash depending on the installation path, so <code>#!/usr/bin/env bash</code>
should be used instead as a catch-all that will always work.
I basically said &#34;whatever bro&#34; to this advice as I will never use macOS.
However in Guix and I presume Nix there is no <code>/bin/bash</code> symlink.
So yeah, Dave was right, make your bash shebangs <code>#!/usr/bin/env bash</code>.</p>
</div>
</div>
<div id="outline-container-headline-5" class="outline-3">
<h3 id="headline-5">
echo $PATH
</h3>
<div id="outline-text-headline-5" class="outline-text-3">
<p>All your system executable files are ultimately symlinked to <code>/gnu/store</code>. By default you should have the following directories or something similar in your <code>PATH</code>:</p>
<ul>
<li>$HOME/.config/guix/current/bin</li>
<li>$HOME/.guix-profile/bin</li>
<li>/run/setuid-programs</li>
<li>$HOME/.config/guix/current/bin</li>
<li>$HOME/.guix-profile/bin</li>
<li>/run/current-system/profile/bin</li>
<li>/run/current-system/profile/sbin</li>
</ul>
<p>If you use guix-home, you&#39;ll have the following added to your path from the <code>~/.profile</code> symlinked file:</p>
<ul>
<li>$HOME/.guix-home/profile/bin</li>
<li>$HOME/.guix-home/profile/sbin</li>
</ul>
<p>If you follow the <a href="https://guix.gnu.org/manual/1.5.0/en/html_node/Miscellaneous-Services.html#:~:text=Nix%20service">Nix service on Guix</a> instructions, you&#39;ll end up adding:</p>
<ul>
<li>$HOME/.nix-profile/bin</li>
</ul>
<p>On most distros users typically add <code>~/.local/bin</code> to <code>PATH</code> via .bash_profile (or similar) and stick custom executable files in that directory.
You can still do this with Guix since your $HOME directory is still fair game.
You cannot create <code>/usr/local/bin</code> however.</p>
<hr>
</div>
</div>
</div>
</div>
<div id="outline-container-headline-6" class="outline-2">
<h2 id="headline-6">
Dotfiles
</h2>
<div id="outline-text-headline-6" class="outline-text-2">
<p>Previously I used <code>~/.profile</code> for most environmental variables and other stuff, but <code>~/.profile</code> is a
symlink used by guix-home to set the <code>HOME_ENVIRONMENT</code> variable.
If you choose not to use guix-home, this won&#39;t be an issue, but guix-home is one of the biggest selling points of guix.</p>
<p>
Instead I use the default profile file, <code>~/.bash_profile</code>, as a launching point. All environmental
variables are declared in <code>~/.config/shell/profile</code>, which is the same
directory all my aliases file. Then all Guix and Nix sourcing happens
in <code>~/.bash_profile</code>. I don&#39;t use <code>zsh</code> because I am a <a href="https://youtu.be/5Wz9BkzU1zY">GNUTard</a>.</p>
<p>
Here&#39;s my <code>~/.bash_profile</code> which has conditionals for Guix system, Guix package manager on a foreign distro, and Nix package manager.
It works on any distro.
The <code>XDG_DATA_DIRS</code> environment variable is also modified to include .desktop files provided by both nix and flatpak:</p>
<div class="src src-shell">
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl"><span class="cp">#!/bin/sh
</span></span></span><span class="line"><span class="cl"><span class="o">[</span> -f <span class="s2">&#34;</span><span class="nv">$HOME</span><span class="s2">/.profile&#34;</span> <span class="o">]</span> <span class="o">&amp;&amp;</span> . <span class="s2">&#34;</span><span class="nv">$HOME</span><span class="s2">/.profile&#34;</span>
</span></span><span class="line"><span class="cl"><span class="o">[</span> -f <span class="s2">&#34;</span><span class="nv">$HOME</span><span class="s2">/.config/shell/profile&#34;</span> <span class="o">]</span> <span class="o">&amp;&amp;</span> . <span class="s2">&#34;</span><span class="nv">$HOME</span><span class="s2">/.config/shell/profile&#34;</span>
</span></span><span class="line"><span class="cl"><span class="o">[</span> -f <span class="s2">&#34;</span><span class="nv">$HOME</span><span class="s2">/.bashrc&#34;</span> <span class="o">]</span> <span class="o">&amp;&amp;</span> . <span class="s2">&#34;</span><span class="nv">$HOME</span><span class="s2">/.bashrc&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">####### GUIX SYSTEM</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Merge search-paths from multiple profiles. Order matters.</span>
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="o">[</span> -e /run/current-system/configuration.scm <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">    <span class="nb">eval</span> <span class="s2">&#34;</span><span class="k">$(</span>guix package --search-paths <span class="se">\
</span></span></span><span class="line"><span class="cl">-p <span class="nv">$HOME</span>/.config/guix/current <span class="se">\
</span></span></span><span class="line"><span class="cl">-p <span class="nv">$HOME</span>/.guix-home/profile <span class="se">\
</span></span></span><span class="line"><span class="cl">-p <span class="nv">$HOME</span>/.guix-profile <span class="se">\
</span></span></span><span class="line"><span class="cl">-p /run/current-system/profile<span class="k">)</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># Prepend setuid programs.</span>
</span></span><span class="line"><span class="cl">    <span class="nb">export</span> <span class="nv">PATH</span><span class="o">=</span>/run/setuid-programs:<span class="nv">$PATH</span>
</span></span><span class="line"><span class="cl"><span class="k">fi</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">####### GUIX PACKAGE MANAGER</span>
</span></span><span class="line"><span class="cl"><span class="nv">GUIX_PROFILE</span><span class="o">=</span><span class="s2">&#34;</span><span class="nv">$HOME</span><span class="s2">/.guix-profile&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="o">[</span> -f <span class="s2">&#34;</span><span class="nv">$GUIX_PROFILE</span><span class="s2">/etc/profile&#34;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">    . <span class="s2">&#34;</span><span class="nv">$GUIX_PROFILE</span><span class="s2">/etc/profile&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="nb">unset</span> GUIX_PROFILE
</span></span><span class="line"><span class="cl"><span class="k">fi</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nv">GUIX_PROFILE</span><span class="o">=</span><span class="s2">&#34;</span><span class="nv">$HOME</span><span class="s2">/.config/guix/current&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="o">[</span> -f <span class="s2">&#34;</span><span class="nv">$GUIX_PROFILE</span><span class="s2">/etc/profile&#34;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">    . <span class="s2">&#34;</span><span class="nv">$GUIX_PROFILE</span><span class="s2">/etc/profile&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="nb">unset</span> GUIX_PROFILE
</span></span><span class="line"><span class="cl"><span class="k">fi</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">####### GUIX HOME</span>
</span></span><span class="line"><span class="cl"><span class="o">[</span> -f <span class="s2">&#34;</span><span class="nv">$HOME</span><span class="s2">/.guix-home/setup-environment&#34;</span> <span class="o">]</span> <span class="o">&amp;&amp;</span> . <span class="s2">&#34;</span><span class="nv">$HOME</span><span class="s2">/.guix-home/setup-environment&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">####### NIX PACKAGE MANAGER</span>
</span></span><span class="line"><span class="cl"><span class="o">[</span> -d <span class="s2">&#34;</span><span class="nv">$HOME</span><span class="s2">/.nix-profile/bin&#34;</span> <span class="o">]</span> <span class="o">&amp;&amp;</span> <span class="nb">export</span> <span class="nv">PATH</span><span class="o">=</span><span class="s2">&#34;</span><span class="nv">$HOME</span><span class="s2">/.nix-profile/bin:</span><span class="nv">$PATH</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl"><span class="o">[</span> -d <span class="s2">&#34;/nix/var/nix/profiles/default/bin&#34;</span> <span class="o">]</span> <span class="o">&amp;&amp;</span> <span class="nb">export</span> <span class="nv">PATH</span><span class="o">=</span><span class="s2">&#34;/nix/var/nix/profiles/default/bin:</span><span class="nv">$PATH</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="o">[</span> -e <span class="s2">&#34;</span><span class="nv">$HOME</span><span class="s2">/.nix-profile/etc/profile.d/nix.sh&#34;</span> <span class="o">]</span> <span class="o">&amp;&amp;</span>
</span></span><span class="line"><span class="cl">    . <span class="s2">&#34;</span><span class="nv">$HOME</span><span class="s2">/.nix-profile/etc/profile.d/nix.sh&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="o">[</span> -e <span class="s2">&#34;/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh&#34;</span> <span class="o">]</span> <span class="o">&amp;&amp;</span>
</span></span><span class="line"><span class="cl">    . <span class="s2">&#34;/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">####### Nix desktop files</span>
</span></span><span class="line"><span class="cl"><span class="o">[</span> -d <span class="s2">&#34;</span><span class="nv">$HOME</span><span class="s2">/.nix-profile/share&#34;</span> <span class="o">]</span> <span class="o">&amp;&amp;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">    <span class="nb">export</span> <span class="nv">XDG_DATA_DIRS</span><span class="o">=</span><span class="s2">&#34;</span><span class="nv">$HOME</span><span class="s2">/.nix-profile/share</span><span class="si">${</span><span class="nv">XDG_DATA_DIRS</span><span class="p">:+:</span><span class="nv">$XDG_DATA_DIRS</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">####### flatpak desktop files</span>
</span></span><span class="line"><span class="cl"><span class="o">[</span> -d <span class="s2">&#34;</span><span class="nv">$HOME</span><span class="s2">/.local/share/flatpak/exports/share&#34;</span> <span class="o">]</span> <span class="o">&amp;&amp;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">    <span class="nb">export</span> <span class="nv">XDG_DATA_DIRS</span><span class="o">=</span><span class="s2">&#34;</span><span class="nv">$HOME</span><span class="s2">/.local/share:</span><span class="nv">$HOME</span><span class="s2">/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:</span><span class="si">${</span><span class="nv">XDG_DATA_DIRS</span><span class="k">:-</span><span class="p">/usr/local/share:/usr/share</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">####### Reset ~/.local/bin on guix</span>
</span></span><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">PATH</span><span class="o">=</span><span class="s2">&#34;</span><span class="nv">$HOME</span><span class="s2">/.local/bin:</span><span class="nv">$PATH</span><span class="s2">&#34;</span></span></span></code></pre></div>
</div>
<div id="outline-container-headline-7" class="outline-3">
<h3 id="headline-7">
Guix Home for Managing Dotfiles
</h3>
<div id="outline-text-headline-7" class="outline-text-3">
<p>I do not plan to declaratively define my dotfiles using guix-home using <a href="https://guix.gnu.org/manual/devel/en/html_node/Essential-Home-Services.html#:~:text=home%2Dfiles%2Dservice%2Dtype">home-files-service-type</a>, it just doesn&#39;t make sense since I use them on other linux distros.
I will continue to use <a href="https://www.gnu.org/software/stow/">GNU Stow</a> as I like the flexibility it provides. I keep all personal git repos in one root directory and symlink files out as needed.</p>
<p>
In fact I actually have 2 dotfiles repos: one minimal containing just the things needed for a headless environment, and another containing just the desktop related stuff.
That way I can keep the files lean on servers/containers and bloated on desktops.
Plus a scripts repo which I symlink to <code>~/.local/bin</code>.
This is an easy task to accomplish with GNU Stow since it is just a symlink manager, but would not be possible using the <a href="https://www.atlassian.com/git/tutorials/dotfiles">git bare repo method</a> for managing dotfiles.
Continuing to use GNU Stow also seems right in-line with the Emacs/Guix/GNUTard pipeline.</p>
<p>
<em>However</em>, guix also has <a href="https://guix.gnu.org/manual/devel/en/html_node/Essential-Home-Services.html#:~:text=home%2Ddotfiles%2Dservice%2Dtype">home-dotfiles-service-type</a> which effectively functions as a hybrid between GNU Stow and <code>home-files-service-type</code>.
You declare your dotfiles repos in your guix home config, and guix home will create symlinks to a created copy in <code>/gnu/store</code>.
This is a best of both world&#39;s approach. It gives you the stability and roll-back features of <code>home-files-service-type</code> and the flexibility of an independent dotfiles repo.
It also prevents you from having to run something like <code>stow -R -t $HOME --no-folding .</code> every time you add a file to your dotfiles repo, but it does require re-configuring guix home for every edit.
For now I&#39;m holding off on using this as your dotfiles become managed in the gnu store, which means on-the-fly edits are not possible without running <code>guix home reconfigure</code> afterward.</p>
<hr>
</div>
</div>
</div>
</div>
<div id="outline-container-headline-8" class="outline-2">
<h2 id="headline-8">
Desktop Mods
</h2>
<div id="outline-text-headline-8" class="outline-text-2">
<p>
Surprising to me, though I suppose not surprising when you consider GNU&#39;s history, Guix defaults to Gnome and retains Gnome tools by default.
The default login manager is gdm, though they support a somewhat limited number of other <a href="https://guix.gnu.org/manual/1.5.0/en/html_node/X-Window.html">login managers</a>.
Having tried a number of them, I would just stick to the default gdm.
It Just Werks<sup>TM</sup> on Guix.
LXDM and ly are my favorite, but those are not included in the Guix repos.</p>
<div id="outline-container-headline-9" class="outline-3">
<h3 id="headline-9">
Gnome Keyring, ssh/gpg-agent Woes:
</h3>
<div id="outline-text-headline-9" class="outline-text-3">
<p>Without getting in the configuration weeds, all alternatives to gdm (lightdm, tty+startx, etc) required typing your keyring password in after every login out of the box.
Since your gpg and ssh keys are also stored in your keyring, you&#39;ll need to enter those passwords as well depending on your setup.
In my case emacs sources <code>~/.authinfo.gpg</code> immediately on startup, and I launch emacs automatically on login
This results in a race condition where I needed to enter my keyring password before emacs could read <code>~/.authinfo.gpg</code>, else I had to additionally type in my gpg passphrase.</p>
<p>
Additionally your ssh-agent will be affected by how you log in. When using the default gcr (gnome) gpg agent, logging in from gdm works fine.
Launching X from the tty resulted in dbus-related errors so that ssh refused using gcr as an ssh-agent.
I managed to get gpg-agent to work as an ssh agent, but that involved adding a couple of lines to my <code>~/.xinitrc</code> to export the GPG_TTY environmental variable among other things.
The keyring unlock race condition still existed when launching X from tty.</p>
<p>
I had all kinds of bugs using slim which is otherwise a good but underused login manager.
When logging out of any DE or WM, slim would pop up from within the DE/WM and lock up.</p>
<p>
If you are really particular about your login manager, Guix is probably not the system for you unless you&#39;re ready to create your own packages and services.
This isn&#39;t so much a guix problem, more of a dubs/keyring/secret-service problem that nobody enjoys troubleshooting.
This is also why it is a not-uncommon practice to have password-less gpg and ssh keys, something I will not do because schizo.</p>
<p>
I could go down the path of troubleshooting all this stuff and trying to get a perfect solution, but it&#39;s something I really don&#39;t care much about.
If I can get a consistently working solution with all little mucking as possible, I&#39;m going to take that every time.</p>
<p>
I haven&#39;t even addressed the fact that some programs also have hard-coded requirements for gnome-keyring even though pass and keepassxc can both function as secret-service alternatives.</p>
</div>
</div>
<div id="outline-container-headline-10" class="outline-3">
<h3 id="headline-10">
Window Managers
</h3>
<div id="outline-text-headline-10" class="outline-text-3">
<p>Openbox worked fine out of the box, though I haven&#39;t touched my openbox config in
years. There is not a menu-generation package in Guix/Nix which is expected as most of those are no longer maintained, so you&#39;ll just have to edit the xml directly.</p>
<p>
Before using dwm I used <a href="https://github.com/conformal/spectrwm">spectrwm</a> (formerly called scrotwm).
It is a very nice dwm-clone which uses a plain-text config file.
Think of it as dwm with sane defaults, a few useful patches, and an extremely minimal bar that is just a shell script.</p>
<p>
This spectrwm package manager is included in guix, however I could not get it to launch from gdm.
It ends up logging out to a locked gdm screen that won&#39;t accept password input.
Side note: I had similar errors with gdm when using an <code>~/.xsession</code> file.
I have yet to troubleshoot this spectrwm launching issue, though I found a reddit dot com post from 4 years describing the same behavior.</p>
</div>
</div>
<div id="outline-container-headline-11" class="outline-3">
<h3 id="headline-11">
Suckless Software
</h3>
<div id="outline-text-headline-11" class="outline-text-3">
<p>In guix you cannot just <code>git clone &lt;repo&gt; &amp;&amp; cd &lt;repo&gt; &amp;&amp; sudo make clean install</code> like you&#39;ll see in tutorials.
For starters you generally never have a need to blanket <code>make install</code> as root, your makefile should be set to a local directory (<code>~/.local</code>) unless a root directory is explicitly needed.</p>
<p>
In guix the ideal solution is to package your own builds of suckless software (or anything else you&#39;d otherwise compile).
I&#39;ll go down this route eventually, but in the short-term I just needed something to build to the suckless starter-pack: dmenu, dwm, slstatus, and st.</p>
<p>
I ended up just cloning my repos as normal, changing to the repo directory, and then launching <code>guix shell</code> with the required compilation dependencies.
Then I ran <code>make</code> and <code>make install</code> with a environmental variables to get <code>gcc</code> and function properly and to install to <code>~/.local/bin</code>.
Ideally you create a <code>manifest.scm</code> file for repeatable <code>guix shell</code> environments, but in my case I just wrote a shell script which I could use on each of the 4 suckless packages I use:</p>
<div class="src src-shell">
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl"><span class="cp">#!/bin/sh
</span></span></span><span class="line"><span class="cl"><span class="nb">set</span> -e
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">cd</span> <span class="s2">&#34;</span><span class="k">$(</span>dirname <span class="s2">&#34;</span><span class="nv">$0</span><span class="s2">&#34;</span><span class="k">)</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">guix shell <span class="se">\
</span></span></span><span class="line"><span class="cl">     gcc-toolchain pkg-config make <span class="se">\
</span></span></span><span class="line"><span class="cl">     libx11 libxft libxinerama fontconfig freetype <span class="se">\
</span></span></span><span class="line"><span class="cl">     -- make <span class="se">\
</span></span></span><span class="line"><span class="cl">     <span class="nv">CC</span><span class="o">=</span>gcc <span class="se">\
</span></span></span><span class="line"><span class="cl">     <span class="nv">X11INC</span><span class="o">=</span><span class="k">$(</span>guix build libx11<span class="k">)</span>/include <span class="se">\
</span></span></span><span class="line"><span class="cl">     <span class="nv">X11LIB</span><span class="o">=</span><span class="k">$(</span>guix build libx11<span class="k">)</span>/lib <span class="se">\
</span></span></span><span class="line"><span class="cl">     <span class="nv">FREETYPEINC</span><span class="o">=</span><span class="k">$(</span>guix build freetype<span class="k">)</span>/include/freetype2
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">guix shell <span class="se">\
</span></span></span><span class="line"><span class="cl">     gcc-toolchain pkg-config make libx11 libxft libxinerama fontconfig freetype <span class="se">\
</span></span></span><span class="line"><span class="cl">     -- make <span class="se">\
</span></span></span><span class="line"><span class="cl">     <span class="nv">CC</span><span class="o">=</span>gcc <span class="se">\
</span></span></span><span class="line"><span class="cl">     <span class="nv">X11INC</span><span class="o">=</span><span class="k">$(</span>guix build libx11<span class="k">)</span>/include <span class="se">\
</span></span></span><span class="line"><span class="cl">     <span class="nv">X11LIB</span><span class="o">=</span><span class="k">$(</span>guix build libx11<span class="k">)</span>/lib <span class="se">\
</span></span></span><span class="line"><span class="cl">     <span class="nv">FREETYPEINC</span><span class="o">=</span><span class="k">$(</span>guix build freetype<span class="k">)</span>/include/freetype2 <span class="se">\
</span></span></span><span class="line"><span class="cl">     <span class="nv">PREFIX</span><span class="o">=</span>~/.local <span class="se">\
</span></span></span><span class="line"><span class="cl">     install clean</span></span></code></pre></div>
</div>
<p>
Not strictly necessary, but I just lumped in every dependency I needed for all 4 programs in one shell.
Those dependencies will depend on which features are patched in your builds.</p>
</div>
</div>
<div id="outline-container-headline-12" class="outline-3">
<h3 id="headline-12">
Launching X from tty
</h3>
<div id="outline-text-headline-12" class="outline-text-3">
<p>Getting startx/xinit to work took some tinkering. Startx my not directly run from the tty (from what I can tell, see <a href="https://lists.gnu.org/archive/html/help-guix/2018-07/msg00080.html">mailing list thread from 2018</a>).</p>
<p>
HOWEVER guix has a &#34;package&#34; which actually originates from the AUR called <code>xinitrc-xsession</code>.
This build script creates a symbolically-linked <code>xinitrc.desktop</code> file which launches whatever is in your <code>~/.xinitrc</code>.
This desktop file can then be read by your login manager so you have an easy way to effectively run <code>startx ~/.xinitrc</code> from gdm.
With this you retain all the benefits/conveniences of your login manager without the PATH/environment issues that can arise from something like lightdm which can prevent execution of stuff called out in <code>~/.xinitrc</code>.</p>
<p>
There are ways you can set this up from <code>config.scm</code>, but you might as well hit the easy-button and use a provided solution.</p>
<p>
In time I would like to have my own dwm package to set up both the executable and .desktop file, which I figure will be an easy intro to guix packaging.
For now this will suffice, I can launch dwm without issue from gdm and all <em>muh keys</em> <sup>TM</sup> unlock at login.</p>
<hr>
</div>
</div>
</div>
</div>
<div id="outline-container-headline-13" class="outline-2">
<h2 id="headline-13">
What Comes Next?
</h2>
<div id="outline-text-headline-13" class="outline-text-2">
<p>My laptop is functionally riced out exactly as I have it in Artix, Devuan, and in the future Alpine and perhaps even Gentoo via ansible.
I won&#39;t come to any conclusions regarding continuing to use Guix for the long-term until I&#39;ve given it at least 6 months.
So far it is very promising, and after configuration Guix to no surprise runs like any other GNU/Linux distro if you can accept the few defaults I&#39;ve mentioned here.</p>
<p>
At first I was a bit bothered by not being able to edit files in /etc, /usr/local/bin, or /usr/share, but I&#39;m not sure that will be a long-term concern.</p>
<p>
I will continue to read the Guix reference manual over the coming days and after that will probably shift gears to properly learning Guile scheme.
Fortunately knowing emacs-lisp goes a long way in Guix.</p>
<p>
I probably won&#39;t bother trying to get off gdm, I&#39;ve done enough dbus/secret-service troubleshooting to know that the juice is usually not worth the squeeze, and is only a distraction from learning more useful things like guix packaging.
In addition to that I&#39;d also like to explore guix containers, guix deployment, running or replacing podman, and other features that might make me want to migrate some of my servers to guix.</p>
</div>
</div>
]]></content:encoded>
    </item>
    <item>
      <title>Guix Part 1: Install and Muse about GNU Guix</title>
      <link>https://linuxmaxxing.com/posts/09_guix/</link>
      <pubDate>Wed, 24 Jun 2026 00:00:00 +0000</pubDate>
      <guid>https://linuxmaxxing.com/posts/09_guix/</guid>
      <description>&lt;p&gt;&lt;em&gt;&lt;strong&gt;N.B.&lt;/strong&gt;&lt;/em&gt;: &lt;em&gt;Throughout this post I refer to Guix System Distribution simply&#xA;as Guix and NixOS as Nix. Understand that Guix and Nix ackshully refer&#xA;to the respective package managers which can be run on any&#xA;distro. Additionally I adopt &lt;a href=&#34;https://www.tonybtw.com/&#34;&gt;tony_btw&lt;/a&gt;&amp;rsquo;s&#xA;phrase of &amp;ldquo;legacy&amp;rdquo; distros to refer to GNU/Linux distros which are not&#xA;Guix System or NixOS.&lt;/em&gt;&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;hr&gt;&#xA;&lt;p&gt;Guix has been on my radar for a number of years now. I always viewed&#xA;it as an elite distro for a number of key reasons:&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><em><strong>N.B.</strong></em>: <em>Throughout this post I refer to Guix System Distribution simply
as Guix and NixOS as Nix. Understand that Guix and Nix ackshully refer
to the respective package managers which can be run on any
distro. Additionally I adopt <a href="https://www.tonybtw.com/">tony_btw</a>&rsquo;s
phrase of &ldquo;legacy&rdquo; distros to refer to GNU/Linux distros which are not
Guix System or NixOS.</em></p>
<hr>
<hr>
<p>Guix has been on my radar for a number of years now. I always viewed
it as an elite distro for a number of key reasons:</p>
<ol>
<li>It is a GNU project and an FSF-approved distro which means it meets
the Free System Distribution guidelines, meaning the distro will
work perfectly on a couple dual-core thinkpads and YMMV on all
other hardware. Harder and more limiting systems are always better.</li>
<li>It is source-based.</li>
<li>It is (was) rarely used in the wild. &ldquo;Neofetch flex potential&rdquo; as
it has been called. <sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup></li>
</ol>
<p>The main selling point of both Guix System and NixOS for the average user would be
the source-controlled configuration file which results in an easily
&ldquo;reproducible&rdquo; system.
I put reproducible in quotes because I don&rsquo;t care so much as whether
the system is technically reproducible - meaning exact binary copy
down to a hash - but more a system that has all the same packages and
configuration.</p>
<p>But I&rsquo;ve been able to make any distro &ldquo;reproducible&rdquo; by using shell
scripts and more recently ansible.
My ansible roles work extremely well for me on any arch or debian
derivative distro, or at least any derivative distro I would consider running.
Install a couple packages, run a quick playbook, add the device to my
tailnet, and then run another playbook that completely recreates my
workstation setup after 15 minutes or so.
There are other simpler roles I use on servers to also include alpine.</p>
<p>I bring up ansible only to say that at this point I don&rsquo;t have a &ldquo;need&rdquo;
for Guix System or NixOS insofar as they are fantastic tools for
reproducibility, roll-backs, snapshots, etc.
I get get all those features from &ldquo;legacy&rdquo; distros with btrfs
snapshots and ansible.</p>
<p>But that doesn&rsquo;t mean I&rsquo;m going to not try Guix and NixOS (well, maybe
not NixOS).
And more importantly it would be a mistake to believe Guix and Nix are
primarily systems for easily recreating your rice. That is just a nice touch.
The shells, containers, and deployment capabilities are the real
selling points of Guix and Nix IMHO, which for me are not that important as I have
zero issues using lxc and docker/podman for containers.</p>
<p>I say all of this as background to explain my perspective as a user
who is perfectly happy using normie GNU/linux tools. Inertia is a
thing, so even if the process of learning FHS linux, ansible, docker,
etc took significantly longer than learning Guix/Nix equivalents
would, I&rsquo;m already at the end-point. Anything different is probably
going to seem &ldquo;harder&rdquo; or &ldquo;complicated,&rdquo; and I don&rsquo;t think any Guix or
Nix enjoyer would describe those systems as simple or easy. So if I
come across as a Guix denier at any point in this post or other related ones
in the future, it&rsquo;s coming from a perspective that the other solutions
<em><strong>Just Werk</strong></em>™ for me at this time.</p>
<hr>
<h2 id="definitions">Definitions</h2>
<p>Like Nix, Guix has its own terminology for various things. Here are a
few important ones:</p>
<ol>
<li><a href="https://guix.gnu.org/cookbook/en/html_node/Channels.html">Channel</a>:</li>
</ol>
<blockquote>
<p>Guix and its package collection can be extended through channels. A
channel is a Git repository, public or not, containing .scm files that
provide packages or services.</p>
</blockquote>
<ul>
<li>I.e. software repository</li>
</ul>
<ol start="2">
<li><a href="https://guix.gnu.org/manual/1.5.0/en/html_node/Official-Substitute-Servers.html">Substitutes</a></li>
</ol>
<blockquote>
<p>Build farms that build packages from Guix continuously for some
architectures, and make them available as substitutes (binaries).</p>
</blockquote>
<ul>
<li>Similar to binary repositories on Gentoo.</li>
<li>Compiling from source is still the fallback.</li>
</ul>
<ol start="3">
<li><a href="https://gitlab.com/nonguix/nonguix">Nonguix</a></li>
</ol>
<blockquote>
<p>Nonguix is a software repository for the
GNU Guix package manager, which packages some software which cannot
be included in the official distribution for ethical or policy-related reasons.</p>
</blockquote>
<ol start="4">
<li>Generation</li>
</ol>
<ul>
<li>An instance of your Guix system at a given time.</li>
<li>Generations are created every time you regeneration your system for
the system configuration file.</li>
<li>Each generation can be booted from grub, giving you the
functionality of grub-btrfs on legacy distros regardless of file system.</li>
<li>New generations are created each time you boot into an older generation.</li>
</ul>
<hr>
<h2 id="known-challenges">Known Challenges</h2>
<p>Like all <a href="https://www.gnu.org/distros/free-distros.html">FSF-approved
distros</a> the Achilles'
heel of Guix is the inability to run proprietary software. It comes with
the linux-libre kernel which removes the proprietary firmware blobs
found in the mainline linux kernel. There&rsquo;s a lot of misleading tribal
knowledge about this on the internet, I figured my computers likely
would not even boot as a result. Whilst this may be true for some
machines, particularly new ones, this simply is not true for the
overwhelming majority of computers.
Your computer will boot fine and your graphics will function for at least
rendering screens unless it is a new card. The one thing won&rsquo;t have is
wifi. Honestly, not the end of the world.</p>
<h3 id="dont-talk-about-nonguix">Don&rsquo;t Talk about Nonguix</h3>
<p>That being said I fully intended to get wifi working using the
freedom-hating <a href="https://gitlab.com/nonguix/nonguix">nonguix
channel</a> which provides
both the mainline linux kernel and proprietary firmware which are
likely needed for your wifi.
Adding a channel in Guix is akin to adding a 3rd party repo in legacy distros.</p>
<p>Nonguix is like Fight Club: everybody knows about it and partakes, but
nobody talks about it in official Guix fora. A bit silly, but I
understand why and have become more and more FSF-aligned over time
despite its flaws and characters.</p>
<hr>
<h2 id="installation-prep">Installation Prep</h2>
<p>Before ever installing Guix System, I used the Guix package manager on
a so-called foreign distro, in my case it was Devuan GNU/Linux. So I
came in with some guix knowledge already. And consoomed System
Crafter&rsquo;s Guix vidyos which are good and still relevant.</p>
<p>I first installed Guix in VM, but after 20 minutes or so I decided to
just live dangerously and install it on bare metal. I gained nothing
of importance from installing in a VM other than knowing that Guix
does not set up btrfs subvolumes by default. More on that later.</p>
<h3 id="bare-metal-weapon-of-choice">Bare Metal Weapon of Choice</h3>
<p>In my stack of old corporate thinkpads I had an unallocated W541 and an
X230 running Artix GNU/Linux. The W541 has a 4th-gen i7 processor (4-core,
8-thread) and a whopping 4 RAM slots which I filled with a number of
DDR3 sticks I had laying around to get a total of 20GB. Plenty enough
for compiling for this cpu.</p>
<p>Despite having an NVIDIA Quadro K1100M
discrete graphics card, I chose the W541 over the X230 because of the
beefier processor since Guix is a source-based distro by
default. This computer also has an integrated graphics card, and from
my research the discrete GPU is old enough that it works fine with
nouveau drivers which are included in the linux-libre kernel. So for
the sake of getting a bootable and functioning system that can also
compile a kernel, the W541 works.</p>
<p>The wifi chip is also easily accessible and there likely is a linux-libre
compatible chip which I can use in the future.</p>
<h3 id="installation-media--nonguix">Installation Media &amp; Nonguix</h3>
<p>If you&rsquo;re absolutely set on having wifi working during installation,
you will need to use a nonguix ISO. The latest
<a href="https://gitlab.com/nonguix/nonguix/-/releases">official nonguix ISO</a> is
from 2022, though from vidyos it seems like there were more recent
images from 2024 which are no-longer on the gitlab. Whilst this is a
very minimal base system and the installer itself probably has not
changed, <em><strong>0/10 WOULD NOT RECOMMEND</strong></em> using a 4-year-old ISO.</p>
<p>For starters it is using Guix 1.4, a version behind the current 1.5 which
brought major changes to the package manager. It probably also
still references the old, slow GNU Savannah channel which
Guix used to be hosted on.
Guix is now on
<a href="https://codeberg.org/guix">codeberg</a> which is a significantly faster
channel. Aside from that you probably don&rsquo;t need me to explain why
using an iso that old is probably a bad idea.</p>
<p>System Crafters used to publish their own nonguix iso on their
<a href="https://github.com/SystemCrafters/guix-installer/releases/tag/v202503220148">github</a>. The
community has since moved to
<a href="https://codeberg.org/SystemCrafters">codeberg</a> and no longer
publishes custom Guix ISOs. My guess is due to codeberg limitations.</p>
<p>You can also generate your own nonguix iso image on any system with
the Guix package manager installed. Instructions are provided on the
<a href="https://gitlab.com/nonguix/nonguix#installation-image">nonguix
gitlab</a>. Keep
in mind this compiles an iso, so expect around an hour. I have not
verified how well this works or if there are any gotchas with this
method, though an <a href="https://joshblais.com/">unnamed friend</a> may or may
not have had issues with this until finally conquering.</p>
<p>I chose to use the official GNU Guix ISO over ethernet and add the
nonguix channel later. If your system boots the
linux-libre kernel - which you should know based on the ISO booting or
not - it is a simple enough process to just add the nonguix channel
after installation. You can even add the nonguix channel during
installation via ssh, see <a href="https://youtu.be/p1w8dwHxFnk">Thanos Apollo&rsquo;s Guix Installation
video</a> for how that can be done.</p>
<h3 id="official-iso-issues">Official ISO Issues</h3>
<p>There are two flavors of the official Guix iso:
<a href="https://guix.gnu.org/en/download/">standard</a> and latest. At the time
of this post the standard ISO is from January, 2026, so I knew going
it that I would basically be pulling the entire system with this
ISO.</p>
<p>There is additionally a latest ISO which should be a weekly build.</p>
<p>Both are direct downloads, I could not find any torrent links.</p>
<p>There are issues with both of these though. The latest official ISO
only includes a gpg signature file. No sha256 or sha512 hash. The
latest ISO includes <em>neither</em> a gpg signature <em>nor</em> hash. <strong>This is
unacceptable.</strong></p>
<p>Since I still like to live a bit dangerously, I was fine with
signature verification of the standard ISO, but I would not recommend
using the latest ISO unless you like to <code>curl | sh</code> your entire
operating system.</p>
<hr>
<h2 id="guix-installation">Guix Installation</h2>
<p>There are several videos running through a Guix installation,
<a href="https://youtu.be/3mbCH7sBLeI">tony_btw</a>&rsquo;s shows a cli install per the
Guix Reference Manual.
This is honestly one of the more straightforward cli installs out there.</p>
<p>I opted to go the graphical/tui route as I value ease and
reproducibility of installation. I was more curious how sane the
defaults were, and when I choose a distro for long-term use I will not
choose one that requires a bunch of cli nursing and a handbook to
install. It&rsquo;s just not worth my time, I want something I can
mindlessly install to get back up and running as quickly as possible.</p>
<p>Let me tell you that the Guix tui installer is fantastic, up there
with the MX Linux gui installer as my favorites.</p>
<h3 id="encryption">Encryption</h3>
<p>Guix by default uses true Full-Disk encryption save the EFI system
partition with GPT partition tables. From what I understand this is only
possible (or more consistent) with the older LUKS1 encryption vs the
newer LUKS2 which generally requires an un-encrypted /boot. LUKS2 with
un-encrypted /boot is the
default on Debian where an encrypted /boot installation will fail from within the
tui installer. I generally prefer an encrypted boot if possible and
convenient. Of course it&rsquo;s always possible from the cli.</p>
<h4 id="btrfs-snapshots-boot--encryption">Btrfs Snapshots, /boot, &amp; Encryption</h4>
<p>This is not an issues on Guix, but on legacy distros using btrfs
snapshots for roll-backs, an un-encrypted boot partition can bite you
if your initramfs gets corrupted or significantly differs from the
installed kernel. For instance if you&rsquo;re on arch where there are only
two officially supported kernels and want to restore an old btrfs
snapshot, it probably will not boot as the kernels on the snapshot
could be completely different kernels. You would need to chroot from
an iso or boot into the snapshot from grub, regenerate initramfs, and modify the
btrfs root subvolume name to point to the actual root subvolume and not the
btrfs snapshot you&rsquo;re booted in. It potentially becomes messy and
could render your /boot unrecoverable without a usb chroot.</p>
<p>So on legacy systems with encryption and btrfs, encrypted /boot is
always preferred as the /boot partition is included in the btrfs root snapshot.</p>
<h3 id="file-systems">File Systems</h3>
<p>On the VM I installed btrfs which included zero btrfs subvolumes. My
initial strategy was to use btrfs snapshots to have restorable backups
even if I garbage-collect (prune) my Guix system. Not having
subvolumes makes this impossible without the cli installer.</p>
<p>As I thought about it though, btrfs snapshots offer you absolutely nothing on a
Guix system. Btrfs snapshots are incremental, so on a legacy distro
each snapshot references the previous snapshot and adds/removes packages
as appropriate. This works because the packages/files are installed in the
same place just with different timestamps and/or versions.</p>
<p>On Guix and Nix, upgraded packages are stored in a completely different locations
and are just symlinked to the appropriate place is the system or user
path. As far as I know btrfs would have no way of identifying these as
the same package since they are in completely different folders, which
means you probably gain zero incremental benefits. So whether you are using
btrfs snapshots or Guix generations, it probably makes no difference, the same
amount of space exists on disk. This is probably why grub-btrfs is not
included in otherwise massive nix package repo.</p>
<p>Further, to roll-back using btrfs you
must restore and reboot the system, while Guix can roll back in
real-time using <code>guix system roll-back</code> without reboot.</p>
<p>So as far as I can tell there
is zero upside to using btrfs snapshots and only downside considering
installation complexity. Additionally if you have both btrfs snapshots
and generations, you are effectively saving the same packages multiple
times, taking up more disk space which I imagine can be
precious on Guix and Nix.</p>
<p>So why choose btrfs? Compression, copy-on-write, and data integrity
features.</p>
<p>For this install I chose the default ext4 on a 500gb drive,
and depending on how much space I have after transferring my /home
folder over and keeping a couple months of generations, I may
re-evaluated switching to btrfs for the compression benefits which are
not insignificant.</p>
<h3 id="substitutes">Substitutes</h3>
<p>You&rsquo;ll want to enable substitutes during installation. It&rsquo;s a long
process regardless, but substitutes will insure installation takes
under an hour. Speed is a weakness of Guix unfortunately, but keep in
mind it was a source-based distro for a number of years. Substitutes
are secondary. If a substitute server does not have the binary, it
will be built from source. That being said I would say around 80% of
the packages installed were from binary substitutes, and most of the
compiled programs were small anyway. I haven&rsquo;t looked in detail but I
imagine Guix is selective as to which packages even make it to substitute.</p>
<h3 id="desktops">Desktops</h3>
<p>Guix includes a few desktop environments and window managers, I opted
for XFCE as that is my go-to on all systems as a fallback.</p>
<hr>
<h2 id="post-install">Post-Install</h2>
<h3 id="moving-etcconfigscm">Moving /etc/config.scm</h3>
<p>I kept the default <code>/etc/config.scm</code> file generated by the
installer. Whilst I could have modified it at this point, I really
wanted to experience default Guix before I go-a-ricing. Additionally
my plan was to copy the system config.scm for modifications, leaving the
original one intact at <code>/etc/config.scm</code>.</p>
<p>Tony directly edits <code>/etc/config.scm</code> to install packages and services in his guide.
This works, but you miss out out version controlling your config file.
Instead I would recommend leaving the default <code>config.scm</code> as is and copying it to a
folder of your choosing where you can add it to git.
It can be anywhere. I chose <code>~/.config/guix/config.scm</code>.</p>
<h3 id="adding-nonguix">Adding nonguix</h3>
<p>The instructions for adding the nonguix channel are
straightforward.</p>
<p>Make sure you add the nonguix channel in a <code>channels.scm</code> file:</p>





<pre tabindex="0"><code>(cons* (channel
        (name &#39;nonguix)
        (url &#34;https://gitlab.com/nonguix/nonguix&#34;)
        ;; Enable signature verification:
        (introduction
         (make-channel-introduction
          &#34;897c1a470da759236cc11798f4e0a5f7d4d59fbc&#34;
          (openpgp-fingerprint
           &#34;2A39 3FFF 68F4 EF7A 3D29  12AF 6F51 20A0 22FB B2D5&#34;))))
       %default-channels)</code></pre><p><code>~/.config/guix/channels.scm</code> is a good place for this.</p>
<p>One thing you&rsquo;ll want to do is add the nonguix
substitute server. The
<a href="https://gitlab.com/nonguix/nonguix#substitutes-for-nonguix">instructions</a>
are clear enough, but the code block included will conflict somewhat
with the default <code>(services ...)</code> block in <code>/etc/config.scm</code></p>
<p>Here is the default <code>(services ...)</code> block in <code>/etc/config.scm</code>
after an XFCE installation.</p>





<pre tabindex="0"><code>(services
 (append (list (service xfce-desktop-service-type)
               (service openssh-service-type)
               (set-xorg-configuration
                (xorg-configuration (keyboard-layout keyboard-layout))))
         ;; This is the default list of services we are appending to.
         %desktop-services))</code></pre><p>And here is what nonguix provides:</p>





<pre tabindex="0"><code>(services (modify-services %desktop-services
           (guix-service-type config =&gt; (guix-configuration
             (inherit config)
             (substitute-urls
              (append (list &#34;https://substitutes.nonguix.org&#34;)
                %default-substitute-urls))
             (authorized-keys
              (append (list (local-file &#34;./signing-key.pub&#34;))
                %default-authorized-guix-keys))))))</code></pre><p>Crystal clear, right? Not going to get into the weeds of scheme here,
but defining services beginning with <code>append</code> and then later
<code>modify-services</code> is not the cleanest approach.</p>
<p>Instead I borrowed what is done on a default base Guix installation
(no desktop) and use <code>cons*</code> to add elements to a list rather than use <code>append</code>
which concatenates lists.</p>
<p>This:</p>





<pre tabindex="0"><code>(services
 (append (list (service xfce-desktop-service-type)
               (service openssh-service-type)
         %desktop-services))</code></pre><p>Is functionally equivalent to</p>





<pre tabindex="0"><code>(services
 (cons* (service xfce-desktop-service-type)
        (service openssh-service-type)
        %desktop-services))</code></pre><p>In both cases we are adding two services to <code>desktop-services</code> which
exists by default on the system.</p>
<p>The difference is we can directly pass <code>(modify-services ...)</code> in the <code>(cons* ...)</code>
block, wheres it would have to be a list in order to include it in the
<code>(append ...)</code> block.</p>
<p>Here&rsquo;s what I ended up with:</p>





<pre tabindex="0"><code> (services (cons* (service xfce-desktop-service-type)
                  (service gnome-keyring-service-type)
                  (service nix-service-type)
                  tailscale-service

                  (modify-services
                   %desktop-services
                   (guix-service-type config =&gt;
                                      (guix-configuration
                                       (inherit config)
                                       (substitute-urls
                                        (append
                                         (list &#34;https://substitutes.nonguix.org&#34;)
                                         %default-substitute-urls))
                                       (authorized-keys
                                        (append
                                         (list
                                          (local-file
                                           &#34;./signing-key.pub&#34;))
                                         %default-authorized-guix-keys)))))))</code></pre><p>Then just change the location of <code>signing-key.pub</code> to a file location
of your choosing. I chose <code>~/.config/guix/nonguix.pub</code>. You can find
the contents for this key file <a href="https://substitutes.nonguix.org/signing-key.pub">here</a>.</p>
<p>Per nonguix instructions:</p>
<blockquote>
<p>Guix System will only use the substitution server after it has been
reconfigured.  The substitution server will therefore by default not
be used the first time you run guix system reconfigure after adding
the substitution server.  It is therefore recommended to explicitly
specify the use of the substitution server the first time
you reconfigure your system:</p>
</blockquote>





<pre tabindex="0"><code>sudo guix archive --authorize &lt; signing-key.pub
sudo guix system reconfigure ~/.config/home/config.scm \
--substitute-urls=&#39;https://ci.guix.gnu.org \
https://bordeaux.guix.gnu.org https://substitutes.nonguix.org&#39;</code></pre><p>Just be sure to put the proper location of <code>config.scm</code> for your
system.</p>
<h4 id="adding-the-non-libre-linux-kernel-and-firmware">Adding the non-libre Linux Kernel and Firmware</h4>
<p>Add the following to <code>config.scm</code>:</p>





<pre tabindex="0"><code>(use-modules
    ...
    (nongnu packages linux)
    (nongnu system linux-initrd)
    ...
    )
...

(operating-system
  ...
 (kernel linux-lts)
 (initrd microcode-initrd)
 (firmware (list linux-firmware))
 ...
 )</code></pre><p>Then run:</p>





<pre tabindex="0"><code>sudo guix system reconfigure ~/.config/guix/config.scm</code></pre><p>And you will begin pulling the binary linux-lts kernel (assuming the
latest build exists, if not it will be source) and linux
firmware. After rebooting you should have working wifi.</p>
<p>Notice I have also added a nix service and tailscale service. The nix
service is <a href="https://guix.gnu.org/manual/1.5.0/en/html_node/Miscellaneous-Services.html">provided by
Guix</a>.</p>
<p>The tailscale service is a module I created with tailscale installed from
nix. You can additionally find guix channels to install tailscale.</p>
<hr>
<h2 id="profiles">Profiles</h2>
<h3 id="system-profile">System Profile</h3>
<p>Now is a good time to mention profiles. By default you have a system
profile and a user profile. When you add software to <code>config.scm</code> and
run:</p>





<pre tabindex="0"><code>sudo guix system reconfigure ~/.config/guix/config.scm</code></pre><p>(substituting your file location), you are revising your system
profile. Any packages installed will be installed to the system profile. The
default path for executable files installed to your system profile is:</p>
<p><code>/run/current-system/profile/bin</code></p>
<p>Running <code>guix install &lt;package&gt;</code> as root (or with sudo) installs that <code>&lt;package&gt;</code> to your system
profile.</p>
<p>There are certain packages you might want in your system profile, for
instance desktop environments and system services, but most software
should not be installed in your system profile, whether that is
installed via <code>sudo guix install</code> or defined in <code>config.scm</code>.</p>
<h3 id="user-profile">User Profile</h3>
<p>Software installed via <code>guix install &lt;package&gt;</code> will be installed to
your user profile located at:</p>
<p><code>~/.guix-profile/bin</code></p>
<p>In general, do not
install software this way. Not that it is bad or wrong, it just
doesn&rsquo;t get you anything beneficial.</p>
<p>Instead, use Guix Home.</p>
<h3 id="home-profile--guix-home">Home Profile / Guix Home</h3>
<p>Guix Home is akin to NixOS home-manager except it is also a
profile and parallels your system configuration. A default home
configuration file is located at <code>~/guix-home-config.scm</code>. Once
again I recommend making a copy of this file and placing it in a
convenient place, and keeping the original saved.
I chose <code>~/.config/guix/home/home-config.scm</code>. Add
packages to this file in a similar manner to <code>config.scm</code>, and update
your home profile by running:</p>





<pre tabindex="0"><code>guix home reconfigure ~/.config/guix/home/home-config.scm</code></pre><p>What is the advantage of this? You have all the same generational
features of your Guix system, just with your home profile. Removing a
package is done by simple removing it from <code>home-config.scm</code>. Your
configuration can also become modular which is what I intend to do. In
this way your <code>home-config.scm</code> and related modules are your source of
truth as to what is installed on your system, not whatever happens to
be in <code>~/.guix-profile/bin</code> which you installed by <code>guix install &lt;package&gt;</code>.</p>
<p>There&rsquo;s a ton more to say about Guix Home but for now I&rsquo;m pretty much just using
it to install packages.</p>
<hr>
<h2 id="installing-software">Installing software</h2>
<p>There is very little included at first, frustratingly so at times.
For instance the <code>clear</code> command is not included and needs to be installed using
the <code>ncurses</code> package.</p>
<p>At a minimum you will need to add the appropriate package module and
package name to the respective sections of your home config
file. There are multiple ways of doing this depending on if you are
using a modularized configuration or not. The default
<code>guix-home-config.scm</code> file is modular which you may or may not want
to immediately use. I would recommend starting from scratch at first,
so keep a copy of the default file and then make your own in a more
simple format.</p>
<p>Here&rsquo;s an example for installing emacs, emacs-guix, and ncurses packages:</p>





<pre tabindex="0"><code>(use-modules
  (gnu home)
  (gnu home services)
  (gnu packages)
  (gnu packages emacs)
  (gnu packages emacs-xyz)
  (gnu packages ncurses))

(home-environment
  (packages
    (list
     emacs
     emacs-guix
     ncurses)))</code></pre><p><code>emacs-guix</code> is a fantastic way to manage your Guix system. It is
extremely useful for searching for packages, much quicker than <code>guix search &lt;package&gt;</code>.</p>
<p>You&rsquo;ll need the <code>location</code> item from <code>guix search &lt;package&gt;</code>, for
example:</p>





<pre tabindex="0"><code>guix search emacs-guix

name: emacs-guix
version: 0.6.1
...
location: gnu/packages/emacs-xyz.scm:8355:2
...</code></pre><p>This location is simply the folder structure of the Guix git repo, and
<code>emacs-xyz</code> is the guile scheme module which includes <code>emacs-guix</code>.
Add <code>emacs-xyz</code> to <code>(use-modules ...)</code> and you&rsquo;ll now have that module
loaded.
Add <code>emacs-guix</code> to your package list and guix home will install
<code>emacs-guix</code> from the <code>emacs-xyz</code> scheme module.</p>
<p>Pretty much everything in Guix follows this format. If we look the
<code>config.scm</code> section above which installed the kernel and firmware
from nonguix, notice how the modules were in the nongnu folder
(channel), not the default gnu channel.</p>
<p>For more information on a modularized configuration, see the Guix
Reference Manual and <a href="https://youtu.be/PGGvoabfvkM">System Crafters
video</a></p>
<hr>
<h2 id="to-be-continued">To be Continued</h2>
<p>At this point I have a Guix system running the mainline linux-lts
kernel, functioning wifi, the XFCE desktop, with some
packages installed in my home profile, and quite a bit more that I&rsquo;ll
save for another post. For me this is the minimum
viable product, I would be perfectly happy living in XFCE. In my next
post I&rsquo;ll go through what I&rsquo;ve done to modify my desktop setup,
install suckless software, copy over (and subsequently modify) my
dotfiles, and the successes and failures I&rsquo;ve had in the process.</p>
<p>Things don&rsquo;t always <strong>Just Werk</strong>™ on Guix, for instance after
writing this post and installing hugo from nonguix, hugo is not
rendering the page at all. So add that to the list of things to
troubleshoot. But, once the troubleshooting is done, everything is
documented in a file and I&rsquo;m sure Guix will at least be just as usable as any
other distro. I&rsquo;m just doing my best to enjoy the journey of getting there.</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p><a href="https://youtu.be/3mbCH7sBLeI">video</a>&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded>
    </item>
  </channel>
</rss>
