Difference between revisions of "Cheatsheet"

From NixOS Wiki
Jump to: navigation, search
m (users.extraUsers -> users.users)
m (rollback unauthorized mass edits)
Tag: Rollback
 
(53 intermediate revisions by 29 users not shown)
Line 1: Line 1:
'''Notice: until this page is cleaned up, it is much more easily viewed [https://nixos.wiki/index.php?title=Cheatsheet&useskin=vector with the Vector wiki theme].'''
+
== A NixOS cheat sheet and comparison to Ubuntu ==
 
+
[[Ubuntu_vs._NixOS|Ubuntu vs. NixOS]] provides a table mapping of common administrative tasks and their commands in Ubuntu to similar capabilities in NixOS.
----
 
 
 
== A cheat sheet and rough mapping between Ubuntu and NixOS ==
 
This is meant to give you basic ideas and get you unstuck. NixOS being very different from most distributions, a deeper understanding will be necessary sooner or later! Follow the links to the manual pages and browse the wiki to find real NixOS tutorials.
 
 
 
The system-wide column is the equivalent of using apt under Ubuntu.
 
 
 
TODO Provide well-commented sample configuration.nix and ~/.nixpkgs/config.nix files with examples of common tasks.
 
 
 
<div class="table-responsive">
 
{| class="wikitable"
 
!|Task
 
!|Ubuntu
 
!|NixOS (system-wide and root)
 
!|NixOS (user) and Nix in general
 
|-
 
| colspan="5" style="text-align:center"| Basic concepts
 
|-
 
|
 
|
 
|This column will let you do everything you can with Ubuntu and more.
 
|This column just isn't possible in Ubuntu.
 
|-
 
|Who can install packages and who can run them?
 
|All packages are always system-wide and only root can install packages.
 
|Packages root installs are system-wide. It does so through /etc/nixos/configuration.nix. If root installs packages the same way users do, through ~/.nixpkgs/config.nix, they are also global. Root's default profile is the system-wide default profile.
 
|Users can install their own packages and have their own profiles (environments) through ~/.nixpkgs/config.nix
 
|-
 
|Package manager
 
|apt which is really running on top of dpkg, sometimes wrapped by UIs like aptitude.
 
|nix, but many system-wide operations are provided by nixos packages.
 
|Just nix without the involvement of nixos.
 
|-
 
|How do you select your official sources and major releases
 
|These are baked into the distribution (e.g. Ubuntu version X). Upgrades are hard and permanent.
 
|At any time you select from a collection of channels. They're system-wide when set by root. You can roll back changes or switch channels with ease.
 
|Channels are per-user if they're not set by root.
 
|-
 
|Where are packages installed?
 
|apt installs globally into /bin/, /usr/, etc.
 
|System-wide packages are in /run/current-system/sw/ (these are installed because of /etc/nixos/configuration.nix) and /nix/var/nix/profiles/default/bin/ (this is the profile managed by root). Note that the files are just symlinks to the real packages managed by nix /nix/store/.
 
|User packages are in ~/.nix-profile/. Note that the files are just symlinks to the real packages managed by nix in /nix/store/.
 
|-
 
|When changes take effect
 
|As soon as the command runs. Commands are not atomic and can leave your machine in a bad state.
 
|Most of the time you modify the configuration file and apply changes with nixos-rebuild switch
 
TODO How does one get nixos to do all the work for a switch and separate out the actual switching from fetching/building?
 
|Most of the time you apply changes with nix-env -i all
 
TODO How does one get nix to do all the work for a switch and separate out the actual switching from fetching/building?
 
|-
 
|Packages
 
|Uniformly referred to as packages
 
|Technically called "derivations" but everyone calls them packages.
 
|Technically called "derivations" but everyone calls them packages.
 
|-
 
| colspan="5" style="text-align:center"| Package management
 
|-
 
|Install a package
 
|<syntaxhighlight lang="bash">sudo apt-get install emacs</syntaxhighlight>
 
|In /etc/nixos/configuration.nix:
 
If it's a program add to systemPackages:
 
<syntaxhighlight lang="nix">
 
systemPackages = with pkgs;
 
                    [ <other packages...> emacs ];</syntaxhighlight>
 
If it's a service add:
 
 
 
<syntaxhighlight lang="nix">services.openssh.enable = true;</syntaxhighlight>
 
|<syntaxhighlight lang="bash">nix-env -i emacs</syntaxhighlight>
 
Or with collections, add the package to your ~/.nixpkgs/config.nix and run
 
<syntaxhighlight lang="bash">nix-env -i all</syntaxhighlight>
 
Since 17.09pre:
 
<syntaxhighlight lang="nix">users.users.<username>.packages =
 
          with pkgs;[ emacs ];</syntaxhighlight>
 
|-
 
|Uninstall a package
 
|<syntaxhighlight lang="bash">sudo apt-get remove emacs</syntaxhighlight>
 
|remove from /etc/nixos/configuration.nix
 
<syntaxhighlight lang="bash">sudo nixos-rebuild switch</syntaxhighlight>
 
|
 
<syntaxhighlight lang="bash">nix-env --uninstall emacs</syntaxhighlight>
 
|-
 
|Uninstall a package removing its configuration
 
|<syntaxhighlight lang="bash">sudo apt-get purge emacs</syntaxhighlight>
 
|All configuration is in configuration.nix
 
|
 
|-
 
|Update the list of packages
 
|<syntaxhighlight lang="bash">sudo apt-get update</syntaxhighlight>
 
|<syntaxhighlight lang="bash">sudo nix-channel --update</syntaxhighlight>
 
|<syntaxhighlight lang="bash">nix-channel --update</syntaxhighlight>
 
|-
 
|Upgrade packages
 
|<syntaxhighlight lang="bash">sudo apt-get upgrade</syntaxhighlight>
 
|<syntaxhighlight lang="bash">sudo nixos-rebuild switch</syntaxhighlight>
 
|<syntaxhighlight lang="bash">nix-env -u</syntaxhighlight>
 
|-
 
|Check for broken dependencies
 
|<syntaxhighlight lang="bash">sudo apt-get check</syntaxhighlight>
 
|<syntaxhighlight lang="bash">nix-store --verify --check-contents</syntaxhighlight>
 
|unneeded!
 
|-
 
|List package dependencies
 
|<syntaxhighlight lang="bash">apt-cache depends emacs</syntaxhighlight>
 
|<syntaxhighlight lang="bash">nix-store --query --requisites $(readlink -f /run/current-system)
 
nix-store -q --tree /nix/var/nix/profiles/system</syntaxhighlight>
 
|<syntaxhighlight lang="bash">nix-store --query --references\
 
  $(nix-instantiate '<nixpkgs>' -A emacs)</syntaxhighlight>
 
For installed packages:
 
<syntaxhighlight lang="bash">nix-store --query --references $(which emacs)</syntaxhighlight>
 
|-
 
|List which packages depend on this one (reverse dependencies)
 
|<syntaxhighlight lang="bash">apt-cache rdepends emacs</syntaxhighlight>
 
|
 
|For installed packages (only print reverse dependencies *which are already installed*):
 
<syntaxhighlight lang="bash">nix-store --query --referrers $(which emacs)</syntaxhighlight>
 
|-
 
|Verify all installed packages
 
|<syntaxhighlight lang="bash">debsums</syntaxhighlight>
 
|<syntaxhighlight lang="bash">sudo nix-store --verify --check-contents</syntaxhighlight>
 
|<syntaxhighlight lang="bash">nix-store --verify --check-contents</syntaxhighlight>
 
|-
 
|Fix packages with failed checksums
 
|Reinstall broken packages
 
|<syntaxhighlight lang="nix">sudo nix-store --verify --check-contents --repair</syntaxhighlight>
 
|<syntaxhighlight lang="nix">nix-store --verify --check-contents --repair</syntaxhighlight>
 
|-
 
|Select major version and stable/unstable
 
|Change sources.list and apt-get dist-upgrade. A an extremely infrequent and destructive operation. The nix variants are safe and easy to use.
 
|<syntaxhighlight lang="bash">nix-channel --add\
 
  https://nixos.org/channels/nixpkgs-unstable <name></syntaxhighlight>
 
Add the unstable channel. At that address you will find names for other versions and variants. Name can be any string.
 
<syntaxhighlight lang="bash">nix-channel --remove <name></syntaxhighlight>
 
To eliminate a channel.
 
<syntaxhighlight lang="bash">nix-channel --list</syntaxhighlight>
 
To show all installed channel.
 
|When run by a user channels work locally, when run by root they're used as the system-wide channels.
 
|-
 
|Private package repository
 
|PPA
 
|Define your package tree as in the general column, and include it in configuration.nix, then list your packages in systemPackages to make them available system wide
 
|See [https://sandervanderburg.blogspot.de/2014/07/managing-private-nix-packages-outside.html]
 
|-
 
|Install a particular version of a package
 
|
 
|
 
|
 
|-
 
| colspan="5" style="text-align:center"| Package configuration
 
|-
 
|Configure a package
 
|<syntaxhighlight lang="bash">sudo dpkg-reconfigure <package></syntaxhighlight>
 
|edit /etc/nixos/configuration.nix
 
|edit ~/.nixpkgs/config.nix TODO More details about how to edit
 
|-
 
|List package options
 
|
 
|
 
|
 
|-
 
|Global package configuration
 
|Modify configuration file in /etc/
 
|
 
|
 
|-
 
| colspan="5" style="text-align:center"| Package configuration
 
|-
 
|Find packages
 
|<syntaxhighlight lang="bash">apt-cache search emacs</syntaxhighlight>
 
|<syntaxhighlight lang="bash">nix-env -qaP '.*emacs.*'</syntaxhighlight>
 
|<syntaxhighlight lang="bash">nix-env -qaP '.*emacs.*'</syntaxhighlight>
 
|-
 
|Show package description
 
|<syntaxhighlight lang="bash">apt-cache show emacs</syntaxhighlight>
 
|<syntaxhighlight lang="bash">nix-env -qa --description '.*emacs.*'</syntaxhighlight>
 
|<syntaxhighlight lang="bash">nix-env -qa --description '.*emacs.*'</syntaxhighlight>
 
|-
 
|Show files installed by package
 
|<syntaxhighlight lang="bash">dpkg -L emacs</syntaxhighlight>
 
|<syntaxhighlight lang="bash">readlink -f $(which emacs)
 
/nix/store/ji06y4haijly0i0knmr986l2dajffv1p-emacs-24.4/bin/emacs-24.4</syntaxhighlight>
 
then
 
<syntaxhighlight lang="bash">du -a /nix/store/ji06y4haijly0i0knmr986l2dajffv1p-emacs-24.4</syntaxhighlight>
 
|<syntaxhighlight lang="bash"></syntaxhighlight>
 
|-
 
|Show package for file
 
|<syntaxhighlight lang="bash">dpkg -S /usr/bin/emacs</syntaxhighlight>
 
|follow the symlink
 
|follow the symlink
 
|-
 
| colspan="5" style="text-align:center"| Services
 
|-
 
|Start a service
 
|<syntaxhighlight lang="bash">sudo service apache start</syntaxhighlight>
 
|<syntaxhighlight lang="bash">sudo systemctl start apache</syntaxhighlight>
 
|
 
|-
 
|Stop a service
 
|<syntaxhighlight lang="bash">sudo service apache stop</syntaxhighlight>
 
|<syntaxhighlight lang="bash">sudo systemctl stop apache</syntaxhighlight>
 
|
 
|-
 
|Where your log files live
 
|/var/log/
 
|System-wide packages /var/log/
 
|User packages ~/.nix-profile/var/log/
 
|-
 
|Adding a user
 
|<syntaxhighlight lang="bash">sudo adduser alice</syntaxhighlight>
 
|Add <syntaxhighlight lang="nix">users.users.alice =
 
{ isNormalUser = true;
 
  home = "/home/alice";
 
  description = "Alice Foobar";
 
  extraGroups = [ "wheel" "networkmanager" ];
 
  openssh.authorizedKeys.keys =
 
      [ "ssh-dss AAAAB3Nza... alice@foobar" ];
 
};</syntaxhighlight> to /etc/nixos/configuration.nix and then call <syntaxhighlight lang="nix">nixos-rebuild switch</syntaxhighlight>
 
|
 
|-
 
| colspan="5" style="text-align:center"| Misc tasks
 
|-
 
|List binaries
 
|<syntaxhighlight lang="bash">ls /usr/bin/</syntaxhighlight>
 
|<syntaxhighlight lang="bash">ls /run/current-system/sw/bin &&\
 
ls /nix/var/nix/profiles/default/bin/</syntaxhighlight>
 
|<syntaxhighlight lang="bash">ls ~/.nix-profile/bin</syntaxhighlight>
 
|-
 
|Get the current version number
 
|<syntaxhighlight lang="bash">cat /etc/debian_version</syntaxhighlight>
 
|<syntaxhighlight lang="bash">nixos-version</syntaxhighlight>
 
|<syntaxhighlight lang="bash">nixos-version</syntaxhighlight>
 
|-
 
|Get sources for a package
 
|<syntaxhighlight lang="bash">sudo apt-get source emacs</syntaxhighlight>
 
|
 
|In Debian, apt-get source gets both the patched upstream source and the recipe for the package. Those need two steps in Nix.
 
 
 
To find the package's attribute path: <syntaxhighlight lang="bash">nix-env -qaP emacs</syntaxhighlight> or <syntaxhighlight lang="bash">nox emacs</syntaxhighlight>
 
To download the source as specified by the package recipe: <syntaxhighlight lang="bash">nix-build '<nixpkgs>' -A emacs.src</syntaxhighlight>
 
The patched source is usually not a derivation itself, but can be produced for most packages with the following command: <syntaxhighlight lang="bash">nix-shell '<nixpkgs>' -A emacs\
 
  --command 'unpackPhase; patchPhase'</syntaxhighlight>
 
|-
 
|Compile & install a package from source
 
|
 
|
 
|<syntaxhighlight lang="bash">git clone foobar
 
cat >default.nix <<EOF
 
with import <nixpkgs> { };
 
stdenv.lib.overrideDerivation foobar (oldAttrs : {
 
  src = ./foobar;
 
})
 
EOF
 
nix-build</syntaxhighlight>
 
|-
 
|Install a binary package
 
|
 
|
 
|
 
|-
 
|Install a .deb
 
|<syntaxhighlight lang="bash">sudo dpkg -i package.deb</syntaxhighlight>
 
|
 
|Install dpkg with Nix, then <syntaxhighlight lang="bash">dpkg -i package.deb</syntaxhighlight> (not recommended!)
 
|}
 
</div>
 
  
 
== Working with the nix store ==
 
== Working with the nix store ==
Line 270: Line 6:
 
=== Get the store path for a package ===
 
=== Get the store path for a package ===
  
<source lang="nix">
+
<syntaxHighlight lang="console">
$ nix-repl
+
$ nix repl
nix-repl> :l <nixpkgs>
+
nix-repl> :l <nixpkgs>  
 
Added 7486 variables.
 
Added 7486 variables.
 
nix-repl> "${xorg.libXtst}"
 
nix-repl> "${xorg.libXtst}"
 
"/nix/store/nlpnx21yjdjx2ii7ln4kcmbm0x1vy7w9-libXtst-1.2.3"
 
"/nix/store/nlpnx21yjdjx2ii7ln4kcmbm0x1vy7w9-libXtst-1.2.3"
 +
 +
nix-repl> :lf ./configuration.nix # as flakes way for a local file
 +
 +
# load nixos configuration from a nix file
 +
$ nix repl --file '<nixpkgs/nixos>' -I nixos-config=./configuration.nix
 +
  
 
$ nix-build '<nixpkgs>' --no-build-output -A xorg.libXtst
 
$ nix-build '<nixpkgs>' --no-build-output -A xorg.libXtst
 
/nix/store/nlpnx21yjdjx2ii7ln4kcmbm0x1vy7w9-libXtst-1.2.3
 
/nix/store/nlpnx21yjdjx2ii7ln4kcmbm0x1vy7w9-libXtst-1.2.3
</source>
+
</syntaxHighlight>
 
 
  
 
==== Adding files to the store ====
 
==== Adding files to the store ====
Line 289: Line 30:
 
For most files, it is sufficient to run:
 
For most files, it is sufficient to run:
  
<source lang="bash">
+
<syntaxHighlight lang="console">
 
$ nix-store --add-fixed sha256 /path/to/file
 
$ nix-store --add-fixed sha256 /path/to/file
</source>
+
</syntaxHighlight>
  
 
Unfortunately, `nix-store` will try to load the entire file into memory,
 
Unfortunately, `nix-store` will try to load the entire file into memory,
Line 297: Line 38:
 
If we have root access, we can copy the file to the store ourselves:
 
If we have root access, we can copy the file to the store ourselves:
  
<source lang="bash">
+
<syntaxHighlight lang="console">
 
$ sudo unshare -m bash  # open a shell as root in a private mount namespace
 
$ sudo unshare -m bash  # open a shell as root in a private mount namespace
 
$ largefile=/path/to/file
 
$ largefile=/path/to/file
Line 306: Line 47:
 
$ printf "$storepath\n\n0\n" | nix-store --register-validity --reregister  # register the file in the Nix database
 
$ printf "$storepath\n\n0\n" | nix-store --register-validity --reregister  # register the file in the Nix database
 
$ exit  # exit to the original shell where /nix/store is still mounted read-only
 
$ exit  # exit to the original shell where /nix/store is still mounted read-only
</source>
+
</syntaxHighlight>
 +
 
 +
To add a file with fixed name (when the input filename is not stable), or to add entire directories with filter, you can use '''builtins.path''':
 +
 
 +
<syntaxHighlight lang="console">
 +
$ nix-instantiate --eval --read-write-mode -E 'builtins.path { path = ./myfile; name = "myname"; }'
 +
</syntaxHighlight>
  
 
=== Build nixos from nixpkgs repo ===
 
=== Build nixos from nixpkgs repo ===
Line 312: Line 59:
 
The following snippet will build the system from a git checkout:
 
The following snippet will build the system from a git checkout:
  
<source lang="bash">
+
<syntaxHighlight lang="console">
 
$ nixos-rebuild -I nixpkgs=/path/to/nixpkgs switch
 
$ nixos-rebuild -I nixpkgs=/path/to/nixpkgs switch
</source>
+
</syntaxHighlight>
  
 
This method can be used when testing nixos services for a pull request to nixpkgs.
 
This method can be used when testing nixos services for a pull request to nixpkgs.
Line 322: Line 69:
 
as well as applying customization.
 
as well as applying customization.
  
Use the following command to build directly from a particular branch of a repo in github:
+
Use the following command to build directly from a particular branch of a repository in GitHub:
  
<source lang="bash">
+
<syntaxHighlight lang="console">
 
$ nixos-rebuild -I nixpkgs=https://github.com/nixcloud/nixpkgs/archive/release-17.03.tar.gz switch
 
$ nixos-rebuild -I nixpkgs=https://github.com/nixcloud/nixpkgs/archive/release-17.03.tar.gz switch
</source>
+
</syntaxHighlight>
 +
 
 +
=== Evaluate a NixOS configuration without building ===
 +
 
 +
If you only want to evaluate `configuration.nix` without building (e.g. to syntax-check or see if you are using module options correctly), you can use:
 +
 
 +
<syntaxHighlight lang="console">
 +
$ nix-instantiate '<nixpkgs/nixos>' -A system
 +
</syntaxHighlight>
 +
 
 +
This creates the `.drv` file that `nixos-rebuild build` would build.
 +
 
 +
=== Manually switching a NixOS system to a certain version of system closure ===
 +
 
 +
(''Or:'' What <code>nixos-rebuild</code> does under the hoods.)
 +
 
 +
Step 1: Do this for the equivalent of <code>nixos-rebuild boot</code> or <code>nixos-rebuild switch</code>, i.e. if you want the changes to persist after reboot:
 +
 
 +
If you have the store path, run this, replacing <code>$systemClosure</code> with store path to your system closure:
 +
 
 +
<syntaxHighlight lang="console">
 +
$ nix-env --profile /nix/var/nix/profiles/system --set $systemClosure
 +
</syntaxHighlight>
 +
 
 +
Or, if it was a previous generation, you can run this instead, replacing <code>$generation</code> with the desired generation number:
 +
 
 +
<syntaxHighlight lang="console">
 +
$ nix-env --profile /nix/var/nix/profiles/system --switch-generation $generation
 +
</syntaxHighlight>
 +
 
 +
Step 2: Do this for all changes:
 +
 
 +
Run this, replacing <code>$action</code> with the action (one of <code>boot</code>, <code>switch</code>, <code>test</code>):
 +
 
 +
<syntaxHighlight lang="console">
 +
$ /nix/var/nix/profiles/system/bin/switch-to-configuration $action
 +
</syntaxHighlight>
 +
 
 +
If you use a different profile name the procedure is similar, but use <code>/nix/var/nix/profiles/system-profiles/$profileName</code> instead of <code>/nix/var/nix/profiles/system</code>.
  
 
=== Building a service as a VM (for testing) ===
 
=== Building a service as a VM (for testing) ===
Line 334: Line 119:
 
Given the following configuration:
 
Given the following configuration:
  
<source lang="nix">
+
<syntaxHighlight lang="nix">
 
# vm.nix
 
# vm.nix
 
{ lib, config, ... }:
 
{ lib, config, ... }:
Line 341: Line 126:
 
   users.users.root.initialPassword = "root";
 
   users.users.root.initialPassword = "root";
 
}
 
}
</source>
+
</syntaxHighlight>
  
 
a vm can be build using the following command:
 
a vm can be build using the following command:
  
<source lang="console">
+
<syntaxHighlight lang="console">
 
$ nixos-rebuild -I nixpkgs=/path/to/nixpkgs -I nixos-config=./vm.nix build-vm
 
$ nixos-rebuild -I nixpkgs=/path/to/nixpkgs -I nixos-config=./vm.nix build-vm
</source>
+
</syntaxHighlight>
  
 
where <code>-I nixpkgs=/path/to/nixpkgs</code> is optionally depending whether the vm should be build from git checkout or a channel.
 
where <code>-I nixpkgs=/path/to/nixpkgs</code> is optionally depending whether the vm should be build from git checkout or a channel.
Line 353: Line 138:
 
On non-nixos (linux) systems the following command can be used instead:
 
On non-nixos (linux) systems the following command can be used instead:
  
<source lang="console">
+
<syntaxHighlight lang="console">
 
$ nix-build '<nixpkgs/nixos>' -A vm -k -I nixos-config=./vm.nix
 
$ nix-build '<nixpkgs/nixos>' -A vm -k -I nixos-config=./vm.nix
</source>
+
</syntaxHighlight>
  
 
By default the resulting vm will require X11 to create a virtual display.
 
By default the resulting vm will require X11 to create a virtual display.
 
By specifying additional arguments via the environment variables <code>QEMU_OPTS</code>and <code>QEMU_KERNEL_PARAMS</code> it is possible to reuse the current running terminal as serial console for the vm:
 
By specifying additional arguments via the environment variables <code>QEMU_OPTS</code>and <code>QEMU_KERNEL_PARAMS</code> it is possible to reuse the current running terminal as serial console for the vm:
  
<source lang="console">
+
<syntaxHighlight lang="console">
 
$ export QEMU_OPTS="-nographic -serial mon:stdio" QEMU_KERNEL_PARAMS=console=ttyS0  
 
$ export QEMU_OPTS="-nographic -serial mon:stdio" QEMU_KERNEL_PARAMS=console=ttyS0  
 
$ /nix/store/lshw31yfbb6izs2s594jd89ma4wf8zw6-nixos-vm/bin/run-nixos-vm
 
$ /nix/store/lshw31yfbb6izs2s594jd89ma4wf8zw6-nixos-vm/bin/run-nixos-vm
</source>
+
</syntaxHighlight>
 
 
To be able to log in you will need a getty started on a serial console as well in your nixos configuration:
 
 
 
<source lang="nix">
 
{...}: {
 
  # ..
 
  systemd.services."serial-getty@ttyS0".enable = true;
 
}
 
</source>
 
  
 
To forward a port you can set export <code>QEMU_NET_OPTS</code>. In the following example port 2222 on the host is forwarded to port 22 in the vm:
 
To forward a port you can set export <code>QEMU_NET_OPTS</code>. In the following example port 2222 on the host is forwarded to port 22 in the vm:
  
<source lang="console">
+
<syntaxHighlight lang="console">
 
$ export QEMU_NET_OPTS="hostfwd=tcp::2222-:22"
 
$ export QEMU_NET_OPTS="hostfwd=tcp::2222-:22"
</source>
+
</syntaxHighlight>
  
 
Don't forget that by default nixos comes with a firewall enabled:
 
Don't forget that by default nixos comes with a firewall enabled:
  
<source lang="nix">
+
<syntaxHighlight lang="nix">
 
{...}: {
 
{...}: {
 
   networking.firewall.enable = false;
 
   networking.firewall.enable = false;
 
}
 
}
</source>
+
</syntaxHighlight>
 +
 
 
=== Reuse a package as a build environment ===
 
=== Reuse a package as a build environment ===
 
As packages already contains all build dependencies, they can be reused to a build environment quickly.
 
As packages already contains all build dependencies, they can be reused to a build environment quickly.
Line 392: Line 169:
 
After obtaining the source:
 
After obtaining the source:
  
<source lang="bash">
+
<syntaxHighlight lang="console">
 
$ git clone https://github.com/iovisor/bcc.git
 
$ git clone https://github.com/iovisor/bcc.git
 
$ cd bcc
 
$ cd bcc
</source>
+
</syntaxHighlight>
  
 
Add the following <code>default.nix</code> to the project:
 
Add the following <code>default.nix</code> to the project:
  
<source lang="nix">
+
<syntaxHighlight lang="nix">
 
with import <nixpkgs> {};
 
with import <nixpkgs> {};
 
linuxPackages.bcc.overrideDerivation (old: {
 
linuxPackages.bcc.overrideDerivation (old: {
Line 405: Line 182:
 
   buildInputs = [ bashInteractive ninja ] ++ old.buildInputs;
 
   buildInputs = [ bashInteractive ninja ] ++ old.buildInputs;
 
})
 
})
</source>
+
</syntaxHighlight>
  
 
To initiate the build environment run `nix-shell` in the project root directory
 
To initiate the build environment run `nix-shell` in the project root directory
  
<source lang="bash">
+
<syntaxHighlight lang="console">
 
# this will download add development dependencies and set up the environment so build tools will find them.
 
# this will download add development dependencies and set up the environment so build tools will find them.
 
$ nix-shell
 
$ nix-shell
</source>
+
</syntaxHighlight>
  
 
The following is specific to bcc or cmake in general:
 
The following is specific to bcc or cmake in general:
 
(so you need to adapt the workflow depending on the project, you hack on)
 
(so you need to adapt the workflow depending on the project, you hack on)
  
<source lang="bash">
+
<syntaxHighlight lang="console">
 
$ mkdir build
 
$ mkdir build
 
$ cd build
 
$ cd build
Line 423: Line 200:
 
$ eval cmake $cmakeFlags ..
 
$ eval cmake $cmakeFlags ..
 
$ make
 
$ make
</source>
+
</syntaxHighlight>
 +
 
 +
=== Evaluate packages for a different platform ===
 +
 
 +
Sometimes you want to check whether a change to a package (such as adding a new dependency) would evaluate even on a different type of system. For example, you may want to check on `x86_64-linux` whether a package evaluates for `x86_64-darwin` or `aarch64-linux`.
 +
 
 +
Use the `system` argument:
  
 +
<syntaxHighlight lang="console">
 +
$ nix-instantiate --argstr system "x86_64-darwin" -A mypackage
 +
</syntaxHighlight>
  
 
=== Cross-compile packages ===
 
=== Cross-compile packages ===
Line 430: Line 216:
 
The following command will cross compile the tinc package for the aarch64 CPU architecture from a different architecture (e.g. x86_64).
 
The following command will cross compile the tinc package for the aarch64 CPU architecture from a different architecture (e.g. x86_64).
  
<source lang="console">
+
<syntaxHighlight lang="console">
 
$ nix-build '<nixpkgs>' --arg crossSystem '(import <nixpkgs> {}).lib.systems.examples.aarch64-multiplatform' -A tinc
 
$ nix-build '<nixpkgs>' --arg crossSystem '(import <nixpkgs> {}).lib.systems.examples.aarch64-multiplatform' -A tinc
</source>
+
</syntaxHighlight>
  
 
You can add your own specifications, or look at existing ones, in nixpkgs/lib/systems/examples.nix.
 
You can add your own specifications, or look at existing ones, in nixpkgs/lib/systems/examples.nix.
Line 444: Line 230:
 
For example one can have both the unstable and stable channels on system root:
 
For example one can have both the unstable and stable channels on system root:
  
<source lang="nix">
+
<syntaxHighlight lang="console">
 
$ sudo nix-channel --list
 
$ sudo nix-channel --list
 
nixos https://nixos.org/channels/nixos-17.03
 
nixos https://nixos.org/channels/nixos-17.03
 
nixos-unstable https://nixos.org/channels/nixos-unstable
 
nixos-unstable https://nixos.org/channels/nixos-unstable
</source>
+
</syntaxHighlight>
  
 
and the following in `configuration.nix`:
 
and the following in `configuration.nix`:
  
<source lang="nix">
+
<syntaxHighlight lang="nix">
 
nixpkgs.config = {
 
nixpkgs.config = {
 
   # Allow proprietary packages
 
   # Allow proprietary packages
Line 459: Line 245:
 
   # Create an alias for the unstable channel
 
   # Create an alias for the unstable channel
 
   packageOverrides = pkgs: {
 
   packageOverrides = pkgs: {
     unstable = import <nixos-unstable> {
+
     unstable = import <nixos-unstable> { # pass the nixpkgs config to the unstable alias # to ensure `allowUnfree = true;` is propagated:
      # pass the nixpkgs config to the unstable alias
 
      # to ensure `allowUnfree = true;` is propagated:
 
 
       config = config.nixpkgs.config;
 
       config = config.nixpkgs.config;
 
     };
 
     };
 
   };
 
   };
 
};
 
};
</source>
+
</syntaxHighlight>
  
 
which allows you to switch particular packages to the unstable channel:
 
which allows you to switch particular packages to the unstable channel:
  
<source lang="nix">
+
<syntaxHighlight lang="nix">
environment = {
+
environment.systemPackages = with pkgs; [
  systemPackages = with pkgs; [
 
 
     ddate
 
     ddate
 
     devilspie2
 
     devilspie2
Line 479: Line 262:
 
     # ...
 
     # ...
 
     zsh
 
     zsh
  ];
+
];
};
+
 
</source>
+
</syntaxHighlight>
  
 
=== Building statically linked packages ===
 
=== Building statically linked packages ===
  
<source lang="bash">
+
<syntaxHighlight lang="console">
 
$ nix-build -E 'with (import ./. {}); (curl.override { stdenv = makeStaticLibraries stdenv;}).out'
 
$ nix-build -E 'with (import ./. {}); (curl.override { stdenv = makeStaticLibraries stdenv;}).out'
</source>
+
</syntaxHighlight>
 +
 
 +
There is also an stdenv adapter that will build static binaries:
 +
 
 +
<syntaxHighlight lang="console">
 +
$ nix-build '<nixpkgs>' -A pkgsStatic.hello
 +
</syntaxHighlight>
  
 
=== Rebuild a package with debug symbols ===
 
=== Rebuild a package with debug symbols ===
  
<source lang="bash">
+
<syntaxHighlight lang="console">
 
$ nix-build -E 'with import <nixpkgs> {}; enableDebugging st'
 
$ nix-build -E 'with import <nixpkgs> {}; enableDebugging st'
 
$ file result/bin/st
 
$ file result/bin/st
 
result/bin/st: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /nix/store/f111ij1fc83965m48bf2zqgiaq88fqv5-glibc-2.25/lib/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, not stripped, with debug_info
 
result/bin/st: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /nix/store/f111ij1fc83965m48bf2zqgiaq88fqv5-glibc-2.25/lib/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, not stripped, with debug_info
</source>
+
</syntaxHighlight>
  
 +
=== Download a nix store path from the cache ===
 +
 +
If you want to the exact same nix store path on a different system, you can use the <code>--realise</code> or short <code>-r</code> parameter in the <code>nix-store</code> command:
 +
 +
<syntaxHighlight lang="console">
 +
$ nix-store -r /nix/store/0vg5bw04dn21czjcqcqczyjrhys5cv30-hello-2.10
 +
$ find  /nix/store/0vg5bw04dn21czjcqcqczyjrhys5cv30-hello-2.10
 +
/nix/store/0vg5bw04dn21czjcqcqczyjrhys5cv30-hello-2.10
 +
/nix/store/0vg5bw04dn21czjcqcqczyjrhys5cv30-hello-2.10/bin
 +
/nix/store/0vg5bw04dn21czjcqcqczyjrhys5cv30-hello-2.10/bin/hello
 +
/nix/store/0vg5bw04dn21czjcqcqczyjrhys5cv30-hello-2.10/share
 +
/nix/store/0vg5bw04dn21czjcqcqczyjrhys5cv30-hello-2.10/share/locale
 +
...
 +
</syntaxHighlight>
 +
 +
=== Install an arbitrary nix store path into a user profile ===
 +
 +
<code>nix-env</code> also accepts the full path to a program in the nix store:
 +
 +
<syntaxHighlight lang="console">
 +
$ nix-env -i /nix/store/yzz2gvpcyxg5i68zi11sznbsp1ypccz8-firefox-65.0
 +
</syntaxHighlight>
 +
 +
=== Check the syntax of a nix file ===
 +
 +
<syntaxHighlight lang="console">
 +
$ echo '{}: bar' > expression.nix
 +
$ nix-instantiate --parse-only expression.nix
 +
error: undefined variable 'bar' at /tmp/expression.nix:1:5
 +
</syntaxHighlight>
 +
 +
=== Using override with nix-build ===
 +
 +
using channels
 +
<syntaxhighlight lang="nix">
 +
nix-build -E 'with (import <nixpkgs>{}); polybar.override { i3Support = true; }'
 +
</syntaxhighlight>
 +
using a local repo
 +
<syntaxhighlight lang="nix">
 +
nix-build -E 'with (import ./default.nix{}); polybar.override { i3Support = true; }'
 +
</syntaxhighlight>
  
 
== See also ==
 
== See also ==
* [[Garbage Collection]]
+
 
* [[NFS#Nix_store_on_NFS|Nix store on NFS]]
+
- [[Garbage Collection]]
 +
- [[NFS#Nix_store_on_NFS|Nix store on NFS]]
 +
 
 +
[[Category:Cookbook]]
 +
[[Category:Software]]

Latest revision as of 10:52, 6 April 2024

A NixOS cheat sheet and comparison to Ubuntu

Ubuntu vs. NixOS provides a table mapping of common administrative tasks and their commands in Ubuntu to similar capabilities in NixOS.

Working with the nix store

Get the store path for a package

$ nix repl
nix-repl> :l <nixpkgs> 
Added 7486 variables.
nix-repl> "${xorg.libXtst}"
"/nix/store/nlpnx21yjdjx2ii7ln4kcmbm0x1vy7w9-libXtst-1.2.3"

nix-repl> :lf ./configuration.nix # as flakes way for a local file 

# load nixos configuration from a nix file
$ nix repl --file '<nixpkgs/nixos>' -I nixos-config=./configuration.nix


$ nix-build '<nixpkgs>' --no-build-output -A xorg.libXtst
/nix/store/nlpnx21yjdjx2ii7ln4kcmbm0x1vy7w9-libXtst-1.2.3

Adding files to the store

It is sometimes necessary to add files to the store manually. This is particularly the case with packages that cannot be downloaded automatically, for example, proprietary software packages. For most files, it is sufficient to run:

$ nix-store --add-fixed sha256 /path/to/file

Unfortunately, `nix-store` will try to load the entire file into memory, which will fail if the file size exceeds available memory. If we have root access, we can copy the file to the store ourselves:

$ sudo unshare -m bash  # open a shell as root in a private mount namespace
$ largefile=/path/to/file
$ hash=$(nix-hash --type sha256 --flat --base32 $largefile)  # sha256 hash of the file
$ storepath=$(nix-store --print-fixed-path sha256 $hash $(basename $largefile))  # destination path in the store
$ mount -o remount,rw /nix/store  # remount the store in read/write mode (only for this session)
$ cp $largefile $storepath  # copy the file
$ printf "$storepath\n\n0\n" | nix-store --register-validity --reregister  # register the file in the Nix database
$ exit  # exit to the original shell where /nix/store is still mounted read-only

To add a file with fixed name (when the input filename is not stable), or to add entire directories with filter, you can use builtins.path:

$ nix-instantiate --eval --read-write-mode -E 'builtins.path { path = ./myfile; name = "myname"; }'

Build nixos from nixpkgs repo

The following snippet will build the system from a git checkout:

$ nixos-rebuild -I nixpkgs=/path/to/nixpkgs switch

This method can be used when testing nixos services for a pull request to nixpkgs.

Building nixos from a git is an alternative to using nix channels and set up permanent following this blog article. It has a couple of advantages over nixpkgs as it allows back-porting of packages/changes to stable versions as well as applying customization.

Use the following command to build directly from a particular branch of a repository in GitHub:

$ nixos-rebuild -I nixpkgs=https://github.com/nixcloud/nixpkgs/archive/release-17.03.tar.gz switch

Evaluate a NixOS configuration without building

If you only want to evaluate `configuration.nix` without building (e.g. to syntax-check or see if you are using module options correctly), you can use:

$ nix-instantiate '<nixpkgs/nixos>' -A system

This creates the `.drv` file that `nixos-rebuild build` would build.

Manually switching a NixOS system to a certain version of system closure

(Or: What nixos-rebuild does under the hoods.)

Step 1: Do this for the equivalent of nixos-rebuild boot or nixos-rebuild switch, i.e. if you want the changes to persist after reboot:

If you have the store path, run this, replacing $systemClosure with store path to your system closure:

$ nix-env --profile /nix/var/nix/profiles/system --set $systemClosure

Or, if it was a previous generation, you can run this instead, replacing $generation with the desired generation number:

$ nix-env --profile /nix/var/nix/profiles/system --switch-generation $generation

Step 2: Do this for all changes:

Run this, replacing $action with the action (one of boot, switch, test):

$ /nix/var/nix/profiles/system/bin/switch-to-configuration $action

If you use a different profile name the procedure is similar, but use /nix/var/nix/profiles/system-profiles/$profileName instead of /nix/var/nix/profiles/system.

Building a service as a VM (for testing)

While nixos-rebuild build-vm allows to build a vm out of the current system configuration, there is a more light-weight alternative when only a single service needs to be tested.

Given the following configuration:

# vm.nix
{ lib, config, ... }:
{
  services.tor.enable = true;
  users.users.root.initialPassword = "root";
}

a vm can be build using the following command:

$ nixos-rebuild -I nixpkgs=/path/to/nixpkgs -I nixos-config=./vm.nix build-vm

where -I nixpkgs=/path/to/nixpkgs is optionally depending whether the vm should be build from git checkout or a channel.

On non-nixos (linux) systems the following command can be used instead:

$ nix-build '<nixpkgs/nixos>' -A vm -k -I nixos-config=./vm.nix

By default the resulting vm will require X11 to create a virtual display. By specifying additional arguments via the environment variables QEMU_OPTSand QEMU_KERNEL_PARAMS it is possible to reuse the current running terminal as serial console for the vm:

$ export QEMU_OPTS="-nographic -serial mon:stdio" QEMU_KERNEL_PARAMS=console=ttyS0 
$ /nix/store/lshw31yfbb6izs2s594jd89ma4wf8zw6-nixos-vm/bin/run-nixos-vm

To forward a port you can set export QEMU_NET_OPTS. In the following example port 2222 on the host is forwarded to port 22 in the vm:

$ export QEMU_NET_OPTS="hostfwd=tcp::2222-:22"

Don't forget that by default nixos comes with a firewall enabled:

{...}: {
  networking.firewall.enable = false;
}

Reuse a package as a build environment

As packages already contains all build dependencies, they can be reused to a build environment quickly. In the following a setup for the cmake-based project [bcc](https://github.com/iovisor/bcc) is shown. After obtaining the source:

$ git clone https://github.com/iovisor/bcc.git
$ cd bcc

Add the following default.nix to the project:

with import <nixpkgs> {};
linuxPackages.bcc.overrideDerivation (old: {
  # overrideDerivation allows it to specify additional dependencies
  buildInputs = [ bashInteractive ninja ] ++ old.buildInputs;
})

To initiate the build environment run `nix-shell` in the project root directory

# this will download add development dependencies and set up the environment so build tools will find them.
$ nix-shell

The following is specific to bcc or cmake in general: (so you need to adapt the workflow depending on the project, you hack on)

$ mkdir build
$ cd build
# cmakeFlags is also defined in the bcc package. autotools based projects might defined $configureFlags
$ eval cmake $cmakeFlags ..
$ make

Evaluate packages for a different platform

Sometimes you want to check whether a change to a package (such as adding a new dependency) would evaluate even on a different type of system. For example, you may want to check on `x86_64-linux` whether a package evaluates for `x86_64-darwin` or `aarch64-linux`.

Use the `system` argument:

$ nix-instantiate --argstr system "x86_64-darwin" -A mypackage

Cross-compile packages

The following command will cross compile the tinc package for the aarch64 CPU architecture from a different architecture (e.g. x86_64).

$ nix-build '<nixpkgs>' --arg crossSystem '(import <nixpkgs> {}).lib.systems.examples.aarch64-multiplatform' -A tinc

You can add your own specifications, or look at existing ones, in nixpkgs/lib/systems/examples.nix.

Customizing Packages

Upgrading individual packages to a different channel

One can track multiple channels on NixOS simultaneously, and then declaratively change packages from the default channel to another one.

For example one can have both the unstable and stable channels on system root:

$ sudo nix-channel --list
nixos https://nixos.org/channels/nixos-17.03
nixos-unstable https://nixos.org/channels/nixos-unstable

and the following in `configuration.nix`:

nixpkgs.config = {
  # Allow proprietary packages
  allowUnfree = true;

  # Create an alias for the unstable channel
  packageOverrides = pkgs: {
    unstable = import <nixos-unstable> { # pass the nixpkgs config to the unstable alias # to ensure `allowUnfree = true;` is propagated:
      config = config.nixpkgs.config;
    };
  };
};

which allows you to switch particular packages to the unstable channel:

environment.systemPackages = with pkgs; [
    ddate
    devilspie2
    evince
    unstable.google-chrome
    # ...
    zsh
];

Building statically linked packages

$ nix-build -E 'with (import ./. {}); (curl.override { stdenv = makeStaticLibraries stdenv;}).out'

There is also an stdenv adapter that will build static binaries:

$ nix-build '<nixpkgs>' -A pkgsStatic.hello

Rebuild a package with debug symbols

$ nix-build -E 'with import <nixpkgs> {}; enableDebugging st'
$ file result/bin/st
result/bin/st: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /nix/store/f111ij1fc83965m48bf2zqgiaq88fqv5-glibc-2.25/lib/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, not stripped, with debug_info

Download a nix store path from the cache

If you want to the exact same nix store path on a different system, you can use the --realise or short -r parameter in the nix-store command:

$ nix-store -r /nix/store/0vg5bw04dn21czjcqcqczyjrhys5cv30-hello-2.10
$ find  /nix/store/0vg5bw04dn21czjcqcqczyjrhys5cv30-hello-2.10
/nix/store/0vg5bw04dn21czjcqcqczyjrhys5cv30-hello-2.10
/nix/store/0vg5bw04dn21czjcqcqczyjrhys5cv30-hello-2.10/bin
/nix/store/0vg5bw04dn21czjcqcqczyjrhys5cv30-hello-2.10/bin/hello
/nix/store/0vg5bw04dn21czjcqcqczyjrhys5cv30-hello-2.10/share
/nix/store/0vg5bw04dn21czjcqcqczyjrhys5cv30-hello-2.10/share/locale
...

Install an arbitrary nix store path into a user profile

nix-env also accepts the full path to a program in the nix store:

$ nix-env -i /nix/store/yzz2gvpcyxg5i68zi11sznbsp1ypccz8-firefox-65.0

Check the syntax of a nix file

$ echo '{}: bar' > expression.nix
$ nix-instantiate --parse-only expression.nix
error: undefined variable 'bar' at /tmp/expression.nix:1:5

Using override with nix-build

using channels

nix-build -E 'with (import <nixpkgs>{}); polybar.override { i3Support = true; }'

using a local repo

nix-build -E 'with (import ./default.nix{}); polybar.override { i3Support = true; }'

See also

- Garbage Collection - Nix store on NFS