¶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!