NixOS - My Configuration and Switch to Podman
For some time now I have been looking for an interesting lightweight linux distribution that could replace Ubuntu.
Now I’ve found NixOS and I have no idea why it hadn’t crossed my path sooner. So far I am very happy with it, it feels very clean. With NixOS you can configure everything in one place. Think for example of users and groups, a few nix packages such as wget, htop, curl, openssl etc. Or, for example, mounting cifs directories or adding docker/podman containers. What makes this very powerful is that you can easily switch to a new configuration and possibly perform a rollback again.
I also decided to switch from Docker to Podman. Why? Because Podman is open source and has a daemonless architecture, you can read more about it here. This means that I will adjust my notes on this digital garden accordingly.
Installation
Within Proxmox I added NixOS as a VM by downloading the Graphical ISO image (Plasma Desktop, 64-bit Intel/AMD).
First I uploaded the ISO to the Proxmox local storage and selected SHA-256 as the hash algorithm. The checksum can be found next to the download button on the NixOS download site.
I also thought it would be nice to place NixOS in the new server VLAN. For that I had to adjust the following setting within the node (pve
):
- Select the node
- Select
System
>Network
- Edit the Linux Bridge
- Turn ON
VLAN aware
and clickOK
You can then enter theVLAN Tag
at the network device of the NixOS VM (underHardware
).
Then I connected to the Plasma Desktop GUI via the console and went through the installation steps.
Configuration
Below is the configuration.nix
that you can find under /etc/nixos
. I have supplemented the default configuration with:
-
Fs.inotify settings
. For optimization for Syncthing, among others. -
DHCP
for the main networking interface. The MAC address comes from the VM and is given a reserved static IP address by the Unifi gateway. - Extra
user options
. This is self-evident. -
Allow unfree packages
. Could be useful (or not). -
Systempackages
, including:-
qemu_kvm.ga
: for Proxmox. Don’t forget to set theQEMU Guest Agent
toEnabled
in theOptions
of the NixOS VM. -
openssl
: useful for generating certificates. -
cifs-utils
: for the cifs mounts. The package may not even need to be added here, but it is then only useful to have for the man pages.
-
-
Nix daemon config
: automatic garbage collection and store optimization. Very handy. -
Openssh service
is enabled. -
Security.sudo.wheelNeedsPassword
: run sudo without a password. This may not always be recommended. -
Services.fstrim
: is enabled. I was told that this would be better for an SSD. -
Services.qemuGuest.enable
: see point 5.1. -
Cifs mount
: so that I can access files on my fileserver that runs as a container within Proxmox. ReplaceIP
and and enter your username and password in thesmb-secrets
file.
Podman specific
-
Systemd.tmpfiles.rules
: with this I will create folders which are needed for some Podman containers. -
Virtualisation
: Podman is set as backend. There are references to the containers I have set up in separate nix files (homer andcaddy
for example). I will talk more about this in other notes. -
Systemd.services.create-podman-network
: This ensures that the Podman macvlan network I use for all containers is always created if it doesn’t exist. This is very useful, for example when installing a new NixOS VM. Within the IP addresses I replacexx
with my VLAN Tag.
Switching between configurations
After modifying the configuration.nix
you just need to run: sudo nixos-rebuild switch
to switch between configurations.
If it doesn’t work the way you want, you can go back with sudo nixos-rebuild switch --rollback
.
Each time you switch, a generation is added that you can view with sudo nix-env -p /nix/var/nix/profiles/system --list-generations
.
# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running ‘nixos-help’).
{ config, pkgs, ... }:
{
imports =
[ # Include the results of the hardware scan.
./hardware-configuration.nix
];
# Bootloader.
boot.loader.grub.enable = true;
boot.loader.grub.device = "/dev/sda";
boot.loader.grub.useOSProber = true;
boot.kernel.sysctl = {
# Note that inotify watches consume 1kB on 64-bit machines.
"fs.inotify.max_user_watches" = 1048576; # default: 8192
"fs.inotify.max_user_instances" = 1024; # default: 128
"fs.inotify.max_queued_events" = 32768; # default: 16384
};
# Enable networking
networking.hostName = "nixos"; # Define your hostname.
networking.networkmanager.enable = true;
networking.interfaces.ens18.useDHCP = true;
# Set your time zone.
time.timeZone = "Europe/Amsterdam";
# Select internationalisation properties.
i18n.defaultLocale = "en_US.UTF-8";
i18n.extraLocaleSettings = {
LC_ADDRESS = "nl_NL.UTF-8";
LC_IDENTIFICATION = "nl_NL.UTF-8";
LC_MEASUREMENT = "nl_NL.UTF-8";
LC_MONETARY = "nl_NL.UTF-8";
LC_NAME = "nl_NL.UTF-8";
LC_NUMERIC = "nl_NL.UTF-8";
LC_PAPER = "nl_NL.UTF-8";
LC_TELEPHONE = "nl_NL.UTF-8";
LC_TIME = "nl_NL.UTF-8";
};
# Configure keymap in X11
services.xserver = {
layout = "gb";
xkbVariant = "";
};
# Configure console keymap
console.keyMap = "uk";
# Define a user account. Don't forget to set a password with ‘passwd’.
users.users.beheer = {
isNormalUser = true;
description = "Beheer";
extraGroups = [ "networkmanager" "wheel" "podman" ];
packages = with pkgs; [];
home = "/home/beheer";
createHome = true;
};
# Allow unfree packages
nixpkgs.config.allowUnfree = true;
# List packages installed in system profile. To search, run:
# $ nix search wget
environment.systemPackages = with pkgs; [
# vim # Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed by default.
wget
htop
curl
qemu_kvm.ga
openssl
cifs-utils
];
# Nix daemon config
nix = {
# Automate garbage collection
gc = {
automatic = true;
dates = "weekly";
options = "--delete-older-than 7d";
};
settings = {
# Automate `nix store --optimise`
auto-optimise-store = true;
};
};
# List services that you want to enable:
# Enable the OpenSSH daemon.
services.openssh.enable = true;
# Open ports in the firewall.
# networking.firewall.allowedTCPPorts = [ ... ];
# networking.firewall.allowedUDPPorts = [ ... ];
# Or disable the firewall altogether.
networking.firewall.enable = false;
# This value determines the NixOS release from which the default
# settings for stateful data, like file locations and database versions
# on your system were taken. It‘s perfectly fine and recommended to leave
# this value at the release version of the first install of this system.
# Before changing this value read the documentation for this option
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
system.stateVersion = "22.11"; # Did you read the comment?
security.sudo.wheelNeedsPassword = false;
# Good for SSD
services.fstrim = {
enable = true;
};
# Enable the guest agent for proxmox
services.qemuGuest.enable = true;
# Samba Client - cifs mount
fileSystems."/mnt/fileserver/backup" = {
device = "//IP/backup";
fsType = "cifs";
options = let
# this line prevents hanging on network split
automount_opts = "x-systemd.automount,noauto,x-systemd.idle-timeout=60,x-systemd.device-timeout=5s,x-systemd.mount-timeout=5s";
in ["${automount_opts},credentials=/etc/nixos/smb-secrets,file_mode=0777,dir_mode=0777,iocharset=utf8"];
};
# Create directories for the containers
systemd.tmpfiles.rules =
[
"d /home/beheer/caddy/site 755 beheer users"
"d /home/beheer/caddy/data 755 beheer users"
"d /home/beheer/caddy/config 755 beheer users"
] ;
virtualisation = {
podman = {
enable = true;
# Create a `docker` alias for podman, to use it as a drop-in replacement
dockerCompat = true;
# Required for containers under podman-compose to be able to talk to each other.
defaultNetwork.dnsname.enable = true;
};
oci-containers = {
backend = "podman";
containers = {
homer = import ./containers/homer.nix;
caddy = import ./containers/caddy.nix; # Add manually the Caddyfile before using this container
};
};
};
systemd.services.create-podman-network = with config.virtualisation.oci-containers; {
serviceConfig.Type = "oneshot";
wantedBy = [ "${backend}-homer.service" ];
script = ''
${pkgs.podman}/bin/podman network exists net_macvlan || \
${pkgs.podman}/bin/podman network create --driver=macvlan --gateway=192.168.xx.1 --subnet=192.168.xx.0/24 -o parent=ens18 net_macvlan
'';
};
}
Read other notes
Tags
Notes mentioning this note
- Homer Dashboard - NixOS Container Setup
I was looking for a simple dashboard that I could use as a home page on my clients. I found...
- Caddy - NixOS Container Setup
Caddy is a simple open-source web server.
- Caddy - Reverse Proxy with Pi-hole Local DNS Setup
Since I create Docker/Podman containers with a macvlan and a reserved IP address, I also wanted to use my local...
Comments
No comments found for this note.
Join the discussion for this note on this ticket. Comments appear on this page instantly.