One of the attractive features of NixOS is the ability to declaratively configure all aspects of the system from one configuration file called configuration.nix or for manageability, with this file and input files -- imports in the nix expression terminology --) that are called from this file. Even nix expressions (package build scripts) that can initiate a custom package build, starting from downloading a source tarball to configuring the custom package, can be integrated into this single file configuration system. This guide will provide examples of a configuration I have used.
Besides being one of NixOS's powerful features, because of the OS's nonstandard directory heirarchy, it is necessary to configure nearly every aspect of the system by specifying attributes in the configuration.nix file. The exception to items that must be configured using the configuration.nix file are settings that can be configured from within the desktop environment, for example, using KDE's "System Settings" control panel, although not all settings that can be configured with this tool in standard Linux distributions can be used in NixOS.
This file needs at its top the statement { config, pkgs, ... }:
with everything else in the file inclosed in braces. Text can be commented with #, where all characters that follow are ignored. Individual statements must end with a ;. The following is the main configuration file I used.
# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running ‘nixos-help’).
{ config, pkgs, ... }:
{
imports =
[ # Include the results of the hardware scan.
./hardware-configuration.nix
./desktop-applications.nix
./sysPkgs.nix
./sysPkgsinternet.nix
./nixpkgs.nix
#./hosts.nix
#./hardware.nix
];
# Use the gummiboot efi boot loader.
boot.loader.gummiboot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
boot.loader.gummiboot.timeout = 30;
networking.hostName = "V570-NIXOS"; # Define your hostname.
networking.wireless.enable = true; # Enables wireless.
#networking.networkmanager.enable = true;
# Select internationalisation properties.
i18n = {
consoleFont = "lat9w-16";
consoleKeyMap = "us";
defaultLocale = "en_US.UTF-8";
};
time.timeZone = "America/New_York";
# List packages installed in system profile. To search by name, run:
# -env -qaP | grep wget
# environment.systemPackages = with pkgs; [
# wget
# ];
# List services that you want to enable:
# Enable the OpenSSH daemon.
# services.openssh.enable = true;
# Enable CUPS to print documents.
# services.printing.enable = true;
# Enable the X11 windowing system.
#services.xserver.enable = true;
#services.xserver.layout = "us";
# services.xserver.xkbOptions = "eurosign:e";
#services.xserver.synaptics.enable = true;
services = {
xserver = {
enable = true;
layout = "us";
#defaultDepth = 24;
#videoDriver = "intel";
#exportConfiguration = true;
#enableTCP = true;
#autorun = true;
#driSupport = false;
synaptics = {
enable = true;
#dev = "/dev/input/event8";
};
};
};
# Enable the KDE Desktop Environment.
services.xserver.displayManager.kdm.enable = true;
services.xserver.desktopManager.kde4.enable = true;
# Define a user account. Don't forget to set a password with ‘passwd’.
# users.extraUsers.guest = {
# name = "guest";
# group = "users";
# uid = 1000;
# createHome = true;
# home = "/home/guest";
# shell = "/run/current-system/sw/bin/bash";
# };
}
In the above code block which contains the configuration.nix file,
To make the file manageble, attributes that can logically be grouped together can be placed in separate files with the extension .nix
. For example, attributes that install KDE components, attributes that specify systemwide software installation, and attributes that specify hardware configuration, can be placed in their own files. These files are included in the main configuration file with the statement:
imports =
[
];
The secondary files, like the main configuration file, must have { config, pkgs, ... }:
as the first line and all other statements must be enclosed by braces as well. These files are listed inside the brackets of the imports statement as in:
imports = [ # Include the results of the hardware scan
./hardware-configuration.nix
./desktop-applications.nix
./sysPkgs.nix
./sysPkgsinternet.nix
./nixpkgs.nix
#./hosts.nix
];
Note that the file names of the secondary files include a relative path to the location of the configuration.nix file, which is created in /etc/nixos by the installer.
The secondary file that is imported into the main configuration file on line 2 of the above snippet is created by default during the NixOS installation and includes basic hardware configuration related to booting. The filesystems that should be mounted at boot are specified here by the installer based on what is mounted by the user during the installation. The swap partition is also activated here based on the user activated swap partition during installation. Kernel modules deemed appropriate by the installer are specified automatically by the installer here also. The hardware-configuration.nix file is shown below.
# Do not modify this file! It was generated by ‘nixos-generate-config’
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, pkgs, ... }:
{
imports =
[
];
boot.initrd.availableKernelModules = [ "ehci_pci" "ahci" ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/sda14";
fsType = "ext4";
};
fileSystems."/home" =
{ device = "/dev/sda15";
fsType = "ext4";
};
fileSystems."/boot" =
{ device = "/dev/sda2";
fsType = "vfat";
};
swapDevices =
[ { device = "/dev/sda8"; }
];
nix.maxJobs = 4;
}
Two of the other files imported into the main configuration file -- desktop-applications.nix and sysPkgsinternet.nix -- are files that include straightforward declarations of packages that should be included in the system configuration, i.e., those that should be installed on the system. nixpkgs.nix configures or modifies the referenced software in the file.sysPkgs.nix is similar to the desktop-applications.nix file in that it declaratively specifies software to be installed, but it also includes a declaratively installed package that is custom built by calling another file that is a nix expression (build script) to build the package. The structure of these files are discussed in sections below.
Attribute names are hierarchically organized through the use of qualifiers. In the attribute boot.loader.gummiboot.enable, boot is the top level qualifier, and loader and gummiboot are intermediate level qualifiers. This system allows attribute specifications to be nested as in the following:
services = {
xserver = {
enable = true;
layout = "us";
synaptics = {
enable = true;
};
};
};
which is equivalent to writing
services.xserver.enable = true;
services.xserver.layout = "us";
services.xserver.synaptics.enable = true;
The entire list of available attributes and permissible values are listed in Appendix B of the .
Packages can be declaratively installed by including them in the list of sytem-wide packages with the statement
environment.systemPackages = with pkgs; [
];
The packages to be installed are listed inside the brackets of the above statement. desktop-applications.nix and sysPkgsinternet.nix, which are included or "imported" into configuration.nix install packages system-wide declaratively using the statement in the previous snippet. In desktop-applications.nix, which is listed in the following code block, the desired KDE packages are listed between the brackets.
{ config, pkgs, ... }:
{
# KDE packages
environment.systemPackages = with pkgs; [
kde4.networkmanagement
kde4.kdemultimedia
kde4.kdegraphics
kde4.kdeutils
kde4.applications
#pkgs.kde4.kdegames
#pkgs.kde4.kdeedu
kde4.kdebindings
kde4.kdeaccessibility
kde4.kde_baseapps
kde4.kactivities
kde4.kdeadmin
kde4.kdeartwork
kde4.kde_base_artwork
kde4.kdenetwork
kde4.kdepim
kde4.kdepimlibs
kde4.kdeplasma_addons
kde4.kdesdk
kde4.kdetoys
kde4.kde_wallpapers
kde4.kdewebdev
kde4.oxygen_icons
kde4.kdebase_workspace
kde4.kdelibs
kde4.kdevelop
kde4.kdevplatform
kde4.qtcurve
kde4.ColorSchemes
kde4.desktopthemes
kde4.kscreensaver
kde4.kwin_styles
kde4.partitionManager
kde4.qt4
kde4.yakuake
kde4.kgpg
];
}
In sysPkgsinternet.nix, which is listed in the following code block,
{ config, pkgs, ... }:
{
environment.systemPackages = with pkgs; [
chromiumWrapper
firefoxWrapper
];
}
Note that if you don't include with pkgs;
in environment.systemPackages = with pkgs;
,
you will have to prefix each of the package names with pkgs.
In nixpkgs.nix, listed below,
{ config, pkgs, ... }:
# Nixpkgs options (like repository options)
{
nixpkgs.config.allowUnfree = true;
nixpkgs.config.firefox.enableAdobeFlash = true; # for Firefox
nixpkgs.config.chromium.enableAdobeFlash = true; # for Chromium
nixpkgs.config.chromium.enablePepperFlash = true;
nixpkgs.config.chromium.enablePepperPDF = true;
}
the packages browsers declared in sysPkgsinternet.nix are configured to use Adobe Flash Player, Pepper PDF, and Pepper Flash Player plugins, meaning that these plugins will be installed during the building of the configuration. Line 6 of this file is necessary to allow these and other non-free packages to be installed on the system.
Anyone who commits to using NixOS past a cursory trial, will need to specify a package that is custom built, either because it is not available in the NixOS channels, a recent version is not available, or the user wants to customize the build. In my case, I needed a newer version of LyX in order to be able to open and modify LyX files created with a newer version of LyX on other Linux distributions. The method I used can serve as an example of one method of doing this.
The first step was to write a nix expression to build the package, using the expression that is viewable on packages.nixos.org which for the LyX package in the NixOS 14.04 channel was specifically at this page. After modification the nix expression looked like the following code block.
# Custom build of Lyx version 2.1.1 which is not available in the Nixpkgs 14.04
# channel as of 8/14/04.
# Modifying the expression in Nixpkgs of versiotn 2.0.7 to allow hunspell and
# enchant spell checkers.
with import { #fetchurl stdenv texLive python
#pkgconfig libX11 qt4 enchant hunspell #mythes, boost
};
stdenv.mkDerivation rec {
version = "2.1.1";
name = "lyx-$ {version}";
src = fetchurl {
url = "ftp://ftp.lyx.org/pub/lyx/stable/2.1.x/${name}.tar.xz";
sha256 = "1fir1dzzy7c92jf3a3psnd10c6widslk0852xk4svpl6phcg4nya";
};
configureFlags = [
"--without-included-boost"
/* Boost is a huge dependency from which 1.4 MB of libs would be used.
Using internal boost stuff only increases executable by around 0.2 MB. */
"--without-included-mythes" # such a small library isn't worth a separate
#package
];
buildInputs = [
pkgconfig qt4 python file bc texLive makeWrapper #libX11
enchant hunspell mythes boost
];
doCheck = true;
postFixup = ''
sed '1s:/usr/bin/python:${python}/bin/python:'
wrapProgram "$out/bin/lyx" \
--prefix PATH : '${python}/bin'
'';
meta = {
description = "LyX 2.1.1 customized for local installation";
homepage = "http://www.lyx.org";
license = stdenv.lib.licenses.gpl2;
maintainers = [ stdenv.lib.maintainers.vcunat ];
platforms = stdenv.lib.platforms.linux;
};
}
The elements of the original file that I changed were
with import < nixpkgs >
and commented out everything in the brackets. This change puts all packages and nix tools into scope for building the package so if they are needed due to statements in the rest of the expression, they will be available, instead of just those that are in the braces of the original expressionI saved this expression as the file my-lyx.nix in /etc/nixos.
The second and last step was to include this expression into the environment.systemPackages
list. I included it in the secondary configuration file sysPkgs.nix which was itself imported into the main configuration file in line 12 of the configuration.nix. sysPkgs.nix is shown in the following code block.
{ config, pkgs, ... }:
{
environment.systemPackages = with pkgs; [
texLive
texLiveExtra
texLivePGF
texLiveLatexXColor
texLiveContext
texLiveBeamer
texLiveModerncv
texLiveModerntimeline
#tetex
#texLiveFull
(import ./my-lyx.nix)
];
}
With the configuration files listed in this article in place in /etc/nixos, when the command nixos-rebuild switch
is executed, the configuration declared in this set of files will be built. The configuration building process will configure the system as specified, install all packages, with all necessary dependencies, downloading sources, compiling, and building packages as necessary.