Published on 2023-10-23
Edited on 2023-10-24
The most important part of my Nix configuration: nix home manager.
From packages installed, services enabled, configuration copied or generated, home manager is where the Linux “customization” happens.
Lets make this simple, my primary flake is my dotfile configuration.
No matter the setup, both Nix and Guix rely on the source control to make sure the packages are reproducible. When you pull on sync your channels, Guix (or Nix) “pull” changes to a local copy of the repository.
In functional expression, a flake derivation would look like this:
f(pinnedInputs, configuration) = configDerivation
where pinnedInputs are the channel + commit hash
for each flake (channel) specified and stored in git.
This makes the configuration flake, a function of it’s input. It’s reproducible, there are no external dependencies.
In Guix, the pinnedInputs exists, but are external and kind of invisible to the user. They represent your last “pull” command, nothing more. It’s place sensitive and not captured anywhere but on your local machine.
Without this critical information, re-installing the configuration will produce different results, unless Guix (or Nix) did not change since last time you did it.
For example, last time I migrated to Guix, using my previous migration’s configuration, I could not get chezmoi dotfile manager to work. It failed to build between the time I left Guix and the time I re-installed Guix. I had spend time figuring out when the build started to fail, and wasted time getting my system up to date.
The solution for this is to store both the channels used by the configuration as well as the git hash versions of each channels. When they are in your repository, you have a lot more chance to get a working system, especially after some time. It also make it super easy to upgrade one channel while keeping an older version of another one by just undoing your changes using git.
When you are a coder, this is super natural to do. Many of the development tools actually have similar mechanism (like npm’s package.lock).
Guix does not have an off the shelf pinning system, but has some commands to support similar
workflow: describe
and time-machine
.
On any Guix system, if you run guix describe --format channels
, you get the same info as your
channel file, but with the specific git hash from the latest guix pull. We could store this output
into a file in our configuration git repo for later reference.
The 2nd useful command is guix time-machine
. It allows you to run a Guix command for a specific
version. There are many ways to specify the version, one of which is a channels file. We can use the
output of guix describe to run guix pull at a specific version using guix time-machine.
The is the closest we can get from Nix flakes.
The main limitation is that Nix flakes tracks inputs of inputs, while guix describe/time-machine will only track your immediate channels specifications.
This is the same mechanism that RDE uses (look at their setup here).
Here is an inventory of all the software I use, except for anything related to nix home-manager (programs and services).
I’m been using whereiseveryone’s toy search engine. It index Guix main channel, but also many other 3rd party channels. The search engine is not just more complete, it’s also much faster than Guix packages web search engine.
In my case, most will come from Guix’s channel, some from NonGuix, and the rest from my own channel.
Note: before installing any software from 3rd party channels, it’s always advised to inspect the Guix package code, and even better, inspect and replicate some of them into your own channel. You should not leave security to luck. Since I only have couple of packages in unknown 3rd party channels, I’ll inspire myself and update my own channel.
nix | guix ([channel#]<package>[:output]) | comment |
---|---|---|
babashka | bin-guix#babashka | issue is graalvm not in Guix due to reproducibility |
bat | = | |
bash-completion | = | |
coreutils | = | |
dosfstools | = | dos partitioning/formatting tools |
lesspipe | = | |
missing, abandon | I dont really need it | |
starship | th#starship-bin | This could go in Guix, but really a lot of dependencies |
nix | guix ([channel#]<package>[:output]) | comment |
---|---|---|
bluez | = | |
bluez-alsa | = | |
bind | bind:utils | I use the lookup tools |
curl | = | |
openssl | = | |
rsync | = | |
sshfs | = | |
surfraw | = | |
abandon | I dont use this anymore | |
wget | = |
nix | guix ([channel#]<package>[:output]) | comment |
---|---|---|
(aspellWithDicts (dicts: with dicts; [ en en-computers en-science fr])) | aspell, aspell-dict-en, aspell-dict-fr | Note en-computers and en-science in kbg |
kbg#aspell-dict-en-computers, kbg#aspell-dict-en-science | Note2: aspellWithDicts equivalent? | |
abandon | file archive manager I dont use | |
beancount | = | |
bsdgames | bsd-games | |
cowsay | = | |
abandon | I dont use this | |
dos2unix | = | |
diffutils | = | diff, cmp, diff3 |
fd | = | find replacement |
figlet | = | banner tools-extra |
findutils | = | find, locate commands |
fzf | = | |
gawk | = | |
gnuplot | = | |
gzip | = | |
highlight | = | |
jet | missing, nixpkgs | like jq, but include transit and edn |
jq | = | |
ledger | = | |
mediainfo | = | |
p7zip | = | |
pandoc | = | |
pbzip2 | = | # multi core replacement for bzip2/bunzip2 |
recutils | = | |
ripgrep | = | |
tree | = | |
texlive.combined.scheme-full | texlive | |
-> p7zip | ||
unzip | = | |
wordnet | = | |
zip | = |
nix | guix | comment |
---|---|---|
acpi | = | |
htop | = | |
lsof | = | |
progress | = | |
pv | = | pipe progress monitor |
strace | = | |
sysstat | = |
nix | guix | comment |
---|---|---|
alsa-plugins | = | |
missing, abandon | I’m not sure I actually use this | |
alsa-utils | = | |
missing, abandon | not found but don’t use | |
ffmpeg | = | |
gst_all_1.gst-plugins-base | gst-plugins-base | |
gst_all_1.gst-plugins-good | gst-plugins-good | |
gst_all_1.gst-plugins-bad | gst-plugins-bad | |
gst_all_1.gst-plugins-ugly | gst-plugins-ugly | |
gst_all_1.gstreamer | gstreamer | |
imagemagick | = | |
mpv | = | |
pulsemixer | = | |
pamixer | = | |
sox | = | |
vorbis-tools | = |
nix | guix | comment |
---|---|---|
keychain | = | great tool to share ssh/gpg agents within a session |
gnupg | = | |
pass | password-store | |
pinentry | = |
nix | guix | comment |
---|---|---|
missing, abandon | I used this for some of my servers. I have a diff solution now | |
docker-compose | docker, docker-cli, docker-compose | Unclear if compose is needed as it’s supported in cli on new versions |
vagrant | missing, nixpkgs | I would want to use that to provision my work VMs |
nix | guix | comment |
---|---|---|
ansible | = | |
autoconf | = | |
automake | = | |
binutils | = | ld and similar tools |
black | python-black | python code formatter |
cargo | = | |
clj-kondo | nonguix#clj-kondo | clojure linter |
clojure | clojure, clojure-tools | this is new. was not in Guix if I recall |
clojure-lsp | missing, nixpkgs | could not find. self package? |
cmake | = | |
editorconfig-core-c | = | |
gcc | = | |
gh | ffab#github-cli | |
ghc | = | |
gitFull | git:out,send-email,gui | |
git-annex | = | |
N/A | ||
git-extras | missing, wait | lots of cool features. Maybe there is an emacs similar package. some are covered by magit |
-> github-cli | ||
abandon | I use magit | |
gitstats | magit-stats | |
gnumake | make | |
go | = | |
gopls | = | go language server |
graphviz | = | |
html-tidy | missing, nixpkgs | |
jdk17 | openjdk | 21 is also available |
jetbrains.idea-ultimate | small-guix#idea-ultimate | |
leiningen | nonguix#leiningen | |
libtool | = | |
maven | = | |
google-java-format | missing, nixpkgs | cli java formatter |
mdl | missing, nixpkgs | markdown linter |
mr | myrepos | |
nodejs | node | latest lts available (18) |
nodePackages.stylelint | -> node-eslint | |
nodePackages.js-beautify | missing, -> npm prettier | replace with prettier from npm? |
nixfmt | from nix package mgr | |
plantuml | = | |
pipenv | missing, wait | |
pyenv | missing, wait | |
python3 | python | |
python-lsp-server | = | |
python beautifulsoup4 | python-beautifulsoup4 | |
python flake8 | python-flake8 | |
python isort | python-isort | |
python lxml | python-lxml | |
python mypy | python-mypy | |
python nose | python-nose | |
python pillow | python-pillow | |
python pyflakes | python-pyflakes | |
python pylint | python-pylint | |
python pynacl | python-pynacl | |
python pytest | python-pytest | |
python pyright | missing, abandon | some extra linting, not critical |
python pypdf2 | python-pypdf2 | |
python terraform | = | |
python tldextract | python-tldextract | |
proselint | python-proselint | |
ruby | = | |
rustc | rust | |
sbcl | = | |
shellcheck | = | |
shfmt | missing, nixpkgs | |
sqlite | = | |
vscode-fhs | missing, wait | it’s a wrapper that allows to install vscode plugin normally |
is vscodium doing the same? |
Tools I use only on my personal laptop
nix | guix ([channel#]<package>[:output]) | comment |
---|---|---|
borgbackup | borg | |
borgmatic | = | |
-> rbw | ||
-> rbw | ||
hugo | rosental#hugo-bin | |
rbw | = | bitwarden client |
rofi-rbw | missing, nixpkgs | rofi frontend. easy to package |
syncthing | = | |
transmission | = | |
yt-dlp | = | |
yubikey-manager | python-yubikey-manager | |
beancount | = | |
beancount-language-server | missing, nixpkgs | |
fava | missing, nixpkgs | |
hledger | = | |
abandon | ||
profanity | = | |
kicad | = | |
qmk | missing, git clone | I may be able to clone qmk instead |
abcde | = | |
beets | = | |
cdrdao | = | |
cdparanoia | = | |
cddiscid | missing, nixpkgs | |
chromaprint | = | |
dr14_tmeter | missing, nixpkgs | |
flac | = | |
fluidsynth | = | |
mopidy | missing, wait | |
mopidy-local | missing, wait | |
#mopidy-spotify | missing, wait | |
mopidy-somafm | missing, wait | |
mopidy-mpd | missing, wait | |
mopidy-iris | missing, wait | |
#mopidy-internetarchive | missing, wait | |
mpc_cli | mpd-mpc | |
mpd | = | |
ncmpcpp | = | |
ncspot | missing, nixpkgs | |
opusTools | opus-tools | |
python39Packages.pyacoustid | missing, wait | |
python39Packages.requests | python-requests | |
rubberband | = | |
sox | = | |
spotifyd | missing, wait | |
spotify-tui | missing, wait | |
twolame | = | |
wavegain | missing, wait |
When missing, i’ll just use the nix package instead until I do something else about it.
nix | guix ([channel#]<package>[:output]) | comment |
---|---|---|
awscli2 | awscli | |
azure-cli | missing, nixpkgs |
nix | guix ([channel#]<package>[:output]) | comment |
---|---|---|
alacritty | = | |
arandr | = | |
autorandr | = | |
brightnessctl | = | |
cantarell-fonts | font-abattis-cantarell | |
dunst | = | |
fontconfig | = | |
dejavu_fonts | font-dejavu | |
dwm | mychannel#bmj-dwm | |
feh | = | |
firefox | nonguix#firefox | |
gimp | = | |
libnotify | = | |
libreoffice | = | |
light | = | |
missing, abandon | use emerge, or other diff tools | |
maim | = | |
mate.mate-polkit | mate-polkit | |
mpv | mpv | |
-> zathura | ||
nerdfonts CascadiaCode | mychannel | |
nerdfonts FiraCode | mychannel | |
nerdfonts Hack | mychannel | |
picom | = | |
missing, abandon | ||
qutebrowser | nixpkgs | guix has a build that don’t work for me |
rofi | = | |
-> maim | ||
st | mychannel#bmj-st | |
sxiv | = | |
tesseract4 | tesseract, tesseract-* | I dont need this now |
widevine-cdm | missing, nixpkgs | needed for qute |
wmctrl | = | |
xclip | = | |
xdg-utils | = | |
xdg-user-dirs | = | |
xdotool | = | |
xdragon | dragon-drop | |
xlockmore | = | |
xorg.setxkbmap | xkbset? | |
xorg.xev | xev | |
xorg.xinput | xinput | |
xorg.xrandr | xrandr | |
xorg.xrdb | xrdb | |
xorg.xset | xset | |
xsel | xsel | |
zathura | zathura, zathura-* |
My program.*
and services.*
nix configuration -> service-types
mapping.
For comments, use email or Mastodon
Don't forget to subscribe to my RSS feed!