Nix and NixOS
The purpose of this page is to document how to use NixOS to create an environment ready for iDempiere. The Nix, Nixpkgs, and NixOS manuals along with the wiki are excellent resources for explaining how Nix/NixOS works.
NixOS is a Linux distro built on top of NixPkgs. NixPkgs uses the Nix language to define how to build packages. Reference: john.codes
Videos to learn Nix:
- No Boilerplate - Everything Everywhere All At Once - why nix is important
- Why Does Nothing work - best and most practical guide for what I need
- Vimjoyer - ultimate guide to Nix - geeky introduction - mostly focused on flakes
- Iogamaster - another learning guide to NixOS
Important docs:
- https://nix.dev/tutorials/first-steps/
- https://nixos.org/guides/nix-pills - if you really want to understand how the nix ecosystem works. (ch5 - current)
- CLI Discussion (old vs new) - flakes vs niv
- Current assumption: will use configuration (not flakes) - Use flakes in configuration.nix
- Nix Awesome
- Keeping NixOS Updated/Current
Repositories:
Installing NixOS
I have not installed NixOS on bare metal yet. All NixOS experimentation has been with Incus and AWS.
- Incus (formerly LXD) container
- command:
- incus launch images:nixos/unstable nixos-01 -c security.nesting=true
- incus exec nixos-01 -- bash
- notes:
- nixos/23.11 (last checked for x86-64 container)
- nixos/unstable (bleeding edge for x86-64)
- List all
- incus image list images: | grep nixos
- How to run a command before it is added in configuration.nix:
- With flakes and experimental enabled
- nix run nixpkgs#git
- nix run nixpkgs#git -- commit -m 'init commit' # use '--' to run with arguments.
- With nix-shell (inside standard NixOS)
- nix-shell --packages git neovim
- With flakes and experimental enabled
- Add git to your configuration.nix
- programs.git = {enable = true;};
- Pure configuration (similar to flakes using niv + configuration.nix)
- command:
- Incus virtual machine (VM) from ISO
- Reference: https://linuxcontainers.org/incus/docs/main/howto/instances_create/#launch-a-vm-that-boots-from-an-iso
- Reference: https://blog.simos.info/how-to-run-a-windows-virtual-machine-on-incus-on-linux/
- Commands:
- sudo apt update
- sudo apt install virt-viewer
- incus storage volume import default /home/cb/Downloads/nixos-gnome-23.11.5474.fa9f817df522-x86_64-linux.iso iso-nixos-volume --type=iso
- Note: "default" is the name of the default pool
- incus init nixos-vm-01 --empty --vm -c security.secureboot=false -c limits.memory=4GiB -c limits.cpu=4 -d root,size=30GiB
- Note: secureboot false needed because the iso is not signed
- reference
- incus config device add nixos-vm-01 iso-nixos-volume disk pool=default source=iso-nixos-volume boot.priority=10
- incus start nixos-vm-01 --console
- followed by "ctrl+a q"
- incus console nixos-vm-01 --type=vga
- Note: complete the installation steps
- Note: stop the instance (do not simply reboot) so that you can detach the ISO
- incus storage volume detach default iso-nixos-volume nixos-vm-01
- Note: start the instance
- incus console nixos-vm-01 --type=vga
- AWS
- List of AWS NixOS images
- ami-091aa143fa84d4a10 (last checked for us-east-1 for x86-64)
Installing NIX (not NixOS)
Nix is both an application and an OS (NixOS). This section describes how to install the Nix application (language and NixPkgs) into an existing linux installation (PopOS in my case).
- ...Read all bullets before starting...
- Go to: https://nixos.org/download/ (current)
- Execute the multi-user command/option
- NOTE: there is an alternative installer
- Enables flakes by default
- Enable flakes if not already done yet
- echo "experimental-features = nix-command flakes" | sudo tee -a /etc/nix/nix.conf
Installing Nix on a Mac:
Installing Package Using Nix
When using the nix package manager, you can install a package using nix profile. Here is an example:
nix profile install nixpkgs#typst
Important References for Common Concepts
- Package Search: https://search.nixos.org/packages
- Options Search: https://search.nixos.org/options
- Rebuild: https://nixos.wiki/wiki/Nixos-rebuild
- Flakes: https://nixos.wiki/wiki/Flakes
- Cron: https://nixos.wiki/wiki/Systemd/Timers
- Firewall: https://nixos.wiki/wiki/Firewall
- Python: https://nixos.wiki/wiki/Python
- PostgreSQL: https://nixos.wiki/wiki/PostgreSQL
- Docker: https://nixos.wiki/wiki/Docker
- Nix Dev: https://nix.dev/
Other Details Worth Referencing
First Working Example with nix-shell
Summary: used Nix to create a nix-shell that installs (only inside the shell) all the tools I typically use to create and manage a database. Since I am using Nix (the application) and not NixOS, I do not want to install postgresql (psql) as a service. Instead, I simply want it available when I am using this particular shell in this particular directory.
The result of the below steps is an almost completely self contained instance of psql. Here are some things to be aware of:
- The postgresql.conf file is located in .tmp/mydb
- The only thing that escapes the shell is the fact that psql is running on a given port.
- If you stop the shell, it does not stop the instance of psql. Said another way, if you stop the shell, you will orphan psql. If you do not have the psql tool installed in your host machine, you will not be able to stop psql unless you either a) kill the process, b) reboot or c) enter back into the shell and stop the process using the shells pg_ctl tool.
Steps:
- Installed Nix in my existing computer using the above section.
- Create and change into a new directory named "basic-nix"
- Create and save the below shell.nix file
- Enter the shell using the command:
- nix-shell --pure
- note: the --pure prevents an existing environment variables or packages from interfering with your development experience.
- Create the DB 'instance' using:
- initdb -D .tmp/mydb --no-locale --encoding=UTF8 && echo "listen_addresses = ''" >> .tmp/mydb/postgresql.conf
- The echo => listen_address with an empty string command turns off TCP
- If initdb throws an no command found, use: export PATH=$PATH:/usr/lib/postgresql/<version>/bin comment to help it find the command.
- initdb -D .tmp/mydb --no-locale --encoding=UTF8 && echo "listen_addresses = ''" >> .tmp/mydb/postgresql.conf
- Start the DB using:
- pg_ctl -D .tmp/mydb -l logfile -o "--unix_socket_directories='$PWD'" start
- Notes:
- Note: use the "-F -p 5433" and no echo => listen_address if you wish to use tcp and set the port.
- Create the actual 'database' using:
- createdb mydb -h $PWD
- createdb mydb -h $PWD -p 5433 if you changed the port
- Connect to the database using:
- psql -h $PWD -d mydb
- psql -h $PWD -d mydb -p 5433 if you changed the port
- Check the status of the database using:
- pg_ctl -D .tmp/mydb -l logfile -o "--unix_socket_directories='$PWD'" status
- Stop the database using:
- pg_ctl -D .tmp/mydb -l logfile -o "--unix_socket_directories='$PWD'" stop
- Note: how to disable TCP (and only use a socket)
shell.nix:
let
nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/tarball/nixos-23.11";
pkgs = import nixpkgs { config = {}; overlays = []; };
in
pkgs.mkShellNoCC {
packages = with pkgs; [
cowsay
lolcat
man
neovim
git
tree
tmux
fd
wget
sysstat
curl
rsync
zip
unzip
pkg-config
gcc
cmake
jc
jq
jdk17_headless
maven
postgresql
starship
];
#note: the below variables are available in the shell without needing to export
GREETING = "Hello, Nix!";
EDITOR = "vim";
VISUAL = "vim";
shellHook = ''
echo $GREETING | cowsay | lolcat
source /home/cb/chuboe-system-configurator/.my_bash # my personal bash adds
alias vim='nvim'
alias vi='nvim'
alias sudo='/usr/bin/sudo' #needed since we do not want to re-install sudo and the -pure removes all previous references
eval "$(starship init bash)"
'';
# https://mgdm.net/weblog/postgresql-in-a-nix-shell/
}
First Working Example with NixOS
This section has evolved into this repo: Chuboe Nix Repo
The rest of this section is kept for reference just in case...
Notes about this example:
- Used with incus to create the container with NixOS using the command command:
- incus launch images:nixos/unstable nixos-01 -c security.nesting=true
- It does minimal configuration for psql regarding security. It is not appropriate for iDempiere yet
- Added to an Incus => NixOS instance (nixos version: 24.05)
- Also tested in AWS successfully with ami: ami-091aa143fa84d4a10 from here (nixos version: 23.11)
- Note that you can keep the below is a separate file (/etc/nixos/chuboe.nix) and simply import into /etc/nixos/configuration.nix if you wish.
Here are the details:
- Here is what I added to /etc/nixos/configuration.nix
- Note that the first line should include pkgs in configuration.nix, for example:
- { config, pkgs, lib, modulesPath, … }:
environment.systemPackages = with pkgs; [
#neovim #see below package for neovim - instead of here
jdk17_headless
maven
postgresql
];
# Define a user account. Don't forget to set a password with ‘passwd’.
users.users.cbn01 = {
isNormalUser = true;
description = "cbn01";
extraGroups = [ "networkmanager" "wheel" ];
packages = with pkgs; [
# firefox
# thunderbird
];
};
environment.shellAliases = {
"vim" = "nvim";
};
environment.etc."inputrc" = {
text = pkgs.lib.mkDefault( pkgs.lib.mkAfter ''
"\e[A": history-search-backward # arrow up
"\e[B": history-search-forward # arrow down
'');
};
programs.neovim = {
enable = true;
defaultEditor = true;
};
services.postgresql = {
settings = {
listen_addresses = "*";
};
enable = true;
enableTCPIP = true;
authentication = pkgs.lib.mkOverride 10 ''
local all all trust
host all all ::1/128 scram-sha-256
host all postgres 127.0.0.1/32 scram-sha-256
'';
};
# Enable the OpenSSH daemon.
services.openssh.enable = true;
# Open ports in the firewall.
networking.firewall.allowedTCPPorts = [ 22 80 443 ];
# networking.firewall.allowedUDPPorts = [ … ];
# Or disable the firewall altogether.
# networking.firewall.enable = false;
Wireguard
Configuring wireguard (assuming you get a wireguard config file) is as easy as the following instructions. If you have multiple vpns, you simply un-comment the one you want to use and nixos-rebuild.
- Including the following in your config:
- networking.wg-quick.interfaces.wg-zito.configFile = "/home/cb/rsync_remote/vpn/customer/custvpn.conf";
- Reloading your environment:
- sudo nixos-rebuild switch