¶Intro
Don’t you hate it when you spend a lot of time configuring the tools you use for your personal workflow on Linux and then later have to figure out how to replicate it all on another machine?
How about when you install an update to your window manager or some other program and you can’t seem to log back in to your desktop environment?
In this video I’m going to show you the quickest way to start using Guix Home to manage the chaos of your personal computing configuration. I’ll explain a little bit about how it works and then I’ll walk you through a basic home-environment configuration so that you can get started with it quickly.
Let’s get started!
¶Understanding Guix Home
Guix Home is a feature of GNU Guix which makes it possible to install and apply configurations for the tools you use in your day to day computing workflow.
It uses the same configuration model as Guix System but applied to your $HOME folder instead of the entire system.
Here’s an example of a basic home-environment configuration file named home-config.scm which installs a couple of programs and configures Bash with a few useful settings:
(use-modules (gnu)
(gnu home)
(gnu home services shells))
(home-environment
(packages (specifications->packages
(list "git"
"emacs-no-x-toolkit")))
(services (list (service home-bash-service-type
(home-bash-configuration
(environment-variables '(("PS1" . "\\[\\e[1;32m\\]\\u \\[\\e[1;34m\\]\\w \\[\\e[0m\\]λ ")
("EDITOR" . "emacsclient")))
(aliases '(("gs" . "git status"))))))))
Let’s walk through this line by line:
The use-modules expression imports a number of modules that provide packages and services that we’ll use in this home configuration. The Guix manual pages will tell you which module you need to import to use each service type.
home-environment is the actual configuration expression that gets evaluated when guix home reads this file. You will most often deal with the two primary fields, packages and services.
The packages field expects a list of packages for software to be installed in your home folder. We’re using the specifications->packages procedure in this case to pass a list of strings representing Guix packages so that it returns the corresponding package definitions. We’ll talk more about this in a later video!
The services field expects a list of home services with their associated configurations. In this case, we’re including the home-bash-service-type which accepts a home-bash-configuration to customize various aspects of Bash across its own configuration files.
The home-bash-configuration expression is used here to set a couple of environment-variables and aliases in the resulting ~/.bash_profile and ~/.bashrc files. More details and configuration fields can be found in the Guix manual.
¶What is a service?
A quick side note on Guix services:
A “service” in Guix is not simply a program that runs in the background like in most Linux systems. It is actually the mechanism for applying a number of things to your system or home configuration:
- Placing configuration files needed by the associated program
- Installing packages to enable the configuration to operate
- Creating special user accounts or other system-level configuration
- Optionally configuring background services to run at the system or user level
We’ll cover services in more detail in a future video, including writing your own home services!
¶Testing the Configuration
Now that we’ve got this configuration ready, it’d be great to test it out without breaking our current home folder setup. Luckily Guix Home provides us with the guix home container command to see the final result configured in a temporary container environment!
Let’s test out this configuration:
guix home container ~/dotfiles/config/home/home-config.scm
Once the new configuration is built, we will immediately be dropped into a Bash shell in the container environment. The custom Bash prompt and aliases we configured are already active and emacs is available on the $PATH.
If we run a quick ls command, we’ll be able to see the .bash_profile and .bashrc files that were generated for us by home-bash-profile-service:
crafter ~ λ ls -al total 0 drwxr-xr-x 5 crafter users 180 Nov 1 09:19 ./ drwxr-xr-x 3 crafter users 60 Nov 1 09:19 ../ lrwxrwxrwx 1 crafter users 56 Nov 1 09:19 .bash_profile -> /gnu/store/g779bp3xz2ipyy2pld1vxkdi6vizs39c-bash_profile lrwxrwxrwx 1 crafter users 50 Nov 1 09:19 .bashrc -> /gnu/store/5dvm2bfwfwan5hsaxl1icqkmbf0wmjf0-bashrc drwxr-xr-x 2 crafter users 40 Nov 1 09:19 .cache/ drwxr-xr-x 3 crafter users 60 Nov 1 09:19 .config/ lrwxrwxrwx 1 crafter users 48 Nov 1 09:19 .guix-home -> /gnu/store/0jg05s4gxf5ynqrrqkc75w3hr0qvwi2k-home drwxr-xr-x 4 crafter users 80 Nov 1 09:19 .local/ lrwxrwxrwx 1 crafter users 57 Nov 1 09:19 .profile -> /gnu/store/nqribhmgwcmd8fgblwkcsi1x4wsy2m1h-shell-profile
These generated files are actually symbolic links into the /gnu/store path which is where Guix keeps all of the configuration files it generates before linking them into your $HOME folder. We’ll talk more about this a bit later in the video.
¶Applying the Configuration
Once you’ve inspected the $HOME folder inside of the container and tested that the appropriate programs are installed, it’s now time to apply the configuration to your actual home folder!
To do this, we use the guix home reconfigure command:
guix home reconfigure ~/dotfiles/config/home/home-config.scm
After this command completes, your home folder will be updated with the result of building your home-environment configuration!
But wait, what if guix home had to overwrite files that already existed in your $HOME folder like Bash configuration files?
Don’t worry, if any existing configuration files get replaced, they will be stashed away in one of the <timestamp>-guix-home-legacy-configs-backup folders that get created in your $HOME folder.
crafter ~ λ ls -al 1730454615-guix-home-legacy-configs-backup/ total 16 drwxr-xr-x 2 crafter users 4096 Nov 1 11:50 ./ drwx------ 8 crafter users 4096 Nov 1 12:48 ../ -rw-r--r-- 1 crafter users 447 Nov 1 11:02 .bash_profile -rw-r--r-- 1 crafter users 719 Nov 1 11:02 .bashrc
This gives you an opportunity to back these old files up or figure out how to integrate the needed parts into your Guix Home configuration so that they get applied in the future.
These folders are not needed by Guix Home, they just contain any files that had to be replaced with your new configuration. If you don’t need the replaced files anymore, you can just delete these folders to clear away the cruft.
¶Migrating Your Existing Configuration
Now you’re probably thinking “well this looks great, but what about all of the configuration files that I’ve hand-crafted over the years?”
Luckily, Guix Home provides a solution for integrating your existing configuration files into your new home-environment configuration, the home-dotfiles-service-type. You’ll need to make sure you’re up to date with guix pull to use it!
This service accepts a list of directories, each of which containing a folder structure that should be symbolically linked directly into your $HOME folder. For example, if you give it a folder containing a subpath of .emacs.d/init.el, this will be linked directly into your home folder as ~/.emacs.d/init.el.
The Guix manual provides more details and examples about how the folder symlinking works including additional useful options.
Here’s an updated configuration that uses the home-dotfiles-service-type:
(use-modules (gnu)
(gnu home)
(gnu home services dotfiles)
(gnu home services shells))
(home-environment
(packages (specifications->packages
(list "git"
"emacs-no-x-toolkit")))
(services (list (service home-bash-service-type
(home-bash-configuration
(environment-variables '(("PS1" . "\\[\\e[1;32m\\]\\u \\[\\e[1;34m\\]\\w \\[\\e[0m\\]λ ")
("EDITOR" . "emacsclient")))
(aliases '(("gs" . "git status")))))
(service home-dotfiles-service-type
(home-dotfiles-configuration
(directories '("../../files")))))))
An important details is that the paths you pass to directories are considered to be relative to the path of the home configuration file! In this case, our config file is located at ~/dotfiles/config/home/home-config.scm and the files folder is at ~/dotfiles/files so the relative path becomes ../../files.
After we apply this configuration with guix home reconfigure, we can see the Emacs and Sway configurations linked into the home folder:
crafter ~ λ ls -al ~/.emacs.d/ total 16 drwx------ 3 crafter users 4096 Nov 3 14:18 ./ drwx------ 8 crafter users 4096 Nov 3 14:18 ../ drwx------ 2 crafter users 4096 Nov 1 12:51 auto-save-list/ lrwxrwxrwx 1 crafter users 74 Nov 3 14:18 init.el -> /gnu/store/y6i4ibz1cy5ns1jnr1wfqisl8j53037h-home-dotfiles--emacs-d-init-el crafter ~ λ ls -al ~/.config/sway/ total 12 drwxr-xr-x 2 crafter users 4096 Nov 3 14:18 ./ drwxr-xr-x 7 crafter users 4096 Nov 3 14:18 ../ lrwxrwxrwx 1 crafter users 77 Nov 3 14:18 config -> /gnu/store/spl92skqqjx94xj80m3mir2gba9qdpsw-home-dotfiles--config-sway-config
¶Why can’t I edit the files?
One curious thing that happens when you use home-dotfiles-service-type is that the symlinked files are marked as read only!
This is because Guix is taking your files and copying them into the “store” where all files meant to be immutable, meaning they should not be edited to preserve the current state of the system.
This is actually a good thing! It’s how Guix provides you with stability guarantees because random configuration changes won’t break your system unless you use guix home reconfigure to apply the new changes.
You can sometimes get around this in programs like Emacs which enable you to re-evaluate sections of your configuration without reloading the entire configuration file.
¶Rolling it Back!
One of the greatest benefits of using Guix Home to manage your $HOME folder is that you can quickly fix your configuration when it breaks!
If you realize that there’s some problem with your configuration after you apply it, you can always roll it back to the previous generation using the guix home roll-back command:
guix home roll-back
Not only will this put your configuration files back the way they were before the last time you ran guix home reconfigure, it will also downgrade any programs back to the versions you had installed at the time. This can save you from a huge headache if something goes wrong!
Guix Home actually stores many of the previous “generations” (builds) of your configuration so you can even go back further in time when things really go wrong.
If you’d like to see all of the previous “generations” that you can roll back to, check out the guix home list-generations command:
crafter ~ λ guix home list-generations
Generation 1 Nov 01 2024 11:19:16
file name: /var/guix/profiles/per-user/crafter/guix-home-1-link
canonical file name: /gnu/store/0jg05s4gxf5ynqrrqkc75w3hr0qvwi2k-home
channels:
guix:
repository URL: https://git.savannah.gnu.org/git/guix.git
branch: master
commit: e85f52e826b0701c3dcf9acf9d81e5ae57aec8f9
configuration file: /gnu/store/hs82gqczyd5qms3nkcn8874kbchxnchj-configuration.scm
Generation 2 Nov 01 2024 11:54:03 (current)
file name: /var/guix/profiles/per-user/crafter/guix-home-2-link
canonical file name: /gnu/store/alhvq73niq128l6lbaxalw89abfyqmng-home
channels:
guix:
repository URL: https://git.savannah.gnu.org/git/guix.git
branch: master
commit: e85f52e826b0701c3dcf9acf9d81e5ae57aec8f9
configuration file: /gnu/store/70r2if11ffgi5sd7dby4wmsqhlz5i79w-configuration.scm
You can switch to a specific generation using the guix home switch-generation command, passing it the desired generation number:
crafter ~ λ guix home switch-generation 1
switched from generation 2 to 1
WARNING: (guile-user): imported module (guix build utils) overrides core binding `delete'
Cleaning up symlinks from previous home at /gnu/store/alhvq73niq128l6lbaxalw89abfyqmng-home.
Removing /home/crafter/.profile... done
Removing /home/crafter/.bash_profile... done
Removing /home/crafter/.bashrc... done
Removing /home/crafter/.config/fontconfig/fonts.conf... done
Removed /home/crafter/.config/fontconfig.
Removing /home/crafter/.config/sway/config... done
Removed /home/crafter/.config/sway.
Skipping /home/crafter/.config (not an empty directory)... done
Removing /home/crafter/.emacs.d/init.el... done
Skipping /home/crafter/.emacs.d (not an empty directory)... done
Cleanup finished.
Symlinking /home/crafter/.profile -> /gnu/store/nqribhmgwcmd8fgblwkcsi1x4wsy2m1h-shell-profile... done
Symlinking /home/crafter/.bash_profile -> /gnu/store/g779bp3xz2ipyy2pld1vxkdi6vizs39c-bash_profile... done
Symlinking /home/crafter/.bashrc -> /gnu/store/5dvm2bfwfwan5hsaxl1icqkmbf0wmjf0-bashrc... done
Symlinking /home/crafter/.config/fontconfig/fonts.conf -> /gnu/store/waz5zaijm4sklnwksk33x6p0p98p24f8-fonts.conf... done
done
Finished updating symlinks.
Comparing /gnu/store/alhvq73niq128l6lbaxalw89abfyqmng-home/profile/share/fonts and
/gnu/store/0jg05s4gxf5ynqrrqkc75w3hr0qvwi2k-home/profile/share/fonts... done (same)
Evaluating on-change gexps.
On-change gexps evaluation finished.
This will put us back to the state of your configuration before we linked our existing configuration files into the $HOME folder!
¶Conclusion
That’s it for our introductory look at how Guix Home can help you manage the chaos of your personal computing configuration!
In future videos I’ll show you some other useful home services that can help you craft an awesome computing environment with all the benefits of Guix Home!
