0
0
Fork 0
mirror of https://github.com/NixOS/nixpkgs.git synced 2025-07-13 13:40:28 +03:00

treewide: Fix all Nix ASTs in all markdown files

This allows for correct highlighting and maybe future automatic
formatting. The AST was verified to work with nixfmt only.
This commit is contained in:
Janne Heß 2024-03-27 19:10:27 +01:00 committed by Valentin Gagarin
parent bc77c7a973
commit fcc95ff817
150 changed files with 2896 additions and 2087 deletions

View file

@ -21,8 +21,10 @@ You can tell NixOS in `configuration.nix` to run this unit automatically
at certain points in time, for instance, every night at 03:15:
```nix
nix.gc.automatic = true;
nix.gc.dates = "03:15";
{
nix.gc.automatic = true;
nix.gc.dates = "03:15";
}
```
The commands above do not remove garbage collector roots, such as old

View file

@ -26,9 +26,11 @@ host to rewrite container traffic to use your external IP address. This
can be accomplished using the following configuration on the host:
```nix
networking.nat.enable = true;
networking.nat.internalInterfaces = ["ve-+"];
networking.nat.externalInterface = "eth0";
{
networking.nat.enable = true;
networking.nat.internalInterfaces = ["ve-+"];
networking.nat.externalInterface = "eth0";
}
```
where `eth0` should be replaced with the desired external interface.
@ -38,7 +40,9 @@ If you are using Network Manager, you need to explicitly prevent it from
managing container interfaces:
```nix
networking.networkmanager.unmanaged = [ "interface-name:ve-*" ];
{
networking.networkmanager.unmanaged = [ "interface-name:ve-*" ];
}
```
You may need to restart your system for the changes to take effect.

View file

@ -39,7 +39,9 @@ they were in the same cgroup, then the PostgreSQL process would get
`configuration.nix`:
```nix
systemd.services.httpd.serviceConfig.CPUShares = 512;
{
systemd.services.httpd.serviceConfig.CPUShares = 512;
}
```
By default, every cgroup has 1024 CPU shares, so this will halve the CPU
@ -52,7 +54,9 @@ limits can be specified in `configuration.nix`; for instance, to limit
`httpd.service` to 512 MiB of RAM (excluding swap):
```nix
systemd.services.httpd.serviceConfig.MemoryLimit = "512M";
{
systemd.services.httpd.serviceConfig.MemoryLimit = "512M";
}
```
The command `systemd-cgtop` shows a continuously updated list of all

View file

@ -5,13 +5,15 @@ You can also specify containers and their configuration in the host's
shall be a container named `database` running PostgreSQL:
```nix
containers.database =
{ config =
{ config, pkgs, ... }:
{ services.postgresql.enable = true;
services.postgresql.package = pkgs.postgresql_14;
};
};
{
containers.database =
{ config =
{ config, pkgs, ... }:
{ services.postgresql.enable = true;
services.postgresql.package = pkgs.postgresql_14;
};
};
}
```
If you run `nixos-rebuild switch`, the container will be built. If the
@ -25,11 +27,13 @@ cannot change the network configuration. You can give a container its
own network as follows:
```nix
containers.database = {
privateNetwork = true;
hostAddress = "192.168.100.10";
localAddress = "192.168.100.11";
};
{
containers.database = {
privateNetwork = true;
hostAddress = "192.168.100.10";
localAddress = "192.168.100.11";
};
}
```
This gives the container a private virtual Ethernet interface with IP

View file

@ -82,7 +82,9 @@ In order to enable a systemd *system* service with provided upstream
package, use (e.g):
```nix
systemd.packages = [ pkgs.packagekit ];
{
systemd.packages = [ pkgs.packagekit ];
}
```
Usually NixOS modules written by the community do the above, plus take

View file

@ -47,9 +47,9 @@ You can write a `let` wherever an expression is allowed. Thus, you also could ha
```nix
{
services.httpd.virtualHosts =
let commonConfig = ...; in
{ "blog.example.org" = (commonConfig // { ... })
"wiki.example.org" = (commonConfig // { ... })
let commonConfig = { /* ... */ }; in
{ "blog.example.org" = (commonConfig // { /* ... */ });
"wiki.example.org" = (commonConfig // { /* ... */ });
};
}
```

View file

@ -6,8 +6,10 @@ is useful for doing network configuration not covered by the existing NixOS
modules. For instance, to statically configure an IPv6 address:
```nix
networking.localCommands =
''
ip -6 addr add 2001:610:685:1::1/64 dev eth0
'';
{
networking.localCommands =
''
ip -6 addr add 2001:610:685:1::1/64 dev eth0
'';
}
```

View file

@ -23,7 +23,9 @@ Then you write and test the package as described in the Nixpkgs manual.
Finally, you add it to [](#opt-environment.systemPackages), e.g.
```nix
environment.systemPackages = [ pkgs.my-package ];
{
environment.systemPackages = [ pkgs.my-package ];
}
```
and you run `nixos-rebuild`, specifying your own Nixpkgs tree:
@ -38,24 +40,28 @@ tree. For instance, here is how you specify a build of the
`configuration.nix`:
```nix
environment.systemPackages =
let
my-hello = with pkgs; stdenv.mkDerivation rec {
name = "hello-2.8";
src = fetchurl {
url = "mirror://gnu/hello/${name}.tar.gz";
hash = "sha256-5rd/gffPfa761Kn1tl3myunD8TuM+66oy1O7XqVGDXM=";
{
environment.systemPackages =
let
my-hello = with pkgs; stdenv.mkDerivation rec {
name = "hello-2.8";
src = fetchurl {
url = "mirror://gnu/hello/${name}.tar.gz";
hash = "sha256-5rd/gffPfa761Kn1tl3myunD8TuM+66oy1O7XqVGDXM=";
};
};
};
in
[ my-hello ];
in
[ my-hello ];
}
```
Of course, you can also move the definition of `my-hello` into a
separate Nix expression, e.g.
```nix
environment.systemPackages = [ (import ./my-hello.nix) ];
{
environment.systemPackages = [ (import ./my-hello.nix) ];
}
```
where `my-hello.nix` contains:
@ -88,7 +94,9 @@ section](#module-services-flatpak). AppImages will not run "as-is" on NixOS.
First you need to install `appimage-run`: add to `/etc/nixos/configuration.nix`
```nix
environment.systemPackages = [ pkgs.appimage-run ];
{
environment.systemPackages = [ pkgs.appimage-run ];
}
```
Then instead of running the AppImage "as-is", run `appimage-run foo.appimage`.

View file

@ -5,7 +5,7 @@ The NixOS configuration file generally looks like this:
```nix
{ config, pkgs, ... }:
{ option definitions
{ /* option definitions */
}
```
@ -80,7 +80,9 @@ Strings
: Strings are enclosed in double quotes, e.g.
```nix
networking.hostName = "dexter";
{
networking.hostName = "dexter";
}
```
Special characters can be escaped by prefixing them with a backslash
@ -89,11 +91,13 @@ Strings
Multi-line strings can be enclosed in *double single quotes*, e.g.
```nix
networking.extraHosts =
''
127.0.0.2 other-localhost
10.0.0.1 server
'';
{
networking.extraHosts =
''
127.0.0.2 other-localhost
10.0.0.1 server
'';
}
```
The main difference is that it strips from each line a number of
@ -108,8 +112,10 @@ Booleans
: These can be `true` or `false`, e.g.
```nix
networking.firewall.enable = true;
networking.firewall.allowPing = false;
{
networking.firewall.enable = true;
networking.firewall.allowPing = false;
}
```
Integers
@ -117,7 +123,9 @@ Integers
: For example,
```nix
boot.kernel.sysctl."net.ipv4.tcp_keepalive_time" = 60;
{
boot.kernel.sysctl."net.ipv4.tcp_keepalive_time" = 60;
}
```
(Note that here the attribute name `net.ipv4.tcp_keepalive_time` is
@ -132,11 +140,13 @@ Sets
braces, as in the option definition
```nix
fileSystems."/boot" =
{ device = "/dev/sda1";
fsType = "ext4";
options = [ "rw" "data=ordered" "relatime" ];
};
{
fileSystems."/boot" =
{ device = "/dev/sda1";
fsType = "ext4";
options = [ "rw" "data=ordered" "relatime" ];
};
}
```
Lists
@ -145,13 +155,17 @@ Lists
separated by whitespace, like this:
```nix
boot.kernelModules = [ "fuse" "kvm-intel" "coretemp" ];
{
boot.kernelModules = [ "fuse" "kvm-intel" "coretemp" ];
}
```
List elements can be any other type, e.g. sets:
```nix
swapDevices = [ { device = "/dev/disk/by-label/swap"; } ];
{
swapDevices = [ { device = "/dev/disk/by-label/swap"; } ];
}
```
Packages
@ -161,12 +175,14 @@ Packages
argument `pkgs`. Typical uses:
```nix
environment.systemPackages =
[ pkgs.thunderbird
pkgs.emacs
];
{
environment.systemPackages =
[ pkgs.thunderbird
pkgs.emacs
];
services.postgresql.package = pkgs.postgresql_14;
services.postgresql.package = pkgs.postgresql_14;
}
```
The latter option definition changes the default PostgreSQL package

View file

@ -16,18 +16,20 @@ Examples include:
You can use them like this:
```nix
environment.systemPackages = with pkgs; [
sl
(pass.withExtensions (subpkgs: with subpkgs; [
pass-audit
pass-otp
pass-genphrase
]))
(python3.withPackages (subpkgs: with subpkgs; [
requests
]))
cowsay
];
{
environment.systemPackages = with pkgs; [
sl
(pass.withExtensions (subpkgs: with subpkgs; [
pass-audit
pass-otp
pass-genphrase
]))
(python3.withPackages (subpkgs: with subpkgs; [
requests
]))
cowsay
];
}
```
:::
@ -38,7 +40,9 @@ dependency on GTK 2. If you want to build it against GTK 3, you can
specify that as follows:
```nix
environment.systemPackages = [ (pkgs.emacs.override { gtk = pkgs.gtk3; }) ];
{
environment.systemPackages = [ (pkgs.emacs.override { gtk = pkgs.gtk3; }) ];
}
```
The function `override` performs the call to the Nix function that
@ -58,12 +62,14 @@ of the package, such as the source code. For instance, if you want to
override the source code of Emacs, you can say:
```nix
environment.systemPackages = [
(pkgs.emacs.overrideAttrs (oldAttrs: {
name = "emacs-25.0-pre";
src = /path/to/my/emacs/tree;
}))
];
{
environment.systemPackages = [
(pkgs.emacs.overrideAttrs (oldAttrs: {
name = "emacs-25.0-pre";
src = /path/to/my/emacs/tree;
}))
];
}
```
Here, `overrideAttrs` takes the Nix derivation specified by `pkgs.emacs`
@ -80,9 +86,11 @@ two instances of the package. If you want to have everything depend on
your customised instance, you can apply a *global* override as follows:
```nix
nixpkgs.config.packageOverrides = pkgs:
{ emacs = pkgs.emacs.override { gtk = pkgs.gtk3; };
};
{
nixpkgs.config.packageOverrides = pkgs:
{ emacs = pkgs.emacs.override { gtk = pkgs.gtk3; };
};
}
```
The effect of this definition is essentially equivalent to modifying the

View file

@ -7,7 +7,9 @@ following line to `configuration.nix` enables the Mozilla Thunderbird
email application:
```nix
environment.systemPackages = [ pkgs.thunderbird ];
{
environment.systemPackages = [ pkgs.thunderbird ];
}
```
The effect of this specification is that the Thunderbird package from

View file

@ -6,10 +6,12 @@ Ext4 file system on device `/dev/disk/by-label/data` onto the mount
point `/data`:
```nix
fileSystems."/data" =
{ device = "/dev/disk/by-label/data";
fsType = "ext4";
};
{
fileSystems."/data" =
{ device = "/dev/disk/by-label/data";
fsType = "ext4";
};
}
```
This will create an entry in `/etc/fstab`, which will generate a

View file

@ -5,14 +5,18 @@ and other unexpected packets. The firewall applies to both IPv4 and IPv6
traffic. It is enabled by default. It can be disabled as follows:
```nix
networking.firewall.enable = false;
{
networking.firewall.enable = false;
}
```
If the firewall is enabled, you can open specific TCP ports to the
outside world:
```nix
networking.firewall.allowedTCPPorts = [ 80 443 ];
{
networking.firewall.allowedTCPPorts = [ 80 443 ];
}
```
Note that TCP port 22 (ssh) is opened automatically if the SSH daemon is
@ -22,10 +26,12 @@ enabled (`services.openssh.enable = true`). UDP ports can be opened through
To open ranges of TCP ports:
```nix
networking.firewall.allowedTCPPortRanges = [
{ from = 4000; to = 4007; }
{ from = 8000; to = 8010; }
];
{
networking.firewall.allowedTCPPortRanges = [
{ from = 4000; to = 4007; }
{ from = 8000; to = 8010; }
];
}
```
Similarly, UDP port ranges can be opened through

View file

@ -55,9 +55,11 @@ supported through the rocmPackages.clr.icd package. Adding this package to
enables OpenCL support:
```nix
hardware.opengl.extraPackages = [
rocmPackages.clr.icd
];
{
hardware.opengl.extraPackages = [
rocmPackages.clr.icd
];
}
```
### Intel {#sec-gpu-accel-opencl-intel}
@ -74,9 +76,11 @@ to enable OpenCL support. For example, for Gen8 and later GPUs, the following
configuration can be used:
```nix
hardware.opengl.extraPackages = [
intel-compute-runtime
];
{
hardware.opengl.extraPackages = [
intel-compute-runtime
];
}
```
## Vulkan {#sec-gpu-accel-vulkan}
@ -141,20 +145,22 @@ makes amdvlk the default driver and hides radv and lavapipe from the device list
A specific driver can be forced as follows:
```nix
hardware.opengl.extraPackages = [
pkgs.amdvlk
];
{
hardware.opengl.extraPackages = [
pkgs.amdvlk
];
# To enable Vulkan support for 32-bit applications, also add:
hardware.opengl.extraPackages32 = [
pkgs.driversi686Linux.amdvlk
];
# To enable Vulkan support for 32-bit applications, also add:
hardware.opengl.extraPackages32 = [
pkgs.driversi686Linux.amdvlk
];
# Force radv
environment.variables.AMD_VULKAN_ICD = "RADV";
# Or
environment.variables.VK_ICD_FILENAMES =
"/run/opengl-driver/share/vulkan/icd.d/radeon_icd.x86_64.json";
# Force radv
environment.variables.AMD_VULKAN_ICD = "RADV";
# Or
environment.variables.VK_ICD_FILENAMES =
"/run/opengl-driver/share/vulkan/icd.d/radeon_icd.x86_64.json";
}
```
## VA-API {#sec-gpu-accel-va-api}
@ -178,17 +184,21 @@ $ nix-shell -p libva-utils --run vainfo
Modern Intel GPUs use the iHD driver, which can be installed with:
```nix
hardware.opengl.extraPackages = [
intel-media-driver
];
{
hardware.opengl.extraPackages = [
intel-media-driver
];
}
```
Older Intel GPUs use the i965 driver, which can be installed with:
```nix
hardware.opengl.extraPackages = [
intel-vaapi-driver
];
{
hardware.opengl.extraPackages = [
intel-vaapi-driver
];
}
```
## Common issues {#sec-gpu-accel-common-issues}

View file

@ -5,18 +5,22 @@ configure network interfaces. However, you can configure an interface
manually as follows:
```nix
networking.interfaces.eth0.ipv4.addresses = [ {
address = "192.168.1.2";
prefixLength = 24;
} ];
{
networking.interfaces.eth0.ipv4.addresses = [ {
address = "192.168.1.2";
prefixLength = 24;
} ];
}
```
Typically you'll also want to set a default gateway and set of name
servers:
```nix
networking.defaultGateway = "192.168.1.1";
networking.nameservers = [ "8.8.8.8" ];
{
networking.defaultGateway = "192.168.1.1";
networking.nameservers = [ "8.8.8.8" ];
}
```
::: {.note}
@ -28,7 +32,9 @@ configuration is performed by `network-setup.service`.
The host name is set using [](#opt-networking.hostName):
```nix
networking.hostName = "cartman";
{
networking.hostName = "cartman";
}
```
The default host name is `nixos`. Set it to the empty string (`""`) to

View file

@ -9,34 +9,42 @@ may be overridden on a per-interface basis by
IPv6 support globally by setting:
```nix
networking.enableIPv6 = false;
{
networking.enableIPv6 = false;
}
```
You can disable IPv6 on a single interface using a normal sysctl (in
this example, we use interface `eth0`):
```nix
boot.kernel.sysctl."net.ipv6.conf.eth0.disable_ipv6" = true;
{
boot.kernel.sysctl."net.ipv6.conf.eth0.disable_ipv6" = true;
}
```
As with IPv4 networking interfaces are automatically configured via
DHCPv6. You can configure an interface manually:
```nix
networking.interfaces.eth0.ipv6.addresses = [ {
address = "fe00:aa:bb:cc::2";
prefixLength = 64;
} ];
{
networking.interfaces.eth0.ipv6.addresses = [ {
address = "fe00:aa:bb:cc::2";
prefixLength = 64;
} ];
}
```
For configuring a gateway, optionally with explicitly specified
interface:
```nix
networking.defaultGateway6 = {
address = "fe00::1";
interface = "enp0s3";
};
{
networking.defaultGateway6 = {
address = "fe00::1";
interface = "enp0s3";
};
}
```
See [](#sec-ipv4) for similar examples and additional information.

View file

@ -7,14 +7,16 @@ There are generally two ways of enabling Kubernetes on NixOS. One way is
to enable and configure cluster components appropriately by hand:
```nix
services.kubernetes = {
apiserver.enable = true;
controllerManager.enable = true;
scheduler.enable = true;
addonManager.enable = true;
proxy.enable = true;
flannel.enable = true;
};
{
services.kubernetes = {
apiserver.enable = true;
controllerManager.enable = true;
scheduler.enable = true;
addonManager.enable = true;
proxy.enable = true;
flannel.enable = true;
};
}
```
Another way is to assign cluster roles ("master" and/or "node") to
@ -22,20 +24,26 @@ the host. This enables apiserver, controllerManager, scheduler,
addonManager, kube-proxy and etcd:
```nix
services.kubernetes.roles = [ "master" ];
{
services.kubernetes.roles = [ "master" ];
}
```
While this will enable the kubelet and kube-proxy only:
```nix
services.kubernetes.roles = [ "node" ];
{
services.kubernetes.roles = [ "node" ];
}
```
Assigning both the master and node roles is usable if you want a single
node Kubernetes cluster for dev or testing purposes:
```nix
services.kubernetes.roles = [ "master" "node" ];
{
services.kubernetes.roles = [ "master" "node" ];
}
```
Note: Assigning either role will also default both

View file

@ -5,7 +5,9 @@ option `boot.kernelPackages`. For instance, this selects the Linux 3.10
kernel:
```nix
boot.kernelPackages = pkgs.linuxKernel.packages.linux_3_10;
{
boot.kernelPackages = pkgs.linuxKernel.packages.linux_3_10;
}
```
Note that this not only replaces the kernel, but also packages that are
@ -40,13 +42,15 @@ If you want to change the kernel configuration, you can use the
instance, to enable support for the kernel debugger KGDB:
```nix
nixpkgs.config.packageOverrides = pkgs: pkgs.lib.recursiveUpdate pkgs {
linuxKernel.kernels.linux_5_10 = pkgs.linuxKernel.kernels.linux_5_10.override {
extraConfig = ''
KGDB y
'';
{
nixpkgs.config.packageOverrides = pkgs: pkgs.lib.recursiveUpdate pkgs {
linuxKernel.kernels.linux_5_10 = pkgs.linuxKernel.kernels.linux_5_10.override {
extraConfig = ''
KGDB y
'';
};
};
};
}
```
`extraConfig` takes a list of Linux kernel configuration options, one
@ -59,14 +63,18 @@ by `udev`. You can force a module to be loaded via
[](#opt-boot.kernelModules), e.g.
```nix
boot.kernelModules = [ "fuse" "kvm-intel" "coretemp" ];
{
boot.kernelModules = [ "fuse" "kvm-intel" "coretemp" ];
}
```
If the module is required early during the boot (e.g. to mount the root
file system), you can use [](#opt-boot.initrd.kernelModules):
```nix
boot.initrd.kernelModules = [ "cifs" ];
{
boot.initrd.kernelModules = [ "cifs" ];
}
```
This causes the specified modules and their dependencies to be added to
@ -76,7 +84,9 @@ Kernel runtime parameters can be set through
[](#opt-boot.kernel.sysctl), e.g.
```nix
boot.kernel.sysctl."net.ipv4.tcp_keepalive_time" = 120;
{
boot.kernel.sysctl."net.ipv4.tcp_keepalive_time" = 120;
}
```
sets the kernel's TCP keepalive time to 120 seconds. To see the
@ -89,7 +99,9 @@ Please refer to the Nixpkgs manual for the various ways of [building a custom ke
To use your custom kernel package in your NixOS configuration, set
```nix
boot.kernelPackages = pkgs.linuxPackagesFor yourCustomKernel;
{
boot.kernelPackages = pkgs.linuxPackagesFor yourCustomKernel;
}
```
## Rust {#sec-linux-rust}
@ -99,15 +111,17 @@ default. For kernel versions 6.7 or newer, experimental Rust support
can be enabled. In a NixOS configuration, set:
```nix
boot.kernelPatches = [
{
name = "Rust Support";
patch = null;
features = {
rust = true;
};
}
];
{
boot.kernelPatches = [
{
name = "Rust Support";
patch = null;
features = {
rust = true;
};
}
];
}
```
## Developing kernel modules {#sec-linux-config-developing-modules}

View file

@ -29,15 +29,19 @@ system is automatically mounted at boot time as `/`, add the following
to `configuration.nix`:
```nix
boot.initrd.luks.devices.crypted.device = "/dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d";
fileSystems."/".device = "/dev/mapper/crypted";
{
boot.initrd.luks.devices.crypted.device = "/dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d";
fileSystems."/".device = "/dev/mapper/crypted";
}
```
Should grub be used as bootloader, and `/boot` is located on an
encrypted partition, it is necessary to add the following grub option:
```nix
boot.loader.grub.enableCryptodisk = true;
{
boot.loader.grub.enableCryptodisk = true;
}
```
## FIDO2 {#sec-luks-file-systems-fido2}
@ -68,8 +72,10 @@ To ensure that this file system is decrypted using the FIDO2 compatible
key, add the following to `configuration.nix`:
```nix
boot.initrd.luks.fido2Support = true;
boot.initrd.luks.devices."/dev/sda2".fido2.credential = "f1d00200108b9d6e849a8b388da457688e3dd653b4e53770012d8f28e5d3b269865038c346802f36f3da7278b13ad6a3bb6a1452e24ebeeaa24ba40eef559b1b287d2a2f80b7";
{
boot.initrd.luks.fido2Support = true;
boot.initrd.luks.devices."/dev/sda2".fido2.credential = "f1d00200108b9d6e849a8b388da457688e3dd653b4e53770012d8f28e5d3b269865038c346802f36f3da7278b13ad6a3bb6a1452e24ebeeaa24ba40eef559b1b287d2a2f80b7";
}
```
You can also use the FIDO2 passwordless setup, but for security reasons,
@ -77,7 +83,9 @@ you might want to enable it only when your device is PIN protected, such
as [Trezor](https://trezor.io/).
```nix
boot.initrd.luks.devices."/dev/sda2".fido2.passwordLess = true;
{
boot.initrd.luks.devices."/dev/sda2".fido2.passwordLess = true;
}
```
### systemd Stage 1 {#sec-luks-file-systems-fido2-systemd}
@ -88,13 +96,15 @@ unlocking the existing LUKS2 volume `root` using any enrolled FIDO2 compatible
tokens.
```nix
boot.initrd = {
luks.devices.root = {
crypttabExtraOpts = [ "fido2-device=auto" ];
device = "/dev/sda2";
{
boot.initrd = {
luks.devices.root = {
crypttabExtraOpts = [ "fido2-device=auto" ];
device = "/dev/sda2";
};
systemd.enable = true;
};
systemd.enable = true;
};
}
```
All tokens that should be used for unlocking the LUKS2-encrypted volume must

View file

@ -16,7 +16,7 @@ including them from `configuration.nix`, e.g.:
{ imports = [ ./vpn.nix ./kde.nix ];
services.httpd.enable = true;
environment.systemPackages = [ pkgs.emacs ];
...
# ...
}
```
@ -42,7 +42,9 @@ merged last, so for list-type options, it will appear at the end of the
merged list. If you want it to appear first, you can use `mkBefore`:
```nix
boot.kernelModules = mkBefore [ "kvm-intel" ];
{
boot.kernelModules = mkBefore [ "kvm-intel" ];
}
```
This causes the `kvm-intel` kernel module to be loaded before any other
@ -60,7 +62,9 @@ When that happens, it's possible to force one definition take precedence
over the others:
```nix
services.httpd.adminAddr = pkgs.lib.mkForce "bob@example.org";
{
services.httpd.adminAddr = pkgs.lib.mkForce "bob@example.org";
}
```
When using multiple modules, you may need to access configuration values

View file

@ -4,7 +4,9 @@ To facilitate network configuration, some desktop environments use
NetworkManager. You can enable NetworkManager by setting:
```nix
networking.networkmanager.enable = true;
{
networking.networkmanager.enable = true;
}
```
some desktop managers (e.g., GNOME) enable NetworkManager automatically
@ -14,7 +16,9 @@ All users that should have permission to change network settings must
belong to the `networkmanager` group:
```nix
users.users.alice.extraGroups = [ "networkmanager" ];
{
users.users.alice.extraGroups = [ "networkmanager" ];
}
```
NetworkManager is controlled using either `nmcli` or `nmtui`
@ -32,9 +36,11 @@ can be used together if desired. To do this you need to instruct
NetworkManager to ignore those interfaces like:
```nix
networking.networkmanager.unmanaged = [
"*" "except:type:wwan" "except:type:gsm"
];
{
networking.networkmanager.unmanaged = [
"*" "except:type:wwan" "except:type:gsm"
];
}
```
Refer to the option description for the exact syntax and references to

View file

@ -4,21 +4,23 @@ NixOS offers a convenient abstraction to create both read-only as well writable
overlays.
```nix
fileSystems = {
"/writable-overlay" = {
overlay = {
lowerdir = [ writableOverlayLowerdir ];
upperdir = "/.rw-writable-overlay/upper";
workdir = "/.rw-writable-overlay/work";
{
fileSystems = {
"/writable-overlay" = {
overlay = {
lowerdir = [ writableOverlayLowerdir ];
upperdir = "/.rw-writable-overlay/upper";
workdir = "/.rw-writable-overlay/work";
};
# Mount the writable overlay in the initrd.
neededForBoot = true;
};
# Mount the writable overlay in the initrd.
neededForBoot = true;
"/readonly-overlay".overlay.lowerdir = [
writableOverlayLowerdir
writableOverlayLowerdir2
];
};
"/readonly-overlay".overlay.lowerdir = [
writableOverlayLowerdir
writableOverlayLowerdir2
];
};
}
```
If `upperdir` and `workdir` are not null, they will be created before the

View file

@ -8,9 +8,11 @@ is to say, expected usage is to add them to the imports list of your
`/etc/configuration.nix` as such:
```nix
imports = [
<nixpkgs/nixos/modules/profiles/profile-name.nix>
];
{
imports = [
<nixpkgs/nixos/modules/profiles/profile-name.nix>
];
}
```
Even if some of these profiles seem only useful in the context of

View file

@ -25,10 +25,12 @@ we assign the name `wan` to the interface with MAC address
`52:54:00:12:01:01` using a netword link unit:
```nix
systemd.network.links."10-wan" = {
matchConfig.PermanentMACAddress = "52:54:00:12:01:01";
linkConfig.Name = "wan";
};
{
systemd.network.links."10-wan" = {
matchConfig.PermanentMACAddress = "52:54:00:12:01:01";
linkConfig.Name = "wan";
};
}
```
Note that links are directly read by udev, *not networkd*, and will work
@ -37,10 +39,12 @@ even if networkd is disabled.
Alternatively, we can use a plain old udev rule:
```nix
boot.initrd.services.udev.rules = ''
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", \
ATTR{address}=="52:54:00:12:01:01", KERNEL=="eth*", NAME="wan"
'';
{
boot.initrd.services.udev.rules = ''
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", \
ATTR{address}=="52:54:00:12:01:01", KERNEL=="eth*", NAME="wan"
'';
}
```
::: {.warning}

View file

@ -3,7 +3,9 @@
Secure shell (SSH) access to your machine can be enabled by setting:
```nix
services.openssh.enable = true;
{
services.openssh.enable = true;
}
```
By default, root logins using a password are disallowed. They can be
@ -14,6 +16,8 @@ You can declaratively specify authorised RSA/DSA public keys for a user
as follows:
```nix
users.users.alice.openssh.authorizedKeys.keys =
[ "ssh-dss AAAAB3NzaC1kc3MAAACBAPIkGWVEt4..." ];
{
users.users.alice.openssh.authorizedKeys.keys =
[ "ssh-dss AAAAB3NzaC1kc3MAAACBAPIkGWVEt4..." ];
}
```

View file

@ -21,9 +21,11 @@ Apache HTTP, setting [](#opt-services.httpd.adminAddr)
appropriately:
```nix
services.httpd.enable = true;
services.httpd.adminAddr = ...;
networking.firewall.allowedTCPPorts = [ 80 443 ];
{
services.httpd.enable = true;
services.httpd.adminAddr = "...";
networking.firewall.allowedTCPPorts = [ 80 443 ];
}
```
For a simple Subversion server with basic authentication, configure the
@ -34,25 +36,28 @@ the `.authz` file describing access permission, and `AuthUserFile` to
the password file.
```nix
services.httpd.extraModules = [
# note that order is *super* important here
{ name = "dav_svn"; path = "${pkgs.apacheHttpdPackages.subversion}/modules/mod_dav_svn.so"; }
{ name = "authz_svn"; path = "${pkgs.apacheHttpdPackages.subversion}/modules/mod_authz_svn.so"; }
];
services.httpd.virtualHosts = {
"svn" = {
hostName = HOSTNAME;
documentRoot = DOCUMENTROOT;
locations."/svn".extraConfig = ''
DAV svn
SVNParentPath REPO_PARENT
AuthzSVNAccessFile ACCESS_FILE
AuthName "SVN Repositories"
AuthType Basic
AuthUserFile PASSWORD_FILE
Require valid-user
'';
}
{
services.httpd.extraModules = [
# note that order is *super* important here
{ name = "dav_svn"; path = "${pkgs.apacheHttpdPackages.subversion}/modules/mod_dav_svn.so"; }
{ name = "authz_svn"; path = "${pkgs.apacheHttpdPackages.subversion}/modules/mod_authz_svn.so"; }
];
services.httpd.virtualHosts = {
"svn" = {
hostName = HOSTNAME;
documentRoot = DOCUMENTROOT;
locations."/svn".extraConfig = ''
DAV svn
SVNParentPath REPO_PARENT
AuthzSVNAccessFile ACCESS_FILE
AuthName "SVN Repositories"
AuthType Basic
AuthUserFile PASSWORD_FILE
Require valid-user
'';
};
};
}
```
The key `"svn"` is just a symbolic name identifying the virtual host.
@ -90,7 +95,7 @@ $ htpasswd -s PASSWORD_FILE USER_NAME
The file describing access permissions `ACCESS_FILE` will look something
like the following:
```nix
```
[/]
* = r

View file

@ -6,13 +6,15 @@ management. In the declarative style, users are specified in
account named `alice` shall exist:
```nix
users.users.alice = {
isNormalUser = true;
home = "/home/alice";
description = "Alice Foobar";
extraGroups = [ "wheel" "networkmanager" ];
openssh.authorizedKeys.keys = [ "ssh-dss AAAAB3Nza... alice@foobar" ];
};
{
users.users.alice = {
isNormalUser = true;
home = "/home/alice";
description = "Alice Foobar";
extraGroups = [ "wheel" "networkmanager" ];
openssh.authorizedKeys.keys = [ "ssh-dss AAAAB3Nza... alice@foobar" ];
};
}
```
Note that `alice` is a member of the `wheel` and `networkmanager`
@ -38,7 +40,9 @@ A user ID (uid) is assigned automatically. You can also specify a uid
manually by adding
```nix
uid = 1000;
{
uid = 1000;
}
```
to the user specification.
@ -47,7 +51,9 @@ Groups can be specified similarly. The following states that a group
named `students` shall exist:
```nix
users.groups.students.gid = 1000;
{
users.groups.students.gid = 1000;
}
```
As with users, the group ID (gid) is optional and will be assigned
@ -100,7 +106,9 @@ Instead of using a custom perl script to create users and groups, you can use
systemd-sysusers:
```nix
systemd.sysusers.enable = true;
{
systemd.sysusers.enable = true;
}
```
The primary benefit of this is to remove a dependency on perl.

View file

@ -9,7 +9,9 @@ a Wayland Compositor such as sway without separately enabling a Wayland
server:
```nix
{
programs.sway.enable = true;
}
```
This installs the sway compositor along with some essential utilities.
@ -19,7 +21,9 @@ If you are using a wlroots-based compositor, like sway, and want to be
able to share your screen, you might want to activate this option:
```nix
xdg.portal.wlr.enable = true;
{
xdg.portal.wlr.enable = true;
}
```
and configure Pipewire using

View file

@ -7,25 +7,29 @@ skip the rest of this section on wireless networks.
NixOS will start wpa_supplicant for you if you enable this setting:
```nix
networking.wireless.enable = true;
{
networking.wireless.enable = true;
}
```
NixOS lets you specify networks for wpa_supplicant declaratively:
```nix
networking.wireless.networks = {
echelon = { # SSID with no spaces or special characters
psk = "abcdefgh";
{
networking.wireless.networks = {
echelon = { # SSID with no spaces or special characters
psk = "abcdefgh";
};
"echelon's AP" = { # SSID with spaces and/or special characters
psk = "ijklmnop";
};
echelon = { # Hidden SSID
hidden = true;
psk = "qrstuvwx";
};
free.wifi = {}; # Public wireless network
};
"echelon's AP" = { # SSID with spaces and/or special characters
psk = "ijklmnop";
};
echelon = { # Hidden SSID
hidden = true;
psk = "qrstuvwx";
};
free.wifi = {}; # Public wireless network
};
}
```
Be aware that keys will be written to the nix store in plaintext! When
@ -46,11 +50,13 @@ network={
```
```nix
networking.wireless.networks = {
echelon = {
pskRaw = "dca6d6ed41f4ab5a984c9f55f6f66d4efdc720ebf66959810f4329bb391c5435";
{
networking.wireless.networks = {
echelon = {
pskRaw = "dca6d6ed41f4ab5a984c9f55f6f66d4efdc720ebf66959810f4329bb391c5435";
};
};
};
}
```
or you can use it to directly generate the `wpa_supplicant.conf`:

View file

@ -4,7 +4,9 @@ The X Window System (X11) provides the basis of NixOS' graphical user
interface. It can be enabled as follows:
```nix
services.xserver.enable = true;
{
services.xserver.enable = true;
}
```
The X server will automatically detect and use the appropriate video
@ -12,7 +14,9 @@ driver from a set of X.org drivers (such as `vesa` and `intel`). You can
also specify a driver manually, e.g.
```nix
services.xserver.videoDrivers = [ "r128" ];
{
services.xserver.videoDrivers = [ "r128" ];
}
```
to enable X.org's `xf86-video-r128` driver.
@ -22,15 +26,17 @@ Otherwise, you can only log into a plain undecorated `xterm` window.
Thus you should pick one or more of the following lines:
```nix
services.xserver.desktopManager.plasma5.enable = true;
services.xserver.desktopManager.xfce.enable = true;
services.xserver.desktopManager.gnome.enable = true;
services.xserver.desktopManager.mate.enable = true;
services.xserver.windowManager.xmonad.enable = true;
services.xserver.windowManager.twm.enable = true;
services.xserver.windowManager.icewm.enable = true;
services.xserver.windowManager.i3.enable = true;
services.xserver.windowManager.herbstluftwm.enable = true;
{
services.xserver.desktopManager.plasma5.enable = true;
services.xserver.desktopManager.xfce.enable = true;
services.xserver.desktopManager.gnome.enable = true;
services.xserver.desktopManager.mate.enable = true;
services.xserver.windowManager.xmonad.enable = true;
services.xserver.windowManager.twm.enable = true;
services.xserver.windowManager.icewm.enable = true;
services.xserver.windowManager.i3.enable = true;
services.xserver.windowManager.herbstluftwm.enable = true;
}
```
NixOS's default *display manager* (the program that provides a graphical
@ -38,22 +44,28 @@ login prompt and manages the X server) is LightDM. You can select an
alternative one by picking one of the following lines:
```nix
services.xserver.displayManager.sddm.enable = true;
services.xserver.displayManager.gdm.enable = true;
{
services.xserver.displayManager.sddm.enable = true;
services.xserver.displayManager.gdm.enable = true;
}
```
You can set the keyboard layout (and optionally the layout variant):
```nix
services.xserver.xkb.layout = "de";
services.xserver.xkb.variant = "neo";
{
services.xserver.xkb.layout = "de";
services.xserver.xkb.variant = "neo";
}
```
The X server is started automatically at boot time. If you don't want
this to happen, you can set:
```nix
services.xserver.autorun = false;
{
services.xserver.autorun = false;
}
```
The X server can then be started manually:
@ -66,7 +78,9 @@ On 64-bit systems, if you want OpenGL for 32-bit programs such as in
Wine, you should also set the following:
```nix
hardware.opengl.driSupport32Bit = true;
{
hardware.opengl.driSupport32Bit = true;
}
```
## Auto-login {#sec-x11-auto-login}
@ -84,16 +98,20 @@ desktop environment. If you wanted no desktop environment and i3 as your
your window manager, you'd define:
```nix
services.xserver.displayManager.defaultSession = "none+i3";
{
services.xserver.displayManager.defaultSession = "none+i3";
}
```
Every display manager in NixOS supports auto-login, here is an example
using lightdm for a user `alice`:
```nix
services.xserver.displayManager.lightdm.enable = true;
services.xserver.displayManager.autoLogin.enable = true;
services.xserver.displayManager.autoLogin.user = "alice";
{
services.xserver.displayManager.lightdm.enable = true;
services.xserver.displayManager.autoLogin.enable = true;
services.xserver.displayManager.autoLogin.user = "alice";
}
```
## Intel Graphics drivers {#sec-x11--graphics-cards-intel}
@ -119,18 +137,22 @@ drivers. Use the option
to set one. The recommended configuration for modern systems is:
```nix
services.xserver.videoDrivers = [ "modesetting" ];
{
services.xserver.videoDrivers = [ "modesetting" ];
}
```
If you experience screen tearing no matter what, this configuration was
reported to resolve the issue:
```nix
services.xserver.videoDrivers = [ "intel" ];
services.xserver.deviceSection = ''
Option "DRI" "2"
Option "TearFree" "true"
'';
{
services.xserver.videoDrivers = [ "intel" ];
services.xserver.deviceSection = ''
Option "DRI" "2"
Option "TearFree" "true"
'';
}
```
Note that this will likely downgrade the performance compared to
@ -143,15 +165,19 @@ better 3D performance than the X.org drivers. It is not enabled by
default because it's not free software. You can enable it as follows:
```nix
services.xserver.videoDrivers = [ "nvidia" ];
{
services.xserver.videoDrivers = [ "nvidia" ];
}
```
If you have an older card, you may have to use one of the legacy drivers:
```nix
hardware.nvidia.package = config.boot.kernelPackages.nvidiaPackages.legacy_470;
hardware.nvidia.package = config.boot.kernelPackages.nvidiaPackages.legacy_390;
hardware.nvidia.package = config.boot.kernelPackages.nvidiaPackages.legacy_340;
{
hardware.nvidia.package = config.boot.kernelPackages.nvidiaPackages.legacy_470;
hardware.nvidia.package = config.boot.kernelPackages.nvidiaPackages.legacy_390;
hardware.nvidia.package = config.boot.kernelPackages.nvidiaPackages.legacy_340;
}
```
You may need to reboot after enabling this driver to prevent a clash
@ -166,7 +192,9 @@ performance. If you still want to use it anyway, you need to explicitly
set:
```nix
services.xserver.videoDrivers = [ "amdgpu-pro" ];
{
services.xserver.videoDrivers = [ "amdgpu-pro" ];
}
```
You will need to reboot after enabling this driver to prevent a clash
@ -178,14 +206,18 @@ Support for Synaptics touchpads (found in many laptops such as the Dell
Latitude series) can be enabled as follows:
```nix
services.xserver.libinput.enable = true;
{
services.xserver.libinput.enable = true;
}
```
The driver has many options (see [](#ch-options)).
For instance, the following disables tap-to-click behavior:
```nix
services.xserver.libinput.touchpad.tapping = false;
{
services.xserver.libinput.touchpad.tapping = false;
}
```
Note: the use of `services.xserver.synaptics` is deprecated since NixOS
@ -198,9 +230,11 @@ GTK themes can be installed either to user profile or system-wide (via
GTK ones, you can use the following configuration:
```nix
qt.enable = true;
qt.platformTheme = "gtk2";
qt.style = "gtk2";
{
qt.enable = true;
qt.platformTheme = "gtk2";
qt.style = "gtk2";
}
```
## Custom XKB layouts {#custom-xkb-layouts}
@ -217,7 +251,7 @@ Create a file called `us-greek` with the following content (under a
directory called `symbols`; it's an XKB peculiarity that will help with
testing):
```nix
```
xkb_symbols "us-greek"
{
include "us(basic)" // includes the base US keys
@ -234,11 +268,13 @@ xkb_symbols "us-greek"
A minimal layout specification must include the following:
```nix
services.xserver.xkb.extraLayouts.us-greek = {
description = "US layout with alt-gr greek";
languages = [ "eng" ];
symbolsFile = /yourpath/symbols/us-greek;
};
{
services.xserver.xkb.extraLayouts.us-greek = {
description = "US layout with alt-gr greek";
languages = [ "eng" ];
symbolsFile = /yourpath/symbols/us-greek;
};
}
```
::: {.note}
@ -275,7 +311,7 @@ Use the *xev* utility from `pkgs.xorg.xev` to find the codes of the keys
of interest, then create a `media-key` file to hold the keycodes
definitions
```nix
```
xkb_keycodes "media"
{
<volUp> = 123;
@ -285,7 +321,7 @@ xkb_keycodes "media"
Now use the newly define keycodes in `media-sym`:
```nix
```
xkb_symbols "media"
{
key.type = "ONE_LEVEL";
@ -297,12 +333,14 @@ xkb_symbols "media"
As before, to install the layout do
```nix
services.xserver.xkb.extraLayouts.media = {
description = "Multimedia keys remapping";
languages = [ "eng" ];
symbolsFile = /path/to/media-key;
keycodesFile = /path/to/media-sym;
};
{
services.xserver.xkb.extraLayouts.media = {
description = "Multimedia keys remapping";
languages = [ "eng" ];
symbolsFile = /path/to/media-key;
keycodesFile = /path/to/media-sym;
};
}
```
::: {.note}
@ -318,7 +356,9 @@ workaround, you can set the keymap using `setxkbmap` at the start of the
session with:
```nix
services.xserver.displayManager.sessionCommands = "setxkbmap -keycodes media";
{
services.xserver.displayManager.sessionCommands = "setxkbmap -keycodes media";
}
```
If you are manually starting the X server, you should set the argument

View file

@ -3,21 +3,25 @@
To enable the Xfce Desktop Environment, set
```nix
services.xserver.desktopManager.xfce.enable = true;
services.xserver.displayManager.defaultSession = "xfce";
{
services.xserver.desktopManager.xfce.enable = true;
services.xserver.displayManager.defaultSession = "xfce";
}
```
Optionally, *picom* can be enabled for nice graphical effects, some
example settings:
```nix
services.picom = {
enable = true;
fade = true;
inactiveOpacity = 0.9;
shadow = true;
fadeDelta = 4;
};
{
services.picom = {
enable = true;
fade = true;
inactiveOpacity = 0.9;
shadow = true;
fadeDelta = 4;
};
}
```
Some Xfce programs are not installed automatically. To install them

View file

@ -17,13 +17,15 @@ activation script will take these dependencies into account and order the
snippets accordingly. As a simple example:
```nix
system.activationScripts.my-activation-script = {
deps = [ "etc" ];
# supportsDryActivation = true;
text = ''
echo "Hallo i bims"
'';
};
{
system.activationScripts.my-activation-script = {
deps = [ "etc" ];
# supportsDryActivation = true;
text = ''
echo "Hallo i bims"
'';
};
}
```
This example creates an activation script snippet that is run after the `etc`

View file

@ -18,7 +18,7 @@ This is an example of using `warnings`.
This is known to cause some specific problems in certain situations.
'' ]
else [];
}
};
}
```
@ -35,6 +35,6 @@ This example, extracted from the [`syslogd` module](https://github.com/NixOS/nix
message = "rsyslogd conflicts with syslogd";
}
];
}
};
}
```

View file

@ -9,7 +9,9 @@ Instead of using a custom perl script to activate `/etc`, you activate it via an
overlay filesystem:
```nix
system.etc.overlay.enable = true;
{
system.etc.overlay.enable = true;
}
```
Using an overlay has two benefits:
@ -22,7 +24,9 @@ upper layer). However, you can also mount `/etc` immutably (i.e. read-only) by
setting:
```nix
system.etc.overlay.mutable = false;
{
system.etc.overlay.mutable = false;
}
```
The overlay is atomically replaced during system switch. However, files that

View file

@ -14,11 +14,11 @@ file.
{ config, lib, pkgs, ... }:
{
options = {
...
# ...
};
config = {
...
# ...
};
meta = {

View file

@ -9,7 +9,7 @@ profile:
```nix
{ modulesPath, ... }: {
imports = [ "${modulesPath}/profiles/image-based-appliance.nix" ]
imports = [ "${modulesPath}/profiles/image-based-appliance.nix" ];
}
```

View file

@ -6,14 +6,16 @@ hasn't been declared in any module. An option declaration generally
looks like this:
```nix
options = {
name = mkOption {
type = type specification;
default = default value;
example = example value;
description = lib.mdDoc "Description for use in the NixOS manual.";
{
options = {
name = mkOption {
type = type specification;
default = default value;
example = example value;
description = lib.mdDoc "Description for use in the NixOS manual.";
};
};
};
}
```
The attribute names within the `name` attribute path must be camel
@ -221,28 +223,34 @@ enforces that there can only be a single display manager enabled.
::: {#ex-option-declaration-eot-service .example}
### Extensible type placeholder in the service module
```nix
services.xserver.displayManager.enable = mkOption {
description = "Display manager to use";
type = with types; nullOr (enum [ ]);
};
{
services.xserver.displayManager.enable = mkOption {
description = "Display manager to use";
type = with types; nullOr (enum [ ]);
};
}
```
:::
::: {#ex-option-declaration-eot-backend-gdm .example}
### Extending `services.xserver.displayManager.enable` in the `gdm` module
```nix
services.xserver.displayManager.enable = mkOption {
type = with types; nullOr (enum [ "gdm" ]);
};
{
services.xserver.displayManager.enable = mkOption {
type = with types; nullOr (enum [ "gdm" ]);
};
}
```
:::
::: {#ex-option-declaration-eot-backend-sddm .example}
### Extending `services.xserver.displayManager.enable` in the `sddm` module
```nix
services.xserver.displayManager.enable = mkOption {
type = with types; nullOr (enum [ "sddm" ]);
};
{
services.xserver.displayManager.enable = mkOption {
type = with types; nullOr (enum [ "sddm" ]);
};
}
```
:::

View file

@ -4,9 +4,11 @@ Option definitions are generally straight-forward bindings of values to
option names, like
```nix
config = {
services.httpd.enable = true;
};
{
config = {
services.httpd.enable = true;
};
}
```
However, sometimes you need to wrap an option definition or set of
@ -18,10 +20,12 @@ If a set of option definitions is conditional on the value of another
option, you may need to use `mkIf`. Consider, for instance:
```nix
config = if config.services.httpd.enable then {
environment.systemPackages = [ ... ];
...
} else {};
{
config = if config.services.httpd.enable then {
environment.systemPackages = [ /* ... */ ];
# ...
} else {};
}
```
This definition will cause Nix to fail with an "infinite recursion"
@ -30,30 +34,36 @@ on the value being constructed here. After all, you could also write the
clearly circular and contradictory:
```nix
config = if config.services.httpd.enable then {
services.httpd.enable = false;
} else {
services.httpd.enable = true;
};
{
config = if config.services.httpd.enable then {
services.httpd.enable = false;
} else {
services.httpd.enable = true;
};
}
```
The solution is to write:
```nix
config = mkIf config.services.httpd.enable {
environment.systemPackages = [ ... ];
...
};
{
config = mkIf config.services.httpd.enable {
environment.systemPackages = [ /* ... */ ];
# ...
};
}
```
The special function `mkIf` causes the evaluation of the conditional to
be "pushed down" into the individual definitions, as if you had written:
```nix
config = {
environment.systemPackages = if config.services.httpd.enable then [ ... ] else [];
...
};
{
config = {
environment.systemPackages = if config.services.httpd.enable then [ /* ... */ ] else [];
# ...
};
}
```
## Setting Priorities {#sec-option-definitions-setting-priorities}
@ -65,7 +75,9 @@ priority 100 and option defaults have priority 1500.
You can specify an explicit priority by using `mkOverride`, e.g.
```nix
services.openssh.enable = mkOverride 10 false;
{
services.openssh.enable = mkOverride 10 false;
}
```
This definition causes all other definitions with priorities above 10 to
@ -80,7 +92,9 @@ The functions `mkBefore` and `mkAfter` are equal to `mkOrder 500` and `mkOrder 1
As an example,
```nix
hardware.firmware = mkBefore [ myFirmware ];
{
hardware.firmware = mkBefore [ myFirmware ];
}
```
This definition ensures that `myFirmware` comes before other unordered
@ -97,13 +111,15 @@ they were declared in separate modules. This can be done using
`mkMerge`:
```nix
config = mkMerge
[ # Unconditional stuff.
{ environment.systemPackages = [ ... ];
}
# Conditional stuff.
(mkIf config.services.bla.enable {
environment.systemPackages = [ ... ];
})
];
{
config = mkMerge
[ # Unconditional stuff.
{ environment.systemPackages = [ /* ... */ ];
}
# Conditional stuff.
(mkIf config.services.bla.enable {
environment.systemPackages = [ /* ... */ ];
})
];
}
```

View file

@ -374,19 +374,21 @@ if you want to allow users to leave it undefined.
::: {#ex-submodule-direct .example}
### Directly defined submodule
```nix
options.mod = mkOption {
description = "submodule example";
type = with types; submodule {
options = {
foo = mkOption {
type = int;
};
bar = mkOption {
type = str;
{
options.mod = mkOption {
description = "submodule example";
type = with types; submodule {
options = {
foo = mkOption {
type = int;
};
bar = mkOption {
type = str;
};
};
};
};
};
}
```
:::
@ -405,10 +407,12 @@ let
};
};
in
options.mod = mkOption {
description = "submodule example";
type = with types; submodule modOptions;
};
{
options.mod = mkOption {
description = "submodule example";
type = with types; submodule modOptions;
};
}
```
:::
@ -421,29 +425,33 @@ multiple definitions of the submodule option set
::: {#ex-submodule-listof-declaration .example}
### Declaration of a list of submodules
```nix
options.mod = mkOption {
description = "submodule example";
type = with types; listOf (submodule {
options = {
foo = mkOption {
type = int;
{
options.mod = mkOption {
description = "submodule example";
type = with types; listOf (submodule {
options = {
foo = mkOption {
type = int;
};
bar = mkOption {
type = str;
};
};
bar = mkOption {
type = str;
};
};
});
};
});
};
}
```
:::
::: {#ex-submodule-listof-definition .example}
### Definition of a list of submodules
```nix
config.mod = [
{ foo = 1; bar = "one"; }
{ foo = 2; bar = "two"; }
];
{
config.mod = [
{ foo = 1; bar = "one"; }
{ foo = 2; bar = "two"; }
];
}
```
:::
@ -455,27 +463,31 @@ multiple named definitions of the submodule option set
::: {#ex-submodule-attrsof-declaration .example}
### Declaration of attribute sets of submodules
```nix
options.mod = mkOption {
description = "submodule example";
type = with types; attrsOf (submodule {
options = {
foo = mkOption {
type = int;
{
options.mod = mkOption {
description = "submodule example";
type = with types; attrsOf (submodule {
options = {
foo = mkOption {
type = int;
};
bar = mkOption {
type = str;
};
};
bar = mkOption {
type = str;
};
};
});
};
});
};
}
```
:::
::: {#ex-submodule-attrsof-definition .example}
### Definition of attribute sets of submodules
```nix
config.mod.one = { foo = 1; bar = "one"; };
config.mod.two = { foo = 2; bar = "two"; };
{
config.mod.one = { foo = 1; bar = "one"; };
config.mod.two = { foo = 2; bar = "two"; };
}
```
:::
@ -495,10 +507,12 @@ Types are mainly characterized by their `check` and `merge` functions.
### Adding a type check
```nix
byte = mkOption {
description = "An integer between 0 and 255.";
type = types.addCheck types.int (x: x >= 0 && x <= 255);
};
{
byte = mkOption {
description = "An integer between 0 and 255.";
type = types.addCheck types.int (x: x >= 0 && x <= 255);
};
}
```
:::
@ -506,12 +520,14 @@ Types are mainly characterized by their `check` and `merge` functions.
### Overriding a type check
```nix
nixThings = mkOption {
description = "words that start with 'nix'";
type = types.str // {
check = (x: lib.hasPrefix "nix" x)
{
nixThings = mkOption {
description = "words that start with 'nix'";
type = types.str // {
check = (x: lib.hasPrefix "nix" x);
};
};
};
}
```
:::

View file

@ -248,28 +248,30 @@ up in the manual.
::: {#ex-settings-typed-attrs .example}
### Declaring a type-checked `settings` attribute
```nix
settings = lib.mkOption {
type = lib.types.submodule {
{
settings = lib.mkOption {
type = lib.types.submodule {
freeformType = settingsFormat.type;
freeformType = settingsFormat.type;
# Declare an option for the port such that the type is checked and this option
# is shown in the manual.
options.port = lib.mkOption {
type = lib.types.port;
default = 8080;
description = ''
Which port this service should listen on.
'';
};
# Declare an option for the port such that the type is checked and this option
# is shown in the manual.
options.port = lib.mkOption {
type = lib.types.port;
default = 8080;
description = ''
Which port this service should listen on.
'';
};
default = {};
description = ''
Configuration for Foo, see
<link xlink:href="https://example.com/docs/foo"/>
for supported values.
'';
};
default = {};
description = ''
Configuration for Foo, see
<link xlink:href="https://example.com/docs/foo"/>
for supported values.
'';
};
}
```
:::

View file

@ -94,11 +94,13 @@ To make an existing sysinit service restart correctly during system switch, you
have to declare:
```nix
systemd.services.my-sysinit = {
requiredBy = [ "sysinit-reactivation.target" ];
before = [ "sysinit-reactivation.target" ];
restartTriggers = [ config.environment.etc."my-sysinit.d".source ];
};
{
systemd.services.my-sysinit = {
requiredBy = [ "sysinit-reactivation.target" ];
before = [ "sysinit-reactivation.target" ];
restartTriggers = [ config.environment.etc."my-sysinit.d".source ];
};
}
```
You need to configure appropriate `restartTriggers` specific to your service.

View file

@ -28,7 +28,7 @@ NixOS modules:
```nix
{ config, pkgs, ... }:
{ option definitions
{ # option definitions
}
```
@ -43,15 +43,15 @@ is shown in [Example: Structure of NixOS Modules](#ex-module-syntax).
{
imports =
[ paths of other modules
[ # paths of other modules
];
options = {
option declarations
# option declarations
};
config = {
option definitions
# option definitions
};
}
```

View file

@ -8,10 +8,10 @@ A NixOS test is a module that has the following structure:
# One or more machines:
nodes =
{ machine =
{ config, pkgs, ... }: { };
{ config, pkgs, ... }: { /* ... */ };
machine2 =
{ config, pkgs, ... }: { };
{ config, pkgs, ... }: { /* ... */ };
#
};
testScript =
@ -46,16 +46,20 @@ Tests are invoked differently depending on whether the test is part of NixOS or
Tests that are part of NixOS are added to [`nixos/tests/all-tests.nix`](https://github.com/NixOS/nixpkgs/blob/master/nixos/tests/all-tests.nix).
```nix
{
hostname = runTest ./hostname.nix;
}
```
Overrides can be added by defining an anonymous module in `all-tests.nix`.
```nix
{
hostname = runTest {
imports = [ ./hostname.nix ];
defaults.networking.firewall.enable = false;
};
}
```
You can run a test with attribute name `hostname` in `nixos/tests/all-tests.nix` by invoking:
@ -161,7 +165,7 @@ For faster dev cycles it's also possible to disable the code-linters
skipLint = true;
nodes.machine =
{ config, pkgs, ... }:
{ configuration…
{ # configuration…
};
testScript =
@ -177,12 +181,14 @@ linter directly (again, don't commit this within the Nixpkgs
repository):
```nix
{
testScript =
''
# fmt: off
Python code…
# fmt: on
'';
}
```
Similarly, the type checking of test scripts can be disabled in the following
@ -193,7 +199,7 @@ way:
skipTypeCheck = true;
nodes.machine =
{ config, pkgs, ... }:
{ configuration…
{ # configuration…
};
}
```

View file

@ -18,11 +18,11 @@ An example of how to build an image:
partitions = {
"esp" = {
contents = {
...
# ...
};
repartConfig = {
Type = "esp";
...
# ...
};
};
"root" = {
@ -30,7 +30,7 @@ An example of how to build an image:
repartConfig = {
Type = "root";
Label = "nixos";
...
# ...
};
};
};
@ -47,19 +47,21 @@ determined by the mount point, you have to set `stripNixStorePrefix = true;` so
that the prefix is stripped from the paths before copying them into the image.
```nix
fileSystems."/nix/store".device = "/dev/disk/by-partlabel/nix-store"
{
fileSystems."/nix/store".device = "/dev/disk/by-partlabel/nix-store";
image.repart.partitions = {
"store" = {
storePaths = [ config.system.build.toplevel ];
stripNixStorePrefix = true;
repartConfig = {
Type = "linux-generic";
Label = "nix-store";
...
image.repart.partitions = {
"store" = {
storePaths = [ config.system.build.toplevel ];
stripNixStorePrefix = true;
repartConfig = {
Type = "linux-generic";
Label = "nix-store";
# ...
};
};
};
};
}
```
## Appliance Image {#sec-image-repart-appliance}

View file

@ -87,7 +87,9 @@ set `mutableUsers = false`. Another way is to temporarily add the
following to your configuration:
```nix
users.users.your-user.initialHashedPassword = "test";
{
users.users.your-user.initialHashedPassword = "test";
}
```
*Important:* delete the \$hostname.qcow2 file if you have started the

View file

@ -7,8 +7,10 @@ To install NixOS behind a proxy, do the following before running
keep the internet accessible after reboot.
```nix
networking.proxy.default = "http://user:password@proxy:port/";
networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";
{
networking.proxy.default = "http://user:password@proxy:port/";
networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";
}
```
1. Setup the proxy environment variables in the shell where you are

View file

@ -89,12 +89,14 @@ The first steps to all these are the same:
want to add something like this to your `configuration.nix`:
```nix
boot.loader.grub.extraEntries = ''
menuentry "Ubuntu" {
search --set=ubuntu --fs-uuid 3cc3e652-0c1f-4800-8451-033754f68e6e
configfile "($ubuntu)/boot/grub/grub.cfg"
}
'';
{
boot.loader.grub.extraEntries = ''
menuentry "Ubuntu" {
search --set=ubuntu --fs-uuid 3cc3e652-0c1f-4800-8451-033754f68e6e
configfile "($ubuntu)/boot/grub/grub.cfg"
}
'';
}
```
(You can find the appropriate UUID for your partition in
@ -164,7 +166,9 @@ The first steps to all these are the same:
`sudo passwd -l root` if you use `sudo`)
```nix
users.users.root.initialHashedPassword = "";
{
users.users.root.initialHashedPassword = "";
}
```
1. Build the NixOS closure and install it in the `system` profile:

View file

@ -29,14 +29,18 @@ There are a few modifications you should make in configuration.nix.
Enable booting:
```nix
boot.loader.grub.device = "/dev/sda";
{
boot.loader.grub.device = "/dev/sda";
}
```
Also remove the fsck that runs at startup. It will always fail to run,
stopping your boot until you press `*`.
```nix
boot.initrd.checkJournalingFS = false;
{
boot.initrd.checkJournalingFS = false;
}
```
Shared folders can be given a name and a path in the host system in the

View file

@ -101,8 +101,10 @@ You can keep a NixOS system up-to-date automatically by adding the
following to `configuration.nix`:
```nix
system.autoUpgrade.enable = true;
system.autoUpgrade.allowReboot = true;
{
system.autoUpgrade.enable = true;
system.autoUpgrade.allowReboot = true;
}
```
This enables a periodically executed systemd service named
@ -114,5 +116,7 @@ the new generation contains a different kernel, initrd or kernel
modules. You can also specify a channel explicitly, e.g.
```nix
system.autoUpgrade.channel = "https://channels.nixos.org/nixos-23.11";
{
system.autoUpgrade.channel = "https://channels.nixos.org/nixos-23.11";
}
```

View file

@ -253,9 +253,9 @@ Installing Haskell _libraries_ this way, however, is no longer supported. See th
{
options = {
foo = mkOption { };
foo = mkOption { /* … */ };
};
config = mkIf config.foo { };
config = mkIf config.foo { /* … */ };
}
```
@ -268,9 +268,9 @@ Installing Haskell _libraries_ this way, however, is no longer supported. See th
{
options = {
foo = mkOption { option declaration };
foo = mkOption { /* option declaration */ };
};
config = mkIf config.foo { option definition };
config = mkIf config.foo { /* option definition */ };
}
```

View file

@ -246,7 +246,7 @@ When upgrading from a previous release, please be aware of the following incompa
let
pkgs = import <nixpkgs> {};
in
pkgs.overridePackages (self: super: ...)
pkgs.overridePackages (self: super: { /* ... */ })
```
should be replaced by:
@ -255,7 +255,7 @@ When upgrading from a previous release, please be aware of the following incompa
let
pkgs = import <nixpkgs> {};
in
import pkgs.path { overlays = [(self: super: ...)]; }
import pkgs.path { overlays = [(self: super: { /* ... */ })]; }
```
- Autoloading connection tracking helpers is now disabled by default. This default was also changed in the Linux kernel and is considered insecure if not configured properly in your firewall. If you need connection tracking helpers (i.e. for active FTP) please enable `networking.firewall.autoLoadConntrackHelpers` and tune `networking.firewall.connectionTrackingModules` to suit your needs.

View file

@ -334,22 +334,18 @@ When upgrading from a previous release, please be aware of the following incompa
- The remaining configuration flags can now be set directly on the `php` attribute. For example, instead of
```nix
{
php.override {
config.php.embed = true;
config.php.apxs2 = false;
}
php.override {
config.php.embed = true;
config.php.apxs2 = false;
}
```
you should now write
```nix
{
php.override {
embedSupport = true;
apxs2Support = false;
}
php.override {
embedSupport = true;
apxs2Support = false;
}
```
@ -383,9 +379,10 @@ When upgrading from a previous release, please be aware of the following incompa
{
specialisation.example-sub-configuration = {
configuration = {
...
# ...
};
};
};
}
```
Replace a `nesting.children` entry with:
@ -395,9 +392,10 @@ When upgrading from a previous release, please be aware of the following incompa
specialisation.example-sub-configuration = {
inheritParentConfig = false;
configuration = {
...
# ...
};
};
};
}
```
To switch to a specialised configuration at runtime you need to run:
@ -469,7 +467,7 @@ When upgrading from a previous release, please be aware of the following incompa
services.bitcoind = {
enable = true;
extraConfig = "...";
...
# ...
};
}
```
@ -483,7 +481,7 @@ When upgrading from a previous release, please be aware of the following incompa
dataDir = "/var/lib/bitcoind";
user = "bitcoin";
extraConfig = "...";
...
# ...
};
}
```
@ -502,7 +500,7 @@ When upgrading from a previous release, please be aware of the following incompa
{
services.dokuwiki = {
enable = true;
...
# ...
};
}
```
@ -517,7 +515,7 @@ When upgrading from a previous release, please be aware of the following incompa
forceSSL = true;
enableACME = true;
};
...
# ...
};
}
```

View file

@ -462,6 +462,7 @@ In addition to numerous new and upgraded packages, this release has the followin
Before:
```nix
{
services.keycloak = {
enable = true;
httpPort = "8080";
@ -471,10 +472,12 @@ In addition to numerous new and upgraded packages, this release has the followin
"subsystem=undertow"."server=default-server"."http-listener=default".proxy-address-forwarding = true;
};
};
}
```
After:
```nix
{
services.keycloak = {
enable = true;
settings = {
@ -485,6 +488,7 @@ In addition to numerous new and upgraded packages, this release has the followin
};
database.passwordFile = "/run/keys/db_password";
};
}
```
- The MoinMoin wiki engine (`services.moinmoin`) has been removed, because Python 2 is being retired from nixpkgs.

View file

@ -255,9 +255,11 @@ In addition to numerous new and upgraded packages, this release includes the fol
- `services.github-runner` and `services.github-runners.<name>` gained the option `serviceOverrides` which allows overriding the systemd `serviceConfig`. If you have been overriding the systemd service configuration (i.e., by defining `systemd.services.github-runner.serviceConfig`), you have to use the `serviceOverrides` option now. Example:
```nix
services.github-runner.serviceOverrides.SupplementaryGroups = [
"docker"
];
{
services.github-runner.serviceOverrides.SupplementaryGroups = [
"docker"
];
}
```
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->

View file

@ -25,7 +25,9 @@ In addition to numerous new and updated packages, this release has the following
- NixOS now defaults to using [nsncd](https://github.com/twosigma/nsncd), a non-caching reimplementation of nscd in Rust, as its NSS lookup dispatcher. This replaces the buggy and deprecated nscd implementation provided through glibc. When you find problems, you can switch back by disabling it:
```nix
services.nscd.enableNsncd = false;
{
services.nscd.enableNsncd = false;
}
```
- The internal option `boot.bootspec.enable` is now enabled by default because [RFC 0125](https://github.com/NixOS/rfcs/pull/125) was merged. This means you will have a bootspec document called `boot.json` generated for each system and specialisation in the top-level. This is useful to enable advanced boot use cases in NixOS, such as Secure Boot.
@ -190,11 +192,13 @@ In addition to numerous new and updated packages, this release has the following
- MAC-then-encrypt algorithms were removed from the default selection of `services.openssh.settings.Macs`. If you still require these [MACs](https://en.wikipedia.org/wiki/Message_authentication_code), for example when you are relying on libssh2 (e.g. VLC) or the SSH library shipped on the iPhone, you can re-add them like this:
```nix
services.openssh.settings.Macs = [
"hmac-sha2-512"
"hmac-sha2-256"
"umac-128@openssh.com"
];
{
services.openssh.settings.Macs = [
"hmac-sha2-512"
"hmac-sha2-256"
"umac-128@openssh.com"
];
}
```
- `podman` now uses the `netavark` network stack. Users will need to delete all of their local containers, images, volumes, etc, by running `podman system reset --force` once before upgrading their systems.
@ -227,21 +231,25 @@ In addition to numerous new and updated packages, this release has the following
- The attributes used by `services.snapper.configs.<name>` have changed. Migrate from this:
```nix
services.snapper.configs.example = {
subvolume = "/example";
extraConfig = ''
ALLOW_USERS="alice"
'';
};
{
services.snapper.configs.example = {
subvolume = "/example";
extraConfig = ''
ALLOW_USERS="alice"
'';
};
}
```
to this:
```nix
services.snapper.configs.example = {
SUBVOLUME = "/example";
ALLOW_USERS = [ "alice" ];
};
{
services.snapper.configs.example = {
SUBVOLUME = "/example";
ALLOW_USERS = [ "alice" ];
};
}
```
- The default module options for [services.snapserver.openFirewall](#opt-services.snapserver.openFirewall), [services.tmate-ssh-server.openFirewall](#opt-services.tmate-ssh-server.openFirewall) and [services.unifi-video.openFirewall](#opt-services.unifi-video.openFirewall) have been changed from `true` to `false`. You will need to explicitly set this option to `true`, or configure your firewall.
@ -446,15 +454,17 @@ In addition to numerous new and updated packages, this release has the following
- NixOS swap partitions with random encryption can now control the sector size, cipher, and key size used to set up the plain encryption device over the underlying block device rather than allowing them to be determined by `cryptsetup(8)`. One can use these features like so:
```nix
swapDevices = [ {
device = "/dev/disk/by-partlabel/swapspace";
randomEncryption = {
enable = true;
cipher = "aes-xts-plain64";
keySize = 512;
sectorSize = 4096;
};
} ];
{
swapDevices = [ {
device = "/dev/disk/by-partlabel/swapspace";
randomEncryption = {
enable = true;
cipher = "aes-xts-plain64";
keySize = 512;
sectorSize = 4096;
};
} ];
}
```
- New option `security.pam.zfs` to enable unlocking and mounting of encrypted ZFS home dataset at login.
@ -465,7 +475,9 @@ In addition to numerous new and updated packages, this release has the following
- PostgreSQL has added opt-in support for [JIT compilation](https://www.postgresql.org/docs/current/jit-reason.html). It can be enabled like this:
```nix
services.postgresql.enableJIT = true;
{
services.postgresql.enableJIT = true;
}
```
- `services.netdata` offers a [`services.netdata.deadlineBeforeStopSec`](#opt-services.netdata.deadlineBeforeStopSec) option which will control the deadline (in seconds) after which systemd will consider your netdata instance as dead if it didn't start in the elapsed time. It is helpful when your netdata instance takes longer to start because of a large amount of state or upgrades.

View file

@ -700,11 +700,13 @@ Make sure to also check the many updates in the [Nixpkgs library](#sec-release-2
will probably be removed eventually.
```nix
qt = {
enable = true;
platformTheme = "gnome";
style = "adwaita";
};
{
qt = {
enable = true;
platformTheme = "gnome";
style = "adwaita";
};
}
```
- DocBook option documentation is no longer supported, all module documentation
@ -885,11 +887,13 @@ Make sure to also check the many updates in the [Nixpkgs library](#sec-release-2
to a compatible major version, so they can move at their own pace.
```nix
python = python3.override {
packageOverrides = self: super: {
django = super.django_3;
{
python = python3.override {
packageOverrides = self: super: {
django = super.django_3;
};
};
};
}
```
- The `qemu-vm.nix` module by default now identifies block devices via
@ -1229,15 +1233,17 @@ Make sure to also check the many updates in the [Nixpkgs library](#sec-release-2
overriding `externalPlugins` and `vendorHash` arguments like this:
```nix
services.coredns = {
enable = true;
package = pkgs.coredns.override {
externalPlugins = [
{name = "fanout"; repo = "github.com/networkservicemesh/fanout"; version = "v1.9.1";}
];
vendorHash = "<SRI hash>";
{
services.coredns = {
enable = true;
package = pkgs.coredns.override {
externalPlugins = [
{name = "fanout"; repo = "github.com/networkservicemesh/fanout"; version = "v1.9.1";}
];
vendorHash = "<SRI hash>";
};
};
};
}
```
To get the necessary SRI hash, set `vendorHash = "";`. The build will fail

View file

@ -223,13 +223,14 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m
Example:
```nix
{
locations."/".extraConfig = ''
add_header Alt-Svc 'h3=":$server_port"; ma=86400';
'';
locations."^~ /assets/".extraConfig = ''
add_header Alt-Svc 'h3=":$server_port"; ma=86400';
'';
}
```
- The package `optparse-bash` is now dropped due to upstream inactivity. Alternatives available in Nixpkgs include [`argc`](https://github.com/sigoden/argc), [`argbash`](https://github.com/matejak/argbash), [`bashly`](https://github.com/DannyBen/bashly) and [`gum`](https://github.com/charmbracelet/gum), to name a few.

View file

@ -23,10 +23,12 @@ friendly input method user interface.
The following snippet can be used to configure IBus:
```nix
i18n.inputMethod = {
enabled = "ibus";
ibus.engines = with pkgs.ibus-engines; [ anthy hangul mozc ];
};
{
i18n.inputMethod = {
enabled = "ibus";
ibus.engines = with pkgs.ibus-engines; [ anthy hangul mozc ];
};
}
```
`i18n.inputMethod.ibus.engines` is optional and can be used
@ -49,7 +51,9 @@ Available extra IBus engines are:
`table`. For example:
```nix
ibus.engines = with pkgs.ibus-engines; [ table table-others ];
{
ibus.engines = with pkgs.ibus-engines; [ table table-others ];
}
```
To use any input method, the package must be added in the configuration, as
@ -75,10 +79,12 @@ built-in Input Method Engine, Pinyin, QuWei and Table-based input methods.
The following snippet can be used to configure Fcitx:
```nix
i18n.inputMethod = {
enabled = "fcitx5";
fcitx5.addons = with pkgs; [ fcitx5-mozc fcitx5-hangul fcitx5-m17n ];
};
{
i18n.inputMethod = {
enabled = "fcitx5";
fcitx5.addons = with pkgs; [ fcitx5-mozc fcitx5-hangul fcitx5-m17n ];
};
}
```
`i18n.inputMethod.fcitx5.addons` is optional and can be
@ -111,9 +117,11 @@ phonetic Korean characters (hangul) and pictographic Korean characters
The following snippet can be used to configure Nabi:
```nix
i18n.inputMethod = {
enabled = "nabi";
};
{
i18n.inputMethod = {
enabled = "nabi";
};
}
```
## Uim {#module-services-input-methods-uim}
@ -124,9 +132,11 @@ framework. Applications can use it through so-called bridges.
The following snippet can be used to configure uim:
```nix
i18n.inputMethod = {
enabled = "uim";
};
{
i18n.inputMethod = {
enabled = "uim";
};
}
```
Note: The [](#opt-i18n.inputMethod.uim.toolbar) option can be
@ -142,9 +152,11 @@ etc...
The following snippet can be used to configure Hime:
```nix
i18n.inputMethod = {
enabled = "hime";
};
{
i18n.inputMethod = {
enabled = "hime";
};
}
```
## Kime {#module-services-input-methods-kime}
@ -154,7 +166,9 @@ Kime is Korean IME. it's built with Rust language and let you get simple, safe,
The following snippet can be used to configure Kime:
```nix
i18n.inputMethod = {
enabled = "kime";
};
{
i18n.inputMethod = {
enabled = "kime";
};
}
```

View file

@ -5,7 +5,9 @@ Digital Bitbox is a hardware wallet and second-factor authenticator.
The `digitalbitbox` programs module may be installed by setting
`programs.digitalbitbox` to `true` in a manner similar to
```nix
programs.digitalbitbox.enable = true;
{
programs.digitalbitbox.enable = true;
}
```
and bundles the `digitalbitbox` package (see [](#sec-digitalbitbox-package)),
which contains the `dbb-app` and `dbb-cli` binaries, along with the hardware
@ -22,9 +24,11 @@ For more information, see <https://digitalbitbox.com/start_linux>.
The binaries, `dbb-app` (a GUI tool) and `dbb-cli` (a CLI tool), are available
through the `digitalbitbox` package which could be installed as follows:
```nix
environment.systemPackages = [
pkgs.digitalbitbox
];
{
environment.systemPackages = [
pkgs.digitalbitbox
];
}
```
## Hardware {#sec-digitalbitbox-hardware-module}
@ -32,16 +36,20 @@ environment.systemPackages = [
The digitalbitbox hardware package enables the udev rules for Digital Bitbox
devices and may be installed as follows:
```nix
hardware.digitalbitbox.enable = true;
{
hardware.digitalbitbox.enable = true;
}
```
In order to alter the udev rules, one may provide different values for the
`udevRule51` and `udevRule52` attributes by means of overriding as follows:
```nix
programs.digitalbitbox = {
enable = true;
package = pkgs.digitalbitbox.override {
udevRule51 = "something else";
{
programs.digitalbitbox = {
enable = true;
package = pkgs.digitalbitbox.override {
udevRule51 = "something else";
};
};
};
}
```

View file

@ -13,5 +13,7 @@ palette provides a searchable list of of all menu items in the application.
To enable Plotinus, add the following to your
{file}`configuration.nix`:
```nix
programs.plotinus.enable = true;
{
programs.plotinus.enable = true;
}
```

View file

@ -46,33 +46,35 @@ certs are overwritten when the ACME certs arrive. For
`foo.example.com` the config would look like this:
```nix
security.acme.acceptTerms = true;
security.acme.defaults.email = "admin+acme@example.com";
services.nginx = {
enable = true;
virtualHosts = {
"foo.example.com" = {
forceSSL = true;
enableACME = true;
# All serverAliases will be added as extra domain names on the certificate.
serverAliases = [ "bar.example.com" ];
locations."/" = {
root = "/var/www";
{
security.acme.acceptTerms = true;
security.acme.defaults.email = "admin+acme@example.com";
services.nginx = {
enable = true;
virtualHosts = {
"foo.example.com" = {
forceSSL = true;
enableACME = true;
# All serverAliases will be added as extra domain names on the certificate.
serverAliases = [ "bar.example.com" ];
locations."/" = {
root = "/var/www";
};
};
};
# We can also add a different vhost and reuse the same certificate
# but we have to append extraDomainNames manually beforehand:
# security.acme.certs."foo.example.com".extraDomainNames = [ "baz.example.com" ];
"baz.example.com" = {
forceSSL = true;
useACMEHost = "foo.example.com";
locations."/" = {
root = "/var/www";
# We can also add a different vhost and reuse the same certificate
# but we have to append extraDomainNames manually beforehand:
# security.acme.certs."foo.example.com".extraDomainNames = [ "baz.example.com" ];
"baz.example.com" = {
forceSSL = true;
useACMEHost = "foo.example.com";
locations."/" = {
root = "/var/www";
};
};
};
};
};
}
```
## Using ACME certificates in Apache/httpd {#module-security-acme-httpd}
@ -89,65 +91,69 @@ the intent that you will generate certs for all your vhosts and redirect
everyone to HTTPS.
```nix
security.acme.acceptTerms = true;
security.acme.defaults.email = "admin+acme@example.com";
{
security.acme.acceptTerms = true;
security.acme.defaults.email = "admin+acme@example.com";
# /var/lib/acme/.challenges must be writable by the ACME user
# and readable by the Nginx user. The easiest way to achieve
# this is to add the Nginx user to the ACME group.
users.users.nginx.extraGroups = [ "acme" ];
# /var/lib/acme/.challenges must be writable by the ACME user
# and readable by the Nginx user. The easiest way to achieve
# this is to add the Nginx user to the ACME group.
users.users.nginx.extraGroups = [ "acme" ];
services.nginx = {
enable = true;
virtualHosts = {
"acmechallenge.example.com" = {
# Catchall vhost, will redirect users to HTTPS for all vhosts
serverAliases = [ "*.example.com" ];
locations."/.well-known/acme-challenge" = {
root = "/var/lib/acme/.challenges";
};
locations."/" = {
return = "301 https://$host$request_uri";
services.nginx = {
enable = true;
virtualHosts = {
"acmechallenge.example.com" = {
# Catchall vhost, will redirect users to HTTPS for all vhosts
serverAliases = [ "*.example.com" ];
locations."/.well-known/acme-challenge" = {
root = "/var/lib/acme/.challenges";
};
locations."/" = {
return = "301 https://$host$request_uri";
};
};
};
};
};
# Alternative config for Apache
users.users.wwwrun.extraGroups = [ "acme" ];
services.httpd = {
enable = true;
virtualHosts = {
"acmechallenge.example.com" = {
# Catchall vhost, will redirect users to HTTPS for all vhosts
serverAliases = [ "*.example.com" ];
# /var/lib/acme/.challenges must be writable by the ACME user and readable by the Apache user.
# By default, this is the case.
documentRoot = "/var/lib/acme/.challenges";
extraConfig = ''
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge [NC]
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301]
'';
# Alternative config for Apache
users.users.wwwrun.extraGroups = [ "acme" ];
services.httpd = {
enable = true;
virtualHosts = {
"acmechallenge.example.com" = {
# Catchall vhost, will redirect users to HTTPS for all vhosts
serverAliases = [ "*.example.com" ];
# /var/lib/acme/.challenges must be writable by the ACME user and readable by the Apache user.
# By default, this is the case.
documentRoot = "/var/lib/acme/.challenges";
extraConfig = ''
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge [NC]
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301]
'';
};
};
};
};
}
```
Now you need to configure ACME to generate a certificate.
```nix
security.acme.certs."foo.example.com" = {
webroot = "/var/lib/acme/.challenges";
email = "foo@example.com";
# Ensure that the web server you use can read the generated certs
# Take a look at the group option for the web server you choose.
group = "nginx";
# Since we have a wildcard vhost to handle port 80,
# we can generate certs for anything!
# Just make sure your DNS resolves them.
extraDomainNames = [ "mail.example.com" ];
};
{
security.acme.certs."foo.example.com" = {
webroot = "/var/lib/acme/.challenges";
email = "foo@example.com";
# Ensure that the web server you use can read the generated certs
# Take a look at the group option for the web server you choose.
group = "nginx";
# Since we have a wildcard vhost to handle port 80,
# we can generate certs for anything!
# Just make sure your DNS resolves them.
extraDomainNames = [ "mail.example.com" ];
};
}
```
The private key {file}`key.pem` and certificate
@ -168,31 +174,33 @@ for provider/server specific configuration values. For the sake of these
docs, we will provide a fully self-hosted example using bind.
```nix
services.bind = {
enable = true;
extraConfig = ''
include "/var/lib/secrets/dnskeys.conf";
'';
zones = [
rec {
name = "example.com";
file = "/var/db/bind/${name}";
master = true;
extraConfig = "allow-update { key rfc2136key.example.com.; };";
}
];
};
{
services.bind = {
enable = true;
extraConfig = ''
include "/var/lib/secrets/dnskeys.conf";
'';
zones = [
rec {
name = "example.com";
file = "/var/db/bind/${name}";
master = true;
extraConfig = "allow-update { key rfc2136key.example.com.; };";
}
];
};
# Now we can configure ACME
security.acme.acceptTerms = true;
security.acme.defaults.email = "admin+acme@example.com";
security.acme.certs."example.com" = {
domain = "*.example.com";
dnsProvider = "rfc2136";
environmentFile = "/var/lib/secrets/certs.secret";
# We don't need to wait for propagation since this is a local DNS server
dnsPropagationCheck = false;
};
# Now we can configure ACME
security.acme.acceptTerms = true;
security.acme.defaults.email = "admin+acme@example.com";
security.acme.certs."example.com" = {
domain = "*.example.com";
dnsProvider = "rfc2136";
environmentFile = "/var/lib/secrets/certs.secret";
# We don't need to wait for propagation since this is a local DNS server
dnsPropagationCheck = false;
};
}
```
The {file}`dnskeys.conf` and {file}`certs.secret`
@ -200,36 +208,38 @@ must be kept secure and thus you should not keep their contents in your
Nix config. Instead, generate them one time with a systemd service:
```nix
systemd.services.dns-rfc2136-conf = {
requiredBy = ["acme-example.com.service" "bind.service"];
before = ["acme-example.com.service" "bind.service"];
unitConfig = {
ConditionPathExists = "!/var/lib/secrets/dnskeys.conf";
};
serviceConfig = {
Type = "oneshot";
UMask = 0077;
};
path = [ pkgs.bind ];
script = ''
mkdir -p /var/lib/secrets
chmod 755 /var/lib/secrets
tsig-keygen rfc2136key.example.com > /var/lib/secrets/dnskeys.conf
chown named:root /var/lib/secrets/dnskeys.conf
chmod 400 /var/lib/secrets/dnskeys.conf
{
systemd.services.dns-rfc2136-conf = {
requiredBy = ["acme-example.com.service" "bind.service"];
before = ["acme-example.com.service" "bind.service"];
unitConfig = {
ConditionPathExists = "!/var/lib/secrets/dnskeys.conf";
};
serviceConfig = {
Type = "oneshot";
UMask = 0077;
};
path = [ pkgs.bind ];
script = ''
mkdir -p /var/lib/secrets
chmod 755 /var/lib/secrets
tsig-keygen rfc2136key.example.com > /var/lib/secrets/dnskeys.conf
chown named:root /var/lib/secrets/dnskeys.conf
chmod 400 /var/lib/secrets/dnskeys.conf
# extract secret value from the dnskeys.conf
while read x y; do if [ "$x" = "secret" ]; then secret="''${y:1:''${#y}-3}"; fi; done < /var/lib/secrets/dnskeys.conf
# extract secret value from the dnskeys.conf
while read x y; do if [ "$x" = "secret" ]; then secret="''${y:1:''${#y}-3}"; fi; done < /var/lib/secrets/dnskeys.conf
cat > /var/lib/secrets/certs.secret << EOF
RFC2136_NAMESERVER='127.0.0.1:53'
RFC2136_TSIG_ALGORITHM='hmac-sha256.'
RFC2136_TSIG_KEY='rfc2136key.example.com'
RFC2136_TSIG_SECRET='$secret'
EOF
chmod 400 /var/lib/secrets/certs.secret
'';
};
cat > /var/lib/secrets/certs.secret << EOF
RFC2136_NAMESERVER='127.0.0.1:53'
RFC2136_TSIG_ALGORITHM='hmac-sha256.'
RFC2136_TSIG_KEY='rfc2136key.example.com'
RFC2136_TSIG_SECRET='$secret'
EOF
chmod 400 /var/lib/secrets/certs.secret
'';
};
}
```
Now you're all set to generate certs! You should monitor the first invocation
@ -251,27 +261,29 @@ you will set them as defaults
(e.g. [](#opt-security.acme.defaults.dnsProvider)).
```nix
# Configure ACME appropriately
security.acme.acceptTerms = true;
security.acme.defaults.email = "admin+acme@example.com";
security.acme.defaults = {
dnsProvider = "rfc2136";
environmentFile = "/var/lib/secrets/certs.secret";
# We don't need to wait for propagation since this is a local DNS server
dnsPropagationCheck = false;
};
{
# Configure ACME appropriately
security.acme.acceptTerms = true;
security.acme.defaults.email = "admin+acme@example.com";
security.acme.defaults = {
dnsProvider = "rfc2136";
environmentFile = "/var/lib/secrets/certs.secret";
# We don't need to wait for propagation since this is a local DNS server
dnsPropagationCheck = false;
};
# For each virtual host you would like to use DNS-01 validation with,
# set acmeRoot = null
services.nginx = {
enable = true;
virtualHosts = {
"foo.example.com" = {
enableACME = true;
acmeRoot = null;
# For each virtual host you would like to use DNS-01 validation with,
# set acmeRoot = null
services.nginx = {
enable = true;
virtualHosts = {
"foo.example.com" = {
enableACME = true;
acmeRoot = null;
};
};
};
};
}
```
And that's it! Next time your configuration is rebuilt, or when
@ -288,39 +300,41 @@ Below is an example configuration for OpenSMTPD, but this pattern
can be applied to any service.
```nix
# Configure ACME however you like (DNS or HTTP validation), adding
# the following configuration for the relevant certificate.
# Note: You cannot use `systemctl reload` here as that would mean
# the LoadCredential configuration below would be skipped and
# the service would continue to use old certificates.
security.acme.certs."mail.example.com".postRun = ''
systemctl restart opensmtpd
'';
# Now you must augment OpenSMTPD's systemd service to load
# the certificate files.
systemd.services.opensmtpd.requires = ["acme-finished-mail.example.com.target"];
systemd.services.opensmtpd.serviceConfig.LoadCredential = let
certDir = config.security.acme.certs."mail.example.com".directory;
in [
"cert.pem:${certDir}/cert.pem"
"key.pem:${certDir}/key.pem"
];
# Finally, configure OpenSMTPD to use these certs.
services.opensmtpd = let
credsDir = "/run/credentials/opensmtpd.service";
in {
enable = true;
setSendmail = false;
serverConfiguration = ''
pki mail.example.com cert "${credsDir}/cert.pem"
pki mail.example.com key "${credsDir}/key.pem"
listen on localhost tls pki mail.example.com
action act1 relay host smtp://127.0.0.1:10027
match for local action act1
{
# Configure ACME however you like (DNS or HTTP validation), adding
# the following configuration for the relevant certificate.
# Note: You cannot use `systemctl reload` here as that would mean
# the LoadCredential configuration below would be skipped and
# the service would continue to use old certificates.
security.acme.certs."mail.example.com".postRun = ''
systemctl restart opensmtpd
'';
};
# Now you must augment OpenSMTPD's systemd service to load
# the certificate files.
systemd.services.opensmtpd.requires = ["acme-finished-mail.example.com.target"];
systemd.services.opensmtpd.serviceConfig.LoadCredential = let
certDir = config.security.acme.certs."mail.example.com".directory;
in [
"cert.pem:${certDir}/cert.pem"
"key.pem:${certDir}/key.pem"
];
# Finally, configure OpenSMTPD to use these certs.
services.opensmtpd = let
credsDir = "/run/credentials/opensmtpd.service";
in {
enable = true;
setSendmail = false;
serverConfiguration = ''
pki mail.example.com cert "${credsDir}/cert.pem"
pki mail.example.com key "${credsDir}/key.pem"
listen on localhost tls pki mail.example.com
action act1 relay host smtp://127.0.0.1:10027
match for local action act1
'';
};
}
```
## Regenerating certificates {#module-security-acme-regenerate}

View file

@ -7,16 +7,18 @@ Castopod is an open-source hosting platform made for podcasters who want to enga
Use the following configuration to start a public instance of Castopod on `castopod.example.com` domain:
```nix
networking.firewall.allowedTCPPorts = [ 80 443 ];
services.castopod = {
enable = true;
database.createLocally = true;
nginx.virtualHost = {
serverName = "castopod.example.com";
enableACME = true;
forceSSL = true;
{
networking.firewall.allowedTCPPorts = [ 80 443 ];
services.castopod = {
enable = true;
database.createLocally = true;
nginx.virtualHost = {
serverName = "castopod.example.com";
enableACME = true;
forceSSL = true;
};
};
};
}
```
Go to `https://castopod.example.com/cp-install` to create superadmin account after applying the above configuration.

View file

@ -24,19 +24,18 @@ A very basic configuration for backing up to a locally accessible directory is:
```nix
{
opt.services.borgbackup.jobs = {
{ rootBackup = {
paths = "/";
exclude = [ "/nix" "/path/to/local/repo" ];
repo = "/path/to/local/repo";
doInit = true;
encryption = {
mode = "repokey";
passphrase = "secret";
};
compression = "auto,lzma";
startAt = "weekly";
rootBackup = {
paths = "/";
exclude = [ "/nix" "/path/to/local/repo" ];
repo = "/path/to/local/repo";
doInit = true;
encryption = {
mode = "repokey";
passphrase = "secret";
};
}
compression = "auto,lzma";
startAt = "weekly";
};
};
}
```
@ -96,7 +95,7 @@ accessible by root
startAt = "hourly";
};
};
};
}
```
The following few commands (run as root) let you test your backup.

View file

@ -16,8 +16,10 @@ key-value store.
To enable FoundationDB, add the following to your
{file}`configuration.nix`:
```nix
services.foundationdb.enable = true;
services.foundationdb.package = pkgs.foundationdb71; # FoundationDB 7.1.x
{
services.foundationdb.enable = true;
services.foundationdb.package = pkgs.foundationdb71; # FoundationDB 7.1.x
}
```
The {option}`services.foundationdb.package` option is required, and
@ -110,7 +112,9 @@ FoundationDB stores all data for all server processes under
{file}`/var/lib/foundationdb`. You can override this using
{option}`services.foundationdb.dataDir`, e.g.
```nix
services.foundationdb.dataDir = "/data/fdb";
{
services.foundationdb.dataDir = "/data/fdb";
}
```
Similarly, logs are stored under {file}`/var/log/foundationdb`
@ -266,7 +270,9 @@ For example, to create backups in {command}`/opt/fdb-backups`, first
set up the paths in the module options:
```nix
services.foundationdb.extraReadWritePaths = [ "/opt/fdb-backups" ];
{
services.foundationdb.extraReadWritePaths = [ "/opt/fdb-backups" ];
}
```
Restart the FoundationDB service, and it will now be able to write to this

View file

@ -16,8 +16,10 @@ PostgreSQL is an advanced, free relational database.
To enable PostgreSQL, add the following to your {file}`configuration.nix`:
```nix
services.postgresql.enable = true;
services.postgresql.package = pkgs.postgresql_15;
{
services.postgresql.enable = true;
services.postgresql.package = pkgs.postgresql_15;
}
```
Note that you are required to specify the desired version of PostgreSQL (e.g. `pkgs.postgresql_15`). Since upgrading your PostgreSQL version requires a database dump and reload (see below), NixOS cannot provide a default value for [](#opt-services.postgresql.package) such as the most recent release of PostgreSQL.
@ -36,7 +38,9 @@ alice=>
By default, PostgreSQL stores its databases in {file}`/var/lib/postgresql/$psqlSchema`. You can override this using [](#opt-services.postgresql.dataDir), e.g.
```nix
services.postgresql.dataDir = "/data/postgresql";
{
services.postgresql.dataDir = "/data/postgresql";
}
```
## Initializing {#module-services-postgres-initializing}
@ -95,16 +99,19 @@ databases from `ensureDatabases` and `extraUser1` from `ensureUsers`
are already created.
```nix
{
systemd.services.postgresql.postStart = lib.mkAfter ''
$PSQL service1 -c 'GRANT SELECT ON ALL TABLES IN SCHEMA public TO "extraUser1"'
$PSQL service1 -c 'GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO "extraUser1"'
# ....
'';
}
```
##### in intermediate oneshot service {#module-services-postgres-initializing-extra-permissions-superuser-oneshot}
```nix
{
systemd.services."migrate-service1-db1" = {
serviceConfig.Type = "oneshot";
requiredBy = "service1.service";
@ -119,6 +126,7 @@ are already created.
# ....
'';
};
}
```
#### as service user {#module-services-postgres-initializing-extra-permissions-service-user}
@ -130,6 +138,7 @@ are already created.
##### in service `preStart` {#module-services-postgres-initializing-extra-permissions-service-user-pre-start}
```nix
{
environment.PSQL = "psql --port=${toString services.postgresql.port}";
path = [ postgresql ];
systemd.services."service1".preStart = ''
@ -137,11 +146,13 @@ are already created.
$PSQL -c 'GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO "extraUser1"'
# ....
'';
}
```
##### in intermediate oneshot service {#module-services-postgres-initializing-extra-permissions-service-user-oneshot}
```nix
{
systemd.services."migrate-service1-db1" = {
serviceConfig.Type = "oneshot";
requiredBy = "service1.service";
@ -156,6 +167,7 @@ are already created.
# ....
'';
};
}
```
## Upgrading {#module-services-postgres-upgrading}
@ -257,11 +269,13 @@ postgresql_15.pkgs.pg_partman postgresql_15.pkgs.pgroonga
To add plugins via NixOS configuration, set `services.postgresql.extraPlugins`:
```nix
services.postgresql.package = pkgs.postgresql_12;
services.postgresql.extraPlugins = ps: with ps; [
pg_repack
postgis
];
{
services.postgresql.package = pkgs.postgresql_12;
services.postgresql.extraPlugins = ps: with ps; [
pg_repack
postgis
];
}
```
You can build custom PostgreSQL-with-plugins (to be used outside of NixOS) using function `.withPackages`. For example, creating a custom PostgreSQL package in an overlay can look like:

View file

@ -8,7 +8,9 @@ TigerBeetle is a distributed financial accounting database designed for mission
To enable TigerBeetle, add the following to your {file}`configuration.nix`:
```nix
{
services.tigerbeetle.enable = true;
}
```
When first started, the TigerBeetle service will create its data file at {file}`/var/lib/tigerbeetle` unless the file already exists, in which case it will just use the existing file.
@ -21,12 +23,14 @@ To configure it to listen on a different interface (and to configure it to conne
Note that the TigerBeetle module won't open any firewall ports automatically, so if you configure it to listen on an external interface, you'll need to ensure that connections can reach it:
```nix
{
services.tigerbeetle = {
enable = true;
addresses = [ "0.0.0.0:3001" ];
};
networking.firewall.allowedTCPPorts = [ 3001 ];
}
```
A complete list of options for TigerBeetle can be found [here](#opt-services.tigerbeetle.enable).

View file

@ -9,7 +9,9 @@ applications on Linux.
To enable Flatpak, add the following to your {file}`configuration.nix`:
```nix
{
services.flatpak.enable = true;
}
```
For the sandboxed apps to work correctly, desktop integration portals need to
@ -17,8 +19,10 @@ be installed. If you run GNOME, this will be handled automatically for you;
in other cases, you will need to add something like the following to your
{file}`configuration.nix`:
```nix
{
xdg.portal.extraPortals = [ pkgs.xdg-desktop-portal-gtk ];
xdg.portal.config.common.default = "gtk";
}
```
Then, you will need to add a repository, for example,

View file

@ -42,7 +42,7 @@ To use the local proxy in Go builds, you can set the proxy as environment variab
```nix
{
environment.variables = {
GOPROXY = "http://localhost:3000"
GOPROXY = "http://localhost:3000";
};
}
```

View file

@ -52,5 +52,7 @@ learning Kinos require `gcc` and `gnumake`. To add these, use
`extraPackages`:
```nix
services.livebook.extraPackages = with pkgs; [ gcc gnumake ];
{
services.livebook.extraPackages = with pkgs; [ gcc gnumake ];
}
```

View file

@ -242,7 +242,7 @@ let
rm $out/share/applications/emacs.desktop
'';
});
in [...]
in [ /* ... */ ]
```
:::
@ -263,7 +263,9 @@ with the user's login session.
To install and enable the {command}`systemd` user service for Emacs
daemon, add the following to your {file}`configuration.nix`:
```nix
services.emacs.enable = true;
{
services.emacs.enable = true;
}
```
The {var}`services.emacs.package` option allows a custom
@ -324,8 +326,10 @@ by symlinks in {file}`/etc/systemd/user`. In the case where
Emacs daemon is not wanted for all users, it is possible to install the
service but not globally enable it:
```nix
services.emacs.enable = false;
services.emacs.install = true;
{
services.emacs.enable = false;
services.emacs.install = true;
}
```
To enable the {command}`systemd` user service for just the

View file

@ -10,7 +10,9 @@ framework for Matrix.
2. If you want to use PostgreSQL instead of SQLite, do this:
```nix
services.maubot.settings.database = "postgresql://maubot@localhost/maubot";
{
services.maubot.settings.database = "postgresql://maubot@localhost/maubot";
}
```
If the PostgreSQL connection requires a password, you will have to
@ -18,54 +20,58 @@ framework for Matrix.
3. If you plan to expose your Maubot interface to the web, do something
like this:
```nix
services.nginx.virtualHosts."matrix.example.org".locations = {
"/_matrix/maubot/" = {
proxyPass = "http://127.0.0.1:${toString config.services.maubot.settings.server.port}";
proxyWebsockets = true;
{
services.nginx.virtualHosts."matrix.example.org".locations = {
"/_matrix/maubot/" = {
proxyPass = "http://127.0.0.1:${toString config.services.maubot.settings.server.port}";
proxyWebsockets = true;
};
};
};
services.maubot.settings.server.public_url = "matrix.example.org";
# do the following only if you want to use something other than /_matrix/maubot...
services.maubot.settings.server.ui_base_path = "/another/base/path";
services.maubot.settings.server.public_url = "matrix.example.org";
# do the following only if you want to use something other than /_matrix/maubot...
services.maubot.settings.server.ui_base_path = "/another/base/path";
}
```
4. Optionally, set `services.maubot.pythonPackages` to a list of python3
packages to make available for Maubot plugins.
5. Optionally, set `services.maubot.plugins` to a list of Maubot
plugins (full list available at https://plugins.maubot.xyz/):
```nix
services.maubot.plugins = with config.services.maubot.package.plugins; [
reactbot
# This will only change the default config! After you create a
# plugin instance, the default config will be copied into that
# instance's config in Maubot's database, and further base config
# changes won't affect the running plugin.
(rss.override {
base_config = {
update_interval = 60;
max_backoff = 7200;
spam_sleep = 2;
command_prefix = "rss";
admins = [ "@chayleaf:pavluk.org" ];
};
})
];
# ...or...
services.maubot.plugins = config.services.maubot.package.plugins.allOfficialPlugins;
# ...or...
services.maubot.plugins = config.services.maubot.package.plugins.allPlugins;
# ...or...
services.maubot.plugins = with config.services.maubot.package.plugins; [
(weather.override {
# you can pass base_config as a string
base_config = ''
default_location: New York
default_units: M
default_language:
show_link: true
show_image: false
'';
})
];
{
services.maubot.plugins = with config.services.maubot.package.plugins; [
reactbot
# This will only change the default config! After you create a
# plugin instance, the default config will be copied into that
# instance's config in Maubot's database, and further base config
# changes won't affect the running plugin.
(rss.override {
base_config = {
update_interval = 60;
max_backoff = 7200;
spam_sleep = 2;
command_prefix = "rss";
admins = [ "@chayleaf:pavluk.org" ];
};
})
];
# ...or...
services.maubot.plugins = config.services.maubot.package.plugins.allOfficialPlugins;
# ...or...
services.maubot.plugins = config.services.maubot.package.plugins.allPlugins;
# ...or...
services.maubot.plugins = with config.services.maubot.package.plugins; [
(weather.override {
# you can pass base_config as a string
base_config = ''
default_location: New York
default_units: M
default_language:
show_link: true
show_image: false
'';
})
];
}
```
6. Start Maubot at least once before doing the following steps (it's
necessary to generate the initial config).

View file

@ -57,23 +57,25 @@ locations and database, instead of having to copy or rename them.
Make sure to disable `services.gitea`, when doing this.
```nix
services.gitea.enable = false;
{
services.gitea.enable = false;
services.forgejo = {
enable = true;
user = "gitea";
group = "gitea";
stateDir = "/var/lib/gitea";
database.name = "gitea";
database.user = "gitea";
};
services.forgejo = {
enable = true;
user = "gitea";
group = "gitea";
stateDir = "/var/lib/gitea";
database.name = "gitea";
database.user = "gitea";
};
users.users.gitea = {
home = "/var/lib/gitea";
useDefaultShell = true;
group = "gitea";
isSystemUser = true;
};
users.users.gitea = {
home = "/var/lib/gitea";
useDefaultShell = true;
group = "gitea";
isSystemUser = true;
};
users.groups.gitea = {};
users.groups.gitea = {};
}
```

View file

@ -11,18 +11,20 @@ configure a webserver to proxy HTTP requests to the socket.
For instance, the following configuration could be used to use nginx as
frontend proxy:
```nix
services.nginx = {
enable = true;
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedProxySettings = true;
recommendedTlsSettings = true;
virtualHosts."git.example.com" = {
enableACME = true;
forceSSL = true;
locations."/".proxyPass = "http://unix:/run/gitlab/gitlab-workhorse.socket";
{
services.nginx = {
enable = true;
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedProxySettings = true;
recommendedTlsSettings = true;
virtualHosts."git.example.com" = {
enableACME = true;
forceSSL = true;
locations."/".proxyPass = "http://unix:/run/gitlab/gitlab-workhorse.socket";
};
};
};
}
```
## Configuring {#module-services-gitlab-configuring}
@ -36,35 +38,37 @@ all data like the repositories and uploads will be stored.
A basic configuration with some custom settings could look like this:
```nix
services.gitlab = {
enable = true;
databasePasswordFile = "/var/keys/gitlab/db_password";
initialRootPasswordFile = "/var/keys/gitlab/root_password";
https = true;
host = "git.example.com";
port = 443;
user = "git";
group = "git";
smtp = {
{
services.gitlab = {
enable = true;
address = "localhost";
port = 25;
};
secrets = {
dbFile = "/var/keys/gitlab/db";
secretFile = "/var/keys/gitlab/secret";
otpFile = "/var/keys/gitlab/otp";
jwsFile = "/var/keys/gitlab/jws";
};
extraConfig = {
gitlab = {
email_from = "gitlab-no-reply@example.com";
email_display_name = "Example GitLab";
email_reply_to = "gitlab-no-reply@example.com";
default_projects_features = { builds = false; };
databasePasswordFile = "/var/keys/gitlab/db_password";
initialRootPasswordFile = "/var/keys/gitlab/root_password";
https = true;
host = "git.example.com";
port = 443;
user = "git";
group = "git";
smtp = {
enable = true;
address = "localhost";
port = 25;
};
secrets = {
dbFile = "/var/keys/gitlab/db";
secretFile = "/var/keys/gitlab/secret";
otpFile = "/var/keys/gitlab/otp";
jwsFile = "/var/keys/gitlab/jws";
};
extraConfig = {
gitlab = {
email_from = "gitlab-no-reply@example.com";
email_display_name = "Example GitLab";
email_reply_to = "gitlab-no-reply@example.com";
default_projects_features = { builds = false; };
};
};
};
};
}
```
If you're setting up a new GitLab instance, generate new

View file

@ -66,9 +66,9 @@ in {
# Settings to setup what certificates are used for which endpoint.
virtualHosts = {
"${fqdn}".enableACME = true;
"meta.${fqdn}".useACMEHost = fqdn:
"man.${fqdn}".useACMEHost = fqdn:
"git.${fqdn}".useACMEHost = fqdn:
"meta.${fqdn}".useACMEHost = fqdn;
"man.${fqdn}".useACMEHost = fqdn;
"git.${fqdn}".useACMEHost = fqdn;
};
};
}

View file

@ -9,17 +9,19 @@ A basic config that notifies you of all certificate changes for your
domain would look as follows:
```nix
services.certspotter = {
enable = true;
# replace example.org with your domain name
watchlist = [ ".example.org" ];
emailRecipients = [ "webmaster@example.org" ];
};
{
services.certspotter = {
enable = true;
# replace example.org with your domain name
watchlist = [ ".example.org" ];
emailRecipients = [ "webmaster@example.org" ];
};
# Configure an SMTP client
programs.msmtp.enable = true;
# Or you can use any other module that provides sendmail, like
# services.nullmailer, services.opensmtpd, services.postfix
# Configure an SMTP client
programs.msmtp.enable = true;
# Or you can use any other module that provides sendmail, like
# services.nullmailer, services.opensmtpd, services.postfix
}
```
In this case, the leading dot in `".example.org"` means that Cert
@ -59,16 +61,18 @@ For example, you can remove `emailRecipients` and send email
notifications manually using the following hook:
```nix
services.certspotter.hooks = [
(pkgs.writeShellScript "certspotter-hook" ''
function print_email() {
echo "Subject: [certspotter] $SUMMARY"
echo "Mime-Version: 1.0"
echo "Content-Type: text/plain; charset=US-ASCII"
echo
cat "$TEXT_FILENAME"
}
print_email | ${config.services.certspotter.sendmailPath} -i webmaster@example.org
'')
];
{
services.certspotter.hooks = [
(pkgs.writeShellScript "certspotter-hook" ''
function print_email() {
echo "Subject: [certspotter] $SUMMARY"
echo "Mime-Version: 1.0"
echo "Content-Type: text/plain; charset=US-ASCII"
echo
cat "$TEXT_FILENAME"
}
print_email | ${config.services.certspotter.sendmailPath} -i webmaster@example.org
'')
];
}
```

View file

@ -11,15 +11,17 @@ email address and saves them to a local Elasticsearch instance looks
like this:
```nix
services.parsedmarc = {
enable = true;
settings.imap = {
host = "imap.example.com";
user = "alice@example.com";
password = "/path/to/imap_password_file";
{
services.parsedmarc = {
enable = true;
settings.imap = {
host = "imap.example.com";
user = "alice@example.com";
password = "/path/to/imap_password_file";
};
provision.geoIp = false; # Not recommended!
};
provision.geoIp = false; # Not recommended!
};
}
```
Note that GeoIP provisioning is disabled in the example for
@ -37,16 +39,18 @@ configured in the domain's dmarc policy is
`dmarc@monitoring.example.com`.
```nix
services.parsedmarc = {
enable = true;
provision = {
localMail = {
enable = true;
hostname = monitoring.example.com;
{
services.parsedmarc = {
enable = true;
provision = {
localMail = {
enable = true;
hostname = monitoring.example.com;
};
geoIp = false; # Not recommended!
};
geoIp = false; # Not recommended!
};
};
}
```
## Grafana and GeoIP {#module-services-parsedmarc-grafana-geoip}
@ -58,55 +62,57 @@ is automatically added as a Grafana datasource, and the dashboard is
added to Grafana as well.
```nix
services.parsedmarc = {
enable = true;
provision = {
localMail = {
enable = true;
hostname = url;
};
grafana = {
datasource = true;
dashboard = true;
{
services.parsedmarc = {
enable = true;
provision = {
localMail = {
enable = true;
hostname = url;
};
grafana = {
datasource = true;
dashboard = true;
};
};
};
};
# Not required, but recommended for full functionality
services.geoipupdate = {
settings = {
AccountID = 000000;
LicenseKey = "/path/to/license_key_file";
# Not required, but recommended for full functionality
services.geoipupdate = {
settings = {
AccountID = 000000;
LicenseKey = "/path/to/license_key_file";
};
};
};
services.grafana = {
enable = true;
addr = "0.0.0.0";
domain = url;
rootUrl = "https://" + url;
protocol = "socket";
security = {
adminUser = "admin";
adminPasswordFile = "/path/to/admin_password_file";
secretKeyFile = "/path/to/secret_key_file";
services.grafana = {
enable = true;
addr = "0.0.0.0";
domain = url;
rootUrl = "https://" + url;
protocol = "socket";
security = {
adminUser = "admin";
adminPasswordFile = "/path/to/admin_password_file";
secretKeyFile = "/path/to/secret_key_file";
};
};
};
services.nginx = {
enable = true;
recommendedTlsSettings = true;
recommendedOptimisation = true;
recommendedGzipSettings = true;
recommendedProxySettings = true;
upstreams.grafana.servers."unix:/${config.services.grafana.socket}" = {};
virtualHosts.${url} = {
root = config.services.grafana.staticRootPath;
enableACME = true;
forceSSL = true;
locations."/".tryFiles = "$uri @grafana";
locations."@grafana".proxyPass = "http://grafana";
services.nginx = {
enable = true;
recommendedTlsSettings = true;
recommendedOptimisation = true;
recommendedGzipSettings = true;
recommendedProxySettings = true;
upstreams.grafana.servers."unix:/${config.services.grafana.socket}" = {};
virtualHosts.${url} = {
root = config.services.grafana.staticRootPath;
enableACME = true;
forceSSL = true;
locations."/".tryFiles = "$uri @grafana";
locations."@grafana".proxyPass = "http://grafana";
};
};
};
users.users.nginx.extraGroups = [ "grafana" ];
users.users.nginx.extraGroups = [ "grafana" ];
}
```

View file

@ -10,6 +10,7 @@ One of the most common exporters is the
it provides hardware and OS metrics from the host it's
running on. The exporter could be configured as follows:
```nix
{
services.prometheus.exporters.node = {
enable = true;
port = 9100;
@ -23,6 +24,7 @@ running on. The exporter could be configured as follows:
openFirewall = true;
firewallFilter = "-i br0 -p tcp -m tcp --dport 9100";
};
}
```
It should now serve all metrics from the collectors that are explicitly
enabled and the ones that are
@ -36,6 +38,7 @@ the [available options](https://nixos.org/nixos/options.html#prometheus.exporter
Prometheus can now be configured to consume the metrics produced by the exporter:
```nix
{
services.prometheus = {
# ...
@ -49,7 +52,8 @@ Prometheus can now be configured to consume the metrics produced by the exporter
];
# ...
}
};
}
```
## Adding a new exporter {#module-services-prometheus-exporters-new-exporter}

View file

@ -7,19 +7,21 @@ A storage server for Firefox Sync that you can easily host yourself.
The absolute minimal configuration for the sync server looks like this:
```nix
services.mysql.package = pkgs.mariadb;
{
services.mysql.package = pkgs.mariadb;
services.firefox-syncserver = {
enable = true;
secrets = builtins.toFile "sync-secrets" ''
SYNC_MASTER_SECRET=this-secret-is-actually-leaked-to-/nix/store
'';
singleNode = {
services.firefox-syncserver = {
enable = true;
hostname = "localhost";
url = "http://localhost:5000";
secrets = builtins.toFile "sync-secrets" ''
SYNC_MASTER_SECRET=this-secret-is-actually-leaked-to-/nix/store
'';
singleNode = {
enable = true;
hostname = "localhost";
url = "http://localhost:5000";
};
};
};
}
```
This will start a sync server that is only accessible locally. Once the services is

View file

@ -7,14 +7,16 @@ Mosquitto is a MQTT broker often used for IoT or home automation data transport.
A minimal configuration for Mosquitto is
```nix
services.mosquitto = {
enable = true;
listeners = [ {
acl = [ "pattern readwrite #" ];
omitPasswordAuth = true;
settings.allow_anonymous = true;
} ];
};
{
services.mosquitto = {
enable = true;
listeners = [ {
acl = [ "pattern readwrite #" ];
omitPasswordAuth = true;
settings.allow_anonymous = true;
} ];
};
}
```
This will start a broker on port 1883, listening on all interfaces of the machine, allowing
@ -25,37 +27,42 @@ full read access to a user `monitor` and restricted write access to a user `serv
like
```nix
services.mosquitto = {
enable = true;
listeners = [ {
users = {
monitor = {
acl = [ "read #" ];
password = "monitor";
{
services.mosquitto = {
enable = true;
listeners = [ {
users = {
monitor = {
acl = [ "read #" ];
password = "monitor";
};
service = {
acl = [ "write service/#" ];
password = "service";
};
};
service = {
acl = [ "write service/#" ];
password = "service";
};
};
} ];
};
} ];
};
}
```
TLS authentication is configured by setting TLS-related options of the listener:
```nix
services.mosquitto = {
enable = true;
listeners = [ {
port = 8883; # port change is not required, but helpful to avoid mistakes
# ...
settings = {
cafile = "/path/to/mqtt.ca.pem";
certfile = "/path/to/mqtt.pem";
keyfile = "/path/to/mqtt.key";
};
} ];
{
services.mosquitto = {
enable = true;
listeners = [ {
port = 8883; # port change is not required, but helpful to avoid mistakes
# ...
settings = {
cafile = "/path/to/mqtt.ca.pem";
certfile = "/path/to/mqtt.pem";
keyfile = "/path/to/mqtt.key";
};
} ];
};
}
```
## Configuration {#module-services-mosquitto-config}

View file

@ -5,7 +5,9 @@
The absolute minimal configuration for the netbird daemon looks like this:
```nix
services.netbird.enable = true;
{
services.netbird.enable = true;
}
```
This will set up a netbird service listening on the port `51820` associated to the
@ -14,7 +16,9 @@ This will set up a netbird service listening on the port `51820` associated to t
It is strictly equivalent to setting:
```nix
services.netbird.tunnels.wt0.stateDir = "netbird";
{
services.netbird.tunnels.wt0.stateDir = "netbird";
}
```
The `enable` option is mainly kept for backward compatibility, as defining netbird
@ -29,11 +33,13 @@ The following configuration will start a netbird daemon using the interface `wt1
the port 51830. Its configuration file will then be located at `/var/lib/netbird-wt1/config.json`.
```nix
services.netbird.tunnels = {
wt1 = {
port = 51830;
{
services.netbird.tunnels = {
wt1 = {
port = 51830;
};
};
};
}
```
To interact with it, you will need to specify the correct daemon address:
@ -48,9 +54,11 @@ It is also possible to overwrite default options passed to the service, for
example:
```nix
services.netbird.tunnels.wt1.environment = {
NB_DAEMON_ADDR = "unix:///var/run/toto.sock"
};
{
services.netbird.tunnels.wt1.environment = {
NB_DAEMON_ADDR = "unix:///var/run/toto.sock";
};
}
```
This will set the socket to interact with the netbird service to `/var/run/toto.sock`.

View file

@ -18,10 +18,12 @@ The `config.exs` file can be further customized following the instructions on th
First, the Postgresql service must be enabled in the NixOS configuration
```nix
services.postgresql = {
enable = true;
package = pkgs.postgresql_13;
};
{
services.postgresql = {
enable = true;
package = pkgs.postgresql_13;
};
}
```
and activated with the usual
```ShellSession
@ -39,42 +41,44 @@ In this section we will enable the Pleroma service only locally, so its configur
This is an example of configuration, where [](#opt-services.pleroma.configs) option contains the content of the file `config.exs`, generated [in the first section](#module-services-pleroma-generate-config), but with the secrets (database password, endpoint secret key, salts, etc.) removed. Removing secrets is important, because otherwise they will be stored publicly in the Nix store.
```nix
services.pleroma = {
enable = true;
secretConfigFile = "/var/lib/pleroma/secrets.exs";
configs = [
''
import Config
{
services.pleroma = {
enable = true;
secretConfigFile = "/var/lib/pleroma/secrets.exs";
configs = [
''
import Config
config :pleroma, Pleroma.Web.Endpoint,
url: [host: "pleroma.example.net", scheme: "https", port: 443],
http: [ip: {127, 0, 0, 1}, port: 4000]
config :pleroma, Pleroma.Web.Endpoint,
url: [host: "pleroma.example.net", scheme: "https", port: 443],
http: [ip: {127, 0, 0, 1}, port: 4000]
config :pleroma, :instance,
name: "Test",
email: "admin@example.net",
notify_email: "admin@example.net",
limit: 5000,
registrations_open: true
config :pleroma, :instance,
name: "Test",
email: "admin@example.net",
notify_email: "admin@example.net",
limit: 5000,
registrations_open: true
config :pleroma, :media_proxy,
enabled: false,
redirect_on_failure: true
config :pleroma, :media_proxy,
enabled: false,
redirect_on_failure: true
config :pleroma, Pleroma.Repo,
adapter: Ecto.Adapters.Postgres,
username: "pleroma",
database: "pleroma",
hostname: "localhost"
config :pleroma, Pleroma.Repo,
adapter: Ecto.Adapters.Postgres,
username: "pleroma",
database: "pleroma",
hostname: "localhost"
# Configure web push notifications
config :web_push_encryption, :vapid_details,
subject: "mailto:admin@example.net"
# Configure web push notifications
config :web_push_encryption, :vapid_details,
subject: "mailto:admin@example.net"
# ... TO CONTINUE ...
''
];
};
# ... TO CONTINUE ...
''
];
};
}
```
Secrets must be moved into a file pointed by [](#opt-services.pleroma.secretConfigFile), in our case `/var/lib/pleroma/secrets.exs`. This file can be created copying the previously generated `config.exs` file and then removing all the settings, except the secrets. This is an example
@ -122,59 +126,61 @@ $ pleroma_ctl user new <nickname> <email> --admin --moderator --password <passw
In this configuration, Pleroma is listening only on the local port 4000. Nginx can be configured as a Reverse Proxy, for forwarding requests from public ports to the Pleroma service. This is an example of configuration, using
[Let's Encrypt](https://letsencrypt.org/) for the TLS certificates
```nix
security.acme = {
email = "root@example.net";
acceptTerms = true;
};
{
security.acme = {
email = "root@example.net";
acceptTerms = true;
};
services.nginx = {
enable = true;
addSSL = true;
services.nginx = {
enable = true;
addSSL = true;
recommendedTlsSettings = true;
recommendedOptimisation = true;
recommendedGzipSettings = true;
recommendedTlsSettings = true;
recommendedOptimisation = true;
recommendedGzipSettings = true;
recommendedProxySettings = false;
# NOTE: if enabled, the NixOS proxy optimizations will override the Pleroma
# specific settings, and they will enter in conflict.
recommendedProxySettings = false;
# NOTE: if enabled, the NixOS proxy optimizations will override the Pleroma
# specific settings, and they will enter in conflict.
virtualHosts = {
"pleroma.example.net" = {
http2 = true;
enableACME = true;
forceSSL = true;
virtualHosts = {
"pleroma.example.net" = {
http2 = true;
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://127.0.0.1:4000";
locations."/" = {
proxyPass = "http://127.0.0.1:4000";
extraConfig = ''
etag on;
gzip on;
extraConfig = ''
etag on;
gzip on;
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'POST, PUT, DELETE, GET, PATCH, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, Idempotency-Key' always;
add_header 'Access-Control-Expose-Headers' 'Link, X-RateLimit-Reset, X-RateLimit-Limit, X-RateLimit-Remaining, X-Request-Id' always;
if ($request_method = OPTIONS) {
return 204;
}
add_header X-XSS-Protection "1; mode=block";
add_header X-Permitted-Cross-Domain-Policies none;
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header Referrer-Policy same-origin;
add_header X-Download-Options noopen;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'POST, PUT, DELETE, GET, PATCH, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, Idempotency-Key' always;
add_header 'Access-Control-Expose-Headers' 'Link, X-RateLimit-Reset, X-RateLimit-Limit, X-RateLimit-Remaining, X-Request-Id' always;
if ($request_method = OPTIONS) {
return 204;
}
add_header X-XSS-Protection "1; mode=block";
add_header X-Permitted-Cross-Domain-Policies none;
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header Referrer-Policy same-origin;
add_header X-Download-Options noopen;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
client_max_body_size 16m;
# NOTE: increase if users need to upload very big files
'';
client_max_body_size 16m;
# NOTE: increase if users need to upload very big files
'';
};
};
};
};
};
}
```

View file

@ -26,24 +26,26 @@ A good configuration to start with, including a
endpoint as well as a [HTTP File Upload](https://xmpp.org/extensions/xep-0363.html)
endpoint will look like this:
```nix
services.prosody = {
enable = true;
admins = [ "root@example.org" ];
ssl.cert = "/var/lib/acme/example.org/fullchain.pem";
ssl.key = "/var/lib/acme/example.org/key.pem";
virtualHosts."example.org" = {
enabled = true;
domain = "example.org";
ssl.cert = "/var/lib/acme/example.org/fullchain.pem";
ssl.key = "/var/lib/acme/example.org/key.pem";
{
services.prosody = {
enable = true;
admins = [ "root@example.org" ];
ssl.cert = "/var/lib/acme/example.org/fullchain.pem";
ssl.key = "/var/lib/acme/example.org/key.pem";
virtualHosts."example.org" = {
enabled = true;
domain = "example.org";
ssl.cert = "/var/lib/acme/example.org/fullchain.pem";
ssl.key = "/var/lib/acme/example.org/key.pem";
};
muc = [ {
domain = "conference.example.org";
} ];
uploadHttp = {
domain = "upload.example.org";
};
};
muc = [ {
domain = "conference.example.org";
} ];
uploadHttp = {
domain = "upload.example.org";
};
};
}
```
## Let's Encrypt Configuration {#module-services-prosody-letsencrypt}
@ -58,15 +60,17 @@ certificate by leveraging the ACME
Provided the setup detailed in the previous section, you'll need the following acme configuration to generate
a TLS certificate for the three endponits:
```nix
security.acme = {
email = "root@example.org";
acceptTerms = true;
certs = {
"example.org" = {
webroot = "/var/www/example.org";
email = "root@example.org";
extraDomainNames = [ "conference.example.org" "upload.example.org" ];
{
security.acme = {
email = "root@example.org";
acceptTerms = true;
certs = {
"example.org" = {
webroot = "/var/www/example.org";
email = "root@example.org";
extraDomainNames = [ "conference.example.org" "upload.example.org" ];
};
};
};
};
}
```

View file

@ -7,7 +7,9 @@ Meilisearch is a lightweight, fast and powerful search engine. Think elastic sea
the minimum to start meilisearch is
```nix
services.meilisearch.enable = true;
{
services.meilisearch.enable = true;
}
```
this will start the http server included with meilisearch on port 7700.

View file

@ -19,21 +19,23 @@ be run behind a HTTP proxy on `fediverse.example.com`.
```nix
services.akkoma.enable = true;
services.akkoma.config = {
":pleroma" = {
":instance" = {
name = "My Akkoma instance";
description = "More detailed description";
email = "admin@example.com";
registration_open = false;
};
{
services.akkoma.enable = true;
services.akkoma.config = {
":pleroma" = {
":instance" = {
name = "My Akkoma instance";
description = "More detailed description";
email = "admin@example.com";
registration_open = false;
};
"Pleroma.Web.Endpoint" = {
url.host = "fediverse.example.com";
"Pleroma.Web.Endpoint" = {
url.host = "fediverse.example.com";
};
};
};
};
}
```
Please refer to the [configuration cheat sheet](https://docs.akkoma.dev/stable/configuration/cheatsheet/)
@ -55,19 +57,21 @@ Although it is possible to expose Akkoma directly, it is common practice to oper
HTTP reverse proxy such as nginx.
```nix
services.akkoma.nginx = {
enableACME = true;
forceSSL = true;
};
{
services.akkoma.nginx = {
enableACME = true;
forceSSL = true;
};
services.nginx = {
enable = true;
services.nginx = {
enable = true;
clientMaxBodySize = "16m";
recommendedTlsSettings = true;
recommendedOptimisation = true;
recommendedGzipSettings = true;
};
clientMaxBodySize = "16m";
recommendedTlsSettings = true;
recommendedOptimisation = true;
recommendedGzipSettings = true;
};
}
```
Please refer to [](#module-security-acme) for details on how to provision an SSL/TLS certificate.
@ -78,51 +82,53 @@ Without the media proxy function, Akkoma does not store any remote media like pi
locally, and clients have to fetch them directly from the source server.
```nix
# Enable nginx slice module distributed with Tengine
services.nginx.package = pkgs.tengine;
{
# Enable nginx slice module distributed with Tengine
services.nginx.package = pkgs.tengine;
# Enable media proxy
services.akkoma.config.":pleroma".":media_proxy" = {
enabled = true;
proxy_opts.redirect_on_failure = true;
};
# Adjust the persistent cache size as needed:
# Assuming an average object size of 128 KiB, around 1 MiB
# of memory is required for the key zone per GiB of cache.
# Ensure that the cache directory exists and is writable by nginx.
services.nginx.commonHttpConfig = ''
proxy_cache_path /var/cache/nginx/cache/akkoma-media-cache
levels= keys_zone=akkoma_media_cache:16m max_size=16g
inactive=1y use_temp_path=off;
'';
services.akkoma.nginx = {
locations."/proxy" = {
proxyPass = "http://unix:/run/akkoma/socket";
extraConfig = ''
proxy_cache akkoma_media_cache;
# Cache objects in slices of 1 MiB
slice 1m;
proxy_cache_key $host$uri$is_args$args$slice_range;
proxy_set_header Range $slice_range;
# Decouple proxy and upstream responses
proxy_buffering on;
proxy_cache_lock on;
proxy_ignore_client_abort on;
# Default cache times for various responses
proxy_cache_valid 200 1y;
proxy_cache_valid 206 301 304 1h;
# Allow serving of stale items
proxy_cache_use_stale error timeout invalid_header updating;
'';
# Enable media proxy
services.akkoma.config.":pleroma".":media_proxy" = {
enabled = true;
proxy_opts.redirect_on_failure = true;
};
};
# Adjust the persistent cache size as needed:
# Assuming an average object size of 128 KiB, around 1 MiB
# of memory is required for the key zone per GiB of cache.
# Ensure that the cache directory exists and is writable by nginx.
services.nginx.commonHttpConfig = ''
proxy_cache_path /var/cache/nginx/cache/akkoma-media-cache
levels= keys_zone=akkoma_media_cache:16m max_size=16g
inactive=1y use_temp_path=off;
'';
services.akkoma.nginx = {
locations."/proxy" = {
proxyPass = "http://unix:/run/akkoma/socket";
extraConfig = ''
proxy_cache akkoma_media_cache;
# Cache objects in slices of 1 MiB
slice 1m;
proxy_cache_key $host$uri$is_args$args$slice_range;
proxy_set_header Range $slice_range;
# Decouple proxy and upstream responses
proxy_buffering on;
proxy_cache_lock on;
proxy_ignore_client_abort on;
# Default cache times for various responses
proxy_cache_valid 200 1y;
proxy_cache_valid 206 301 304 1h;
# Allow serving of stale items
proxy_cache_use_stale error timeout invalid_header updating;
'';
};
};
}
```
#### Prefetch remote media {#modules-services-akkoma-prefetch-remote-media}
@ -132,10 +138,12 @@ fetches all media associated with a post through the media proxy, as soon as the
received by the instance.
```nix
services.akkoma.config.":pleroma".":mrf".policies =
map (pkgs.formats.elixirConf { }).lib.mkRaw [
"Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy"
];
{
services.akkoma.config.":pleroma".":mrf".policies =
map (pkgs.formats.elixirConf { }).lib.mkRaw [
"Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy"
];
}
```
#### Media previews {#modules-services-akkoma-media-previews}
@ -143,11 +151,13 @@ services.akkoma.config.":pleroma".":mrf".policies =
Akkoma can generate previews for media.
```nix
services.akkoma.config.":pleroma".":media_preview_proxy" = {
enabled = true;
thumbnail_max_width = 1920;
thumbnail_max_height = 1080;
};
{
services.akkoma.config.":pleroma".":media_preview_proxy" = {
enabled = true;
thumbnail_max_width = 1920;
thumbnail_max_height = 1080;
};
}
```
## Frontend management {#modules-services-akkoma-frontend-management}
@ -160,29 +170,31 @@ The following example overrides the primary frontends default configuration u
derivation.
```nix
services.akkoma.frontends.primary.package = pkgs.runCommand "akkoma-fe" {
config = builtins.toJSON {
expertLevel = 1;
collapseMessageWithSubject = false;
stopGifs = false;
replyVisibility = "following";
webPushHideIfCW = true;
hideScopeNotice = true;
renderMisskeyMarkdown = false;
hideSiteFavicon = true;
postContentType = "text/markdown";
showNavShortcuts = false;
};
nativeBuildInputs = with pkgs; [ jq xorg.lndir ];
passAsFile = [ "config" ];
} ''
mkdir $out
lndir ${pkgs.akkoma-frontends.akkoma-fe} $out
{
services.akkoma.frontends.primary.package = pkgs.runCommand "akkoma-fe" {
config = builtins.toJSON {
expertLevel = 1;
collapseMessageWithSubject = false;
stopGifs = false;
replyVisibility = "following";
webPushHideIfCW = true;
hideScopeNotice = true;
renderMisskeyMarkdown = false;
hideSiteFavicon = true;
postContentType = "text/markdown";
showNavShortcuts = false;
};
nativeBuildInputs = with pkgs; [ jq xorg.lndir ];
passAsFile = [ "config" ];
} ''
mkdir $out
lndir ${pkgs.akkoma-frontends.akkoma-fe} $out
rm $out/static/config.json
jq -s add ${pkgs.akkoma-frontends.akkoma-fe}/static/config.json ${config} \
>$out/static/config.json
'';
rm $out/static/config.json
jq -s add ${pkgs.akkoma-frontends.akkoma-fe}/static/config.json ${config} \
>$out/static/config.json
'';
}
```
## Federation policies {#modules-services-akkoma-federation-policies}
@ -198,28 +210,30 @@ of the fediverse and providing a pleasant experience to the users of an instance
```nix
services.akkoma.config.":pleroma" = with (pkgs.formats.elixirConf { }).lib; {
":mrf".policies = map mkRaw [
"Pleroma.Web.ActivityPub.MRF.SimplePolicy"
];
{
services.akkoma.config.":pleroma" = with (pkgs.formats.elixirConf { }).lib; {
":mrf".policies = map mkRaw [
"Pleroma.Web.ActivityPub.MRF.SimplePolicy"
];
":mrf_simple" = {
# Tag all media as sensitive
media_nsfw = mkMap {
"nsfw.weird.kinky" = "Untagged NSFW content";
};
":mrf_simple" = {
# Tag all media as sensitive
media_nsfw = mkMap {
"nsfw.weird.kinky" = "Untagged NSFW content";
};
# Reject all activities except deletes
reject = mkMap {
"kiwifarms.cc" = "Persistent harassment of users, no moderation";
};
# Reject all activities except deletes
reject = mkMap {
"kiwifarms.cc" = "Persistent harassment of users, no moderation";
};
# Force posts to be visible by followers only
followers_only = mkMap {
"beta.birdsite.live" = "Avoid polluting timelines with Twitter posts";
# Force posts to be visible by followers only
followers_only = mkMap {
"beta.birdsite.live" = "Avoid polluting timelines with Twitter posts";
};
};
};
};
}
```
## Upload filters {#modules-services-akkoma-upload-filters}
@ -228,12 +242,14 @@ This example strips GPS and location metadata from uploads, deduplicates them an
the file name.
```nix
services.akkoma.config.":pleroma"."Pleroma.Upload".filters =
map (pkgs.formats.elixirConf { }).lib.mkRaw [
"Pleroma.Upload.Filter.Exiftool"
"Pleroma.Upload.Filter.Dedupe"
"Pleroma.Upload.Filter.AnonymizeFilename"
];
{
services.akkoma.config.":pleroma"."Pleroma.Upload".filters =
map (pkgs.formats.elixirConf { }).lib.mkRaw [
"Pleroma.Upload.Filter.Exiftool"
"Pleroma.Upload.Filter.Dedupe"
"Pleroma.Upload.Filter.AnonymizeFilename"
];
}
```
## Migration from Pleroma {#modules-services-akkoma-migration-pleroma}
@ -286,9 +302,11 @@ To reuse the Pleroma data in place, disable Pleroma and enable Akkoma, pointi
Pleroma database and upload directory.
```nix
# Adjust these settings according to the database name and upload directory path used by Pleroma
services.akkoma.config.":pleroma"."Pleroma.Repo".database = "pleroma";
services.akkoma.config.":pleroma".":instance".upload_dir = "/var/lib/pleroma/uploads";
{
# Adjust these settings according to the database name and upload directory path used by Pleroma
services.akkoma.config.":pleroma"."Pleroma.Repo".database = "pleroma";
services.akkoma.config.":pleroma".":instance".upload_dir = "/var/lib/pleroma/uploads";
}
```
Please keep in mind that after the Akkoma service has been started, any migrations applied by
@ -304,7 +322,9 @@ details.
The Akkoma systemd service may be confined to a chroot with
```nix
services.systemd.akkoma.confinement.enable = true;
{
services.systemd.akkoma.confinement.enable = true;
}
```
Confinement of services is not generally supported in NixOS and therefore disabled by default.

View file

@ -7,19 +7,21 @@ modern and open source discussion platform.
A minimal configuration using Let's Encrypt for TLS certificates looks like this:
```nix
services.discourse = {
enable = true;
hostname = "discourse.example.com";
admin = {
email = "admin@example.com";
username = "admin";
fullName = "Administrator";
passwordFile = "/path/to/password_file";
{
services.discourse = {
enable = true;
hostname = "discourse.example.com";
admin = {
email = "admin@example.com";
username = "admin";
fullName = "Administrator";
passwordFile = "/path/to/password_file";
};
secretKeyBaseFile = "/path/to/secret_key_base_file";
};
secretKeyBaseFile = "/path/to/secret_key_base_file";
};
security.acme.email = "me@example.com";
security.acme.acceptTerms = true;
security.acme.email = "me@example.com";
security.acme.acceptTerms = true;
}
```
Provided a proper DNS setup, you'll be able to connect to the
@ -35,19 +37,21 @@ and [](#opt-services.discourse.sslCertificateKey)
options:
```nix
services.discourse = {
enable = true;
hostname = "discourse.example.com";
sslCertificate = "/path/to/ssl_certificate";
sslCertificateKey = "/path/to/ssl_certificate_key";
admin = {
email = "admin@example.com";
username = "admin";
fullName = "Administrator";
passwordFile = "/path/to/password_file";
{
services.discourse = {
enable = true;
hostname = "discourse.example.com";
sslCertificate = "/path/to/ssl_certificate";
sslCertificateKey = "/path/to/ssl_certificate_key";
admin = {
email = "admin@example.com";
username = "admin";
fullName = "Administrator";
passwordFile = "/path/to/password_file";
};
secretKeyBaseFile = "/path/to/secret_key_base_file";
};
secretKeyBaseFile = "/path/to/secret_key_base_file";
};
}
```
## Database access {#module-services-discourse-database}
@ -81,26 +85,28 @@ A basic setup which assumes you want to use your configured
email domain can be done like this:
```nix
services.discourse = {
enable = true;
hostname = "discourse.example.com";
sslCertificate = "/path/to/ssl_certificate";
sslCertificateKey = "/path/to/ssl_certificate_key";
admin = {
email = "admin@example.com";
username = "admin";
fullName = "Administrator";
passwordFile = "/path/to/password_file";
{
services.discourse = {
enable = true;
hostname = "discourse.example.com";
sslCertificate = "/path/to/ssl_certificate";
sslCertificateKey = "/path/to/ssl_certificate_key";
admin = {
email = "admin@example.com";
username = "admin";
fullName = "Administrator";
passwordFile = "/path/to/password_file";
};
mail.outgoing = {
serverAddress = "smtp.emailprovider.com";
port = 587;
username = "user@emailprovider.com";
passwordFile = "/path/to/smtp_password_file";
};
mail.incoming.enable = true;
secretKeyBaseFile = "/path/to/secret_key_base_file";
};
mail.outgoing = {
serverAddress = "smtp.emailprovider.com";
port = 587;
username = "user@emailprovider.com";
passwordFile = "/path/to/smtp_password_file";
};
mail.incoming.enable = true;
secretKeyBaseFile = "/path/to/secret_key_base_file";
};
}
```
This assumes you have set up an MX record for the address you've
@ -163,43 +169,45 @@ Discourse instance and enables
GitHub login in the site settings,
and changes a few request limits in the backend settings:
```nix
services.discourse = {
enable = true;
hostname = "discourse.example.com";
sslCertificate = "/path/to/ssl_certificate";
sslCertificateKey = "/path/to/ssl_certificate_key";
admin = {
email = "admin@example.com";
username = "admin";
fullName = "Administrator";
passwordFile = "/path/to/password_file";
};
mail.outgoing = {
serverAddress = "smtp.emailprovider.com";
port = 587;
username = "user@emailprovider.com";
passwordFile = "/path/to/smtp_password_file";
};
mail.incoming.enable = true;
siteSettings = {
required = {
title = "My Cats";
site_description = "Discuss My Cats (and be nice plz)";
{
services.discourse = {
enable = true;
hostname = "discourse.example.com";
sslCertificate = "/path/to/ssl_certificate";
sslCertificateKey = "/path/to/ssl_certificate_key";
admin = {
email = "admin@example.com";
username = "admin";
fullName = "Administrator";
passwordFile = "/path/to/password_file";
};
login = {
enable_github_logins = true;
github_client_id = "a2f6dfe838cb3206ce20";
github_client_secret._secret = /run/keys/discourse_github_client_secret;
mail.outgoing = {
serverAddress = "smtp.emailprovider.com";
port = 587;
username = "user@emailprovider.com";
passwordFile = "/path/to/smtp_password_file";
};
mail.incoming.enable = true;
siteSettings = {
required = {
title = "My Cats";
site_description = "Discuss My Cats (and be nice plz)";
};
login = {
enable_github_logins = true;
github_client_id = "a2f6dfe838cb3206ce20";
github_client_secret._secret = /run/keys/discourse_github_client_secret;
};
};
backendSettings = {
max_reqs_per_ip_per_minute = 300;
max_reqs_per_ip_per_10_seconds = 60;
max_asset_reqs_per_ip_per_10_seconds = 250;
max_reqs_per_ip_mode = "warn+block";
};
secretKeyBaseFile = "/path/to/secret_key_base_file";
};
backendSettings = {
max_reqs_per_ip_per_minute = 300;
max_reqs_per_ip_per_10_seconds = 60;
max_asset_reqs_per_ip_per_10_seconds = 250;
max_reqs_per_ip_mode = "warn+block";
};
secretKeyBaseFile = "/path/to/secret_key_base_file";
};
}
```
In the resulting site settings file, the
@ -254,33 +262,35 @@ plugins, and disable `discourse-spoiler-alert`
by default:
```nix
services.discourse = {
enable = true;
hostname = "discourse.example.com";
sslCertificate = "/path/to/ssl_certificate";
sslCertificateKey = "/path/to/ssl_certificate_key";
admin = {
email = "admin@example.com";
username = "admin";
fullName = "Administrator";
passwordFile = "/path/to/password_file";
};
mail.outgoing = {
serverAddress = "smtp.emailprovider.com";
port = 587;
username = "user@emailprovider.com";
passwordFile = "/path/to/smtp_password_file";
};
mail.incoming.enable = true;
plugins = with config.services.discourse.package.plugins; [
discourse-spoiler-alert
discourse-solved
];
siteSettings = {
plugins = {
spoiler_enabled = false;
{
services.discourse = {
enable = true;
hostname = "discourse.example.com";
sslCertificate = "/path/to/ssl_certificate";
sslCertificateKey = "/path/to/ssl_certificate_key";
admin = {
email = "admin@example.com";
username = "admin";
fullName = "Administrator";
passwordFile = "/path/to/password_file";
};
mail.outgoing = {
serverAddress = "smtp.emailprovider.com";
port = 587;
username = "user@emailprovider.com";
passwordFile = "/path/to/smtp_password_file";
};
mail.incoming.enable = true;
plugins = with config.services.discourse.package.plugins; [
discourse-spoiler-alert
discourse-solved
];
siteSettings = {
plugins = {
spoiler_enabled = false;
};
};
secretKeyBaseFile = "/path/to/secret_key_base_file";
};
secretKeyBaseFile = "/path/to/secret_key_base_file";
};
}
```

View file

@ -8,17 +8,19 @@ The following configuration sets up the PostgreSQL as database backend and binds
GoToSocial to `127.0.0.1:8080`, expecting to be run behind a HTTP proxy on `gotosocial.example.com`.
```nix
services.gotosocial = {
enable = true;
setupPostgresqlDB = true;
settings = {
application-name = "My GoToSocial";
host = "gotosocial.example.com";
protocol = "https";
bind-address = "127.0.0.1";
port = 8080;
{
services.gotosocial = {
enable = true;
setupPostgresqlDB = true;
settings = {
application-name = "My GoToSocial";
host = "gotosocial.example.com";
protocol = "https";
bind-address = "127.0.0.1";
port = 8080;
};
};
};
}
```
Please refer to the [GoToSocial Documentation](https://docs.gotosocial.org/en/latest/configuration/general/)
@ -30,24 +32,26 @@ Although it is possible to expose GoToSocial directly, it is common practice to
HTTP reverse proxy such as nginx.
```nix
networking.firewall.allowedTCPPorts = [ 80 443 ];
services.nginx = {
enable = true;
clientMaxBodySize = "40M";
virtualHosts = with config.services.gotosocial.settings; {
"${host}" = {
enableACME = true;
forceSSL = true;
locations = {
"/" = {
recommendedProxySettings = true;
proxyWebsockets = true;
proxyPass = "http://${bind-address}:${toString port}";
{
networking.firewall.allowedTCPPorts = [ 80 443 ];
services.nginx = {
enable = true;
clientMaxBodySize = "40M";
virtualHosts = with config.services.gotosocial.settings; {
"${host}" = {
enableACME = true;
forceSSL = true;
locations = {
"/" = {
recommendedProxySettings = true;
proxyWebsockets = true;
proxyPass = "http://${bind-address}:${toString port}";
};
};
};
};
};
};
}
```
Please refer to [](#module-security-acme) for details on how to provision an SSL/TLS certificate.

View file

@ -127,15 +127,17 @@ should be set to. See the description of
A basic configuration with some custom settings could look like this:
```nix
services.keycloak = {
enable = true;
settings = {
hostname = "keycloak.example.com";
hostname-strict-backchannel = true;
{
services.keycloak = {
enable = true;
settings = {
hostname = "keycloak.example.com";
hostname-strict-backchannel = true;
};
initialAdminPassword = "e6Wcm0RrtegMEHl"; # change on first login
sslCertificate = "/run/keys/ssl_cert";
sslCertificateKey = "/run/keys/ssl_key";
database.passwordFile = "/run/keys/db_password";
};
initialAdminPassword = "e6Wcm0RrtegMEHl"; # change on first login
sslCertificate = "/run/keys/ssl_cert";
sslCertificateKey = "/run/keys/ssl_key";
database.passwordFile = "/run/keys/db_password";
};
}
```

View file

@ -7,13 +7,15 @@ Lemmy is a federated alternative to reddit in rust.
the minimum to start lemmy is
```nix
services.lemmy = {
enable = true;
settings = {
hostname = "lemmy.union.rocks";
database.createLocally = true;
{
services.lemmy = {
enable = true;
settings = {
hostname = "lemmy.union.rocks";
database.createLocally = true;
};
caddy.enable = true;
};
caddy.enable = true;
}
```

View file

@ -7,7 +7,9 @@ pict-rs is a a simple image hosting service.
the minimum to start pict-rs is
```nix
services.pict-rs.enable = true;
{
services.pict-rs.enable = true;
}
```
this will start the http server on port 8080 by default.

View file

@ -100,7 +100,7 @@ Not all the configuration options are available directly in this module, but you
server = {
port = 4567;
autoDownloadNewChapters = false;
maxSourcesInParallel" = 6;
maxSourcesInParallel = 6;
extensionRepos = [
"https://raw.githubusercontent.com/MY_ACCOUNT/MY_REPO/repo/index.min.json"
];

View file

@ -9,8 +9,10 @@ All of the core apps, optional apps, games, and core developer tools from GNOME
To enable the GNOME desktop use:
```nix
services.xserver.desktopManager.gnome.enable = true;
services.xserver.displayManager.gdm.enable = true;
{
services.xserver.desktopManager.gnome.enable = true;
services.xserver.displayManager.gdm.enable = true;
}
```
::: {.note}
@ -24,7 +26,9 @@ The default applications used in NixOS are very minimal, inspired by the default
If youd like to only use the GNOME desktop and not the apps, you can disable them with:
```nix
services.gnome.core-utilities.enable = false;
{
services.gnome.core-utilities.enable = false;
}
```
and none of them will be installed.
@ -38,8 +42,10 @@ Note that this mechanism can only exclude core utilities, games and core develop
It is also possible to disable many of the [core services](https://github.com/NixOS/nixpkgs/blob/b8ec4fd2a4edc4e30d02ba7b1a2cc1358f3db1d5/nixos/modules/services/x11/desktop-managers/gnome.nix#L329-L348). For example, if you do not need indexing files, you can disable Tracker with:
```nix
services.gnome.tracker-miners.enable = false;
services.gnome.tracker.enable = false;
{
services.gnome.tracker-miners.enable = false;
services.gnome.tracker.enable = false;
}
```
Note, however, that doing so is not supported and might break some applications. Notably, GNOME Music cannot work without Tracker.
@ -49,7 +55,9 @@ Note, however, that doing so is not supported and might break some applications.
You can install all of the GNOME games with:
```nix
services.gnome.games.enable = true;
{
services.gnome.games.enable = true;
}
```
### GNOME core developer tools {#sec-gnome-core-developer-tools}
@ -57,7 +65,9 @@ services.gnome.games.enable = true;
You can install GNOME core developer tools with:
```nix
services.gnome.core-developer-tools.enable = true;
{
services.gnome.core-developer-tools.enable = true;
}
```
## Enabling GNOME Flashback {#sec-gnome-enable-flashback}
@ -65,7 +75,9 @@ services.gnome.core-developer-tools.enable = true;
GNOME Flashback provides a desktop environment based on the classic GNOME 2 architecture. You can enable the default GNOME Flashback session, which uses the Metacity window manager, with:
```nix
services.xserver.desktopManager.gnome.flashback.enableMetacity = true;
{
services.xserver.desktopManager.gnome.flashback.enableMetacity = true;
}
```
It is also possible to create custom sessions that replace Metacity with a different window manager using [](#opt-services.xserver.desktopManager.gnome.flashback.customSessions).
@ -73,14 +85,16 @@ It is also possible to create custom sessions that replace Metacity with a diffe
The following example uses `xmonad` window manager:
```nix
services.xserver.desktopManager.gnome.flashback.customSessions = [
{
wmName = "xmonad";
wmLabel = "XMonad";
wmCommand = "${pkgs.haskellPackages.xmonad}/bin/xmonad";
enableGnomePanel = false;
}
];
{
services.xserver.desktopManager.gnome.flashback.customSessions = [
{
wmName = "xmonad";
wmLabel = "XMonad";
wmCommand = "${pkgs.haskellPackages.xmonad}/bin/xmonad";
enableGnomePanel = false;
}
];
}
```
## Icons and GTK Themes {#sec-gnome-icons-and-gtk-themes}
@ -105,11 +119,13 @@ Some packages that include Shell extensions, like `gnome.gpaste`, dont have t
You can install them like any other package:
```nix
environment.systemPackages = [
gnomeExtensions.dash-to-dock
gnomeExtensions.gsconnect
gnomeExtensions.mpris-indicator-button
];
{
environment.systemPackages = [
gnomeExtensions.dash-to-dock
gnomeExtensions.gsconnect
gnomeExtensions.mpris-indicator-button
];
}
```
Unfortunately, we lack a way for these to be managed in a completely declarative way.
@ -137,22 +153,24 @@ You can use `dconf-editor` tool to explore which GSettings you can set.
### Example {#sec-gnome-gsettings-overrides-example}
```nix
services.xserver.desktopManager.gnome = {
extraGSettingsOverrides = ''
# Change default background
[org.gnome.desktop.background]
picture-uri='file://${pkgs.nixos-artwork.wallpapers.mosaic-blue.gnomeFilePath}'
{
services.xserver.desktopManager.gnome = {
extraGSettingsOverrides = ''
# Change default background
[org.gnome.desktop.background]
picture-uri='file://${pkgs.nixos-artwork.wallpapers.mosaic-blue.gnomeFilePath}'
# Favorite apps in gnome-shell
[org.gnome.shell]
favorite-apps=['org.gnome.Console.desktop', 'org.gnome.Nautilus.desktop']
'';
# Favorite apps in gnome-shell
[org.gnome.shell]
favorite-apps=['org.gnome.Console.desktop', 'org.gnome.Nautilus.desktop']
'';
extraGSettingsOverridePackages = [
pkgs.gsettings-desktop-schemas # for org.gnome.desktop
pkgs.gnome.gnome-shell # for org.gnome.shell
];
};
extraGSettingsOverridePackages = [
pkgs.gsettings-desktop-schemas # for org.gnome.desktop
pkgs.gnome.gnome-shell # for org.gnome.shell
];
};
}
```
## Frequently Asked Questions {#sec-gnome-faq}

View file

@ -6,16 +6,22 @@ Pantheon is the desktop environment created for the elementary OS distribution.
All of Pantheon is working in NixOS and the applications should be available, aside from a few [exceptions](https://github.com/NixOS/nixpkgs/issues/58161). To enable Pantheon, set
```nix
services.xserver.desktopManager.pantheon.enable = true;
{
services.xserver.desktopManager.pantheon.enable = true;
}
```
This automatically enables LightDM and Pantheon's LightDM greeter. If you'd like to disable this, set
```nix
services.xserver.displayManager.lightdm.greeters.pantheon.enable = false;
services.xserver.displayManager.lightdm.enable = false;
{
services.xserver.displayManager.lightdm.greeters.pantheon.enable = false;
services.xserver.displayManager.lightdm.enable = false;
}
```
but please be aware using Pantheon without LightDM as a display manager will break screenlocking from the UI. The NixOS module for Pantheon installs all of Pantheon's default applications. If you'd like to not install Pantheon's apps, set
```nix
services.pantheon.apps.enable = false;
{
services.pantheon.apps.enable = false;
}
```
You can also use [](#opt-environment.pantheon.excludePackages) to remove any other app (like `elementary-mail`).
@ -34,25 +40,28 @@ wingpanel-with-indicators.override {
indicators = [
pkgs.some-special-indicator
];
};
}
```
```nix
switchboard-with-plugs.override {
plugs = [
pkgs.some-special-plug
];
};
}
```
please note that, like how the NixOS options describe these as extra plugins, this would only add to the default plugins included with the programs. If for some reason you'd like to configure which plugins to use exactly, both packages have an argument for this:
```nix
wingpanel-with-indicators.override {
useDefaultIndicators = false;
indicators = specialListOfIndicators;
};
}
```
```nix
switchboard-with-plugs.override {
useDefaultPlugs = false;
plugs = specialListOfPlugs;
};
}
```
this could be most useful for testing a particular plug-in in isolation.

View file

@ -40,12 +40,16 @@ For more complete documentation on how to generate a secret with clevis, see the
In order to activate unattended decryption of a resource at boot, enable the `clevis` module:
```nix
boot.initrd.clevis.enable = true;
{
boot.initrd.clevis.enable = true;
}
```
Then, specify the device you want to decrypt using a given clevis secret. Clevis will automatically try to decrypt the device at boot and will fallback to interactive unlocking if the decryption policy is not fulfilled.
```nix
boot.initrd.clevis.devices."/dev/nvme0n1p1".secretFile = ./nvme0n1p1.jwe;
{
boot.initrd.clevis.devices."/dev/nvme0n1p1".secretFile = ./nvme0n1p1.jwe;
}
```
Only `bcachefs`, `zfs` and `luks` encrypted devices are supported at this time.