You will occasionally see a $ before a command. This is mostly to differentiate the input (what you type), from the output, the computer provides.
Here’s an example:
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 465.8G 0 disk
└─sda1 8:1 0 465.8G 0 part /media/franz/4e619844-b92a-49bd-8b70-cf934abdc8eb
So the actual command is lsblk (you don’t write $).
On the other hand, if there’s only a command, and no output, we sometimes omit the $ like so:
lsblk
Pre-installation
Before you get started, ready a USB stick with the latest ISO image.
Download 1xnvrrk5n25llks8pjx64f2kb3nfasn4-image.iso (2.2GB)
0vvnfzw6y52z1qd2k60jcxw9r5y9mfvp9s1p4nj53ii4l3gyhbmg (Guix nix-base32, SHA-256)
Flash with dd
Plugin the USB stick and determine the name:
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 1 14.9G 0 disk
├─sda1 8:1 1 1G 0 part /media/franz/GUIX_IMAGE
└─sda2 8:2 1 2.8M 0 part
nvme0n1 259:0 0 953.9G 0 disk
├─nvme0n1p1 259:1 0 549M 0 part /boot/efi
└─nvme0n1p2 259:2 0 953.3G 0 part
└─cryptroot 253:0 0 953.3G 0 crypt /
In my case, it’s /dev/sda, so I proceed with copying the ISO to this drive:
$ sudo dd if=1xnvrrk5n25llks8pjx64f2kb3nfasn4-image.iso of=/dev/sda status=progress
Password:
1110499840 bytes (1.1 GB, 1.0 GiB) copied, 284 s, 3.9 MB/s
2169320+0 records in
2169320+0 records out
1110691840 bytes (1.1 GB, 1.0 GiB) copied, 284.985 s, 3.9 MB/s
$ sync
Now un-mount / eject the drive:
sudo umount /dev/sda1
Flash with etcher
If you prefer a GUI tool that runs on your existing OS (Windows, MacOS, other Linux), have a look at etcher.
First steps
Now just plugin the USB stick into the target computer, and boot from it.
Most commonly, you can get a boot device selection with F10 or F11.
Once you have booted from USB, you will be greeted with “Locale language” selection.
(1) Select your locale
(2) Select your location
Select “Install using the shell based process”.
If you’re connected via LAN cable, you probably already have internet. Skip ahead to installation.
Connect to the Internet
Now that you’re in the command line, it should read “Welcome to the Installation of PantherX OS!”. Before you continue, you need to establish a internet connection. If you are connected with a LAN cable, that might already have happened.
Here’s how you verify whether you’re connected:
$ ip -brief addr
lo UNKNOWN 127.0.0.1/8 ::1/128
enp2s0 UP 192.168.1.73/24 fe80::6e4b:90ff:feed:9578/64
One of the listed interfaces should have a valid IP address. For example 192.168.1.69. If that’s the case, you can proceed to the next step. If not, here’s how you connect:
Either LAN or WLAN must be working before you can proceed. Here’s how you configure either:
Wired Network (LAN)
To configure a wired network run the following command, substituting interface with the name of the wired interface you want to use:
$ ifconfig INTERFACE_NAME up # for ex. enp2s0
Now try to get a IP address:
$ dhclient -v INTERFACE_NAME # for ex. enp2s0
Wireless Network (WLAN)
You have two options:
- Guided (recommended) —
guix-install wifi - Manual — configure
wpa_supplicantyourself
Option 1: Guided with guix-install wifi
The easiest way is to use the built-in helper, which walks you through scanning for networks, picking one, and entering the passphrase via connmanctl:
guix-install wifi
Note: The first run may show no networks — just run it again and they should appear. This assumes you have a supported Wi-Fi adapter; if nothing shows up after a couple of tries, your hardware likely needs non-free firmware that isn’t loaded.
Once connected, verify with ip -brief addr and skip ahead to installation.
Option 2: Manual with wpa_supplicant
To configure wireless networking manually, create a configuration file for the wpa_supplicant configuration tool:
$ nano wpa_supplicant.conf
with the following content:
network={
ssid="YOUR_WIFI_NAME"
key_mgmt=SECURITY_STANDARD
psk="YOUR_WIFI_PASSWORD"
}
once you’re done, this should look roughly like this:
network={
ssid="MyWirelessNetwork"
key_mgmt=WPA-PSK
psk="3295e09f-241b-4a06-a492-f3f3cc95c24d"
}
You can find more examples and options here: wpa_supplicant.conf: Linux man page.
To start the wireless service, and run it on interface in the background:
$ wpa_supplicant -c wpa_supplicant.conf -i INTERFACE_NAME -B
# Example
$ wpa_supplicant -c wpa_supplicant.conf -i enp2s0 -B
Note If this doesn’t work, you might want to try to check your network with rfkill:
$ rfkill
ID TYPE DEVICE SOFT HARD
0 bluetooth tpacpi_bluetooth_sw unblocked unblocked
1 bluetooth hci0 unblocked unblocked
2 wlan phy0 unblocked unblocked
If the wlan interface is blocked, you can unblock it with rfkill unblock wlan.
Now try to get a IP address:
$ dhclient -v INTERFACE_NAME
# Example
$ dhclient -v wlan0
SSH access (OPTIONAL)
If you want to continue with the installation remotely, load the SSH server and set a root password:
$ herd start ssh-daemon
Service ssh-daemon has been started.
$ passwd
New Password:
Retype new password:
passwd: password updated successfully
Now simply connect via SSH from another computer: ssh root@192.168.1.67.
Installation
It is highly recommended to download and run the latest version of the installer, instead of the included version: Download from GitHub releases
We ship a small installer that walks through the setup. Run it with:
guix-install
The installer walks through 9 steps. Press Esc at any prompt to go back.
(1) Mode — which channel and kernel you want. Defaults to panther.
panther— PantherX OS, based on nonguix with the linux kernel + microcode, plus the PantherX substitute serverguix— upstream GNU Guix with linux-libre (no proprietary firmware; Wi-Fi/GPU may not work)nonguix— Guix + the linux kernel + microcode for broader hardware supportenterprise— fetches a system config tarball from a remote server by ID; skips locale/timezone/hostname/users/desktop
(2) Locale — the system language and character set, for example en_US.utf8. This sets LANG and friends system-wide.
(3) Timezone — for example Europe/Berlin. Used for the system clock and logs.
(4) Hostname — the machine’s name on the network. Defaults to <mode>-<6 random chars> if you don’t pick one.
(5) Disk — the target disk that will be wiped and partitioned (for example /dev/sda or /dev/nvme0n1). BIOS vs UEFI is auto-detected. Pick carefully — everything on this disk is replaced.
(6) Encryption — optionally enable LUKS full-disk encryption on /. You’ll be asked for a passphrase you’ll need to enter on every boot.
(7) Users — primary username (defaults to panther) and password. Passwords are SHA-512-crypted in-process and written directly to /mnt/etc/shadow — they never land in system.scm.
(8) Desktop — pick one of:
- XFCE
- MATE
- GNOME
- KDE
- Sway
- i3
- LXQt
Or skip for a console-only system.
(9) Summary — review everything before any disk is touched. Confirm to start; the installer partitions, formats, mounts, generates system.scm + channels.scm, authorizes substitute servers, runs guix pull, and finally guix system init. State is persisted to /tmp/.guix-install-state after each phase, so you can re-run and pick up where it failed.
Resuming a failed install
The install can take a while, and the guix pull and guix system init phases occasionally get stuck on flaky substitute servers — for example:
Computing Guix derivation for 'x86_64-linux'... \
substitute: looking for substitutes on 'https://bordeaux.guix.gnu.org'... 0.0%
guix substitute: warning: bordeaux.guix.gnu.org: TLS connection failed: in write_to_session_record_port: Error in the push function.
If that happens, you can stop with Ctrl+C and run guix-install again. It detects the saved state and offers to resume from the failed phase — you just re-enter your user password:
guix-install — Guix System Installer
Found incomplete installation: completed through phase 7/8 (mode=panther, disk=/dev/nvme0n1).
✔ What next? · Resume previous installation
✔ User password (re-enter to resume install) · ********
The disk isn’t re-partitioned and your earlier choices are kept. State lives in /tmp/.guix-install-state — if you change disk, mode, or firmware, it’s discarded and you start fresh.
Once the installation has completed, it should read something like this:
guix system: bootloader successfully installed on /dev/sda
Now simply reboot with
reboot
- Source and releases: github.com/franzos/guix-install.
- Run into a bug or something unexpected? Open an issue at github.com/franzos/guix-install/issues.
- Tip: SSH is disabled by default on Desktop so you won’t be able to reconnect after reboot without enabling it first
Post-installation
(1) Set the root password
Your user password was set during install, but root doesn’t have one yet — log in as your user and set it now:
sudo passwd
You’ll be prompted for your user password (for sudo), then for the new root password twice.
(2) Update the system
Guix splits updates into two layers, and you need to do both:
- The system layer — the kernel, services, and packages defined in
/etc/system.scm. Managed by root. - Your user profile — the packages you’ve installed with
guix package -i. Managed per-user, lives in~/.guix-profile.
Both layers start with guix pull, which updates Guix itself and the package definitions. guix pull is per-user — running it as root only updates root’s Guix; running it as panther only updates yours. So you have to run it in both places.
System updates (as root)
sudo -i
guix pull
guix system reconfigure /etc/system.scm
What this does:
guix pullfetches the latest package definitions for root, using the channels in/etc/guix/channels.scm.guix system reconfigurerebuilds the system from/etc/system.scm, activates it, and adds a new entry to the bootloader. The previous generation stays available, so if something breaks you can pick the older entry at boot, or runguix system roll-backlater.
A reboot isn’t strictly required after reconfigure — running services upgrade as they’re restarted — but for kernel and init changes you’ll want one.
User profile updates (as your user)
guix pull
guix package -u
What this does:
guix pullupdates your Guix and package definitions (independent of root’s).guix package -uupgrades every package in your user profile to the versions from that pull. Each upgrade creates a new profile generation;guix package --roll-backreverts to the previous one.
(3) Reboot and enjoy
Have a great time with GNU Guix