Title: Using Arion to use NixOS modules in containers | |
Author: Solène | |
Date: 21 September 2022 | |
Tags: nixos containers docker podman | |
Description: This article explains how to use Arion to create | |
containers using NixOS modules instead of a simple entrypoint. | |
# Introduction | |
NixOS is cool, but it's super cool because it has modules for many | |
services, so you don't have to learn how to manage them (except if you | |
want them in production), and you don't need to update them like a | |
container image. | |
But it's specific to NixOS, while the modules are defined in the nix | |
nixpkgs repository, you can't use them if you are not using NixOS. | |
But there is a trick, it's called arion and is able to generate | |
containers to leverage NixOS modules power in them, without being on | |
NixOS. You just need to have Nix installed locally. | |
arion GitHub project page | |
Nix project page | |
# Docker vs Podman | |
Long story short, docker is a tool to manage containers but requires | |
going through a local socket and root daemon to handle this. Podman is | |
a docker drop-in alternative that is almost 100% compatible (including | |
docker-compose), and can run containers in userland or through a local | |
daemon for more privileges. | |
Arion works best with podman, this is so because it relies on some | |
systemd features to handle capabilities, and docker is diverting from | |
this while podman isn't. | |
Explanations about why Arion should be used with podman | |
# Prerequisites | |
In order to use arion, I found these prerequisites: | |
* `nix` must be in path | |
* podman daemon running | |
* `docker` command in path (arion is calling docker, but to use podman) | |
* `export DOCKER_HOST=unix:///run/podman/podman.sock` | |
# Different modes | |
Arion can create different kind of container, using more or less parts | |
of NixOS. You can run systemd services from NixOS, or a full blown | |
NixOS and its modules, this is what I want to use here. | |
There are examples of the various modes that are provided in arion | |
sources, but also in the documentation. | |
Arion documentation | |
Arion GitHub project page: examples | |
# Let's try! | |
We are now going to create a container to run a Netdata instance: | |
Create a file arion-compose.nix | |
``` | |
{ | |
project.name = "netdata"; | |
services.netdata = { pkgs, lib, ... }: { | |
nixos.useSystemd = true; | |
nixos.configuration.boot.tmpOnTmpfs = true; | |
nixos.configuration = { | |
services.netdata.enable = true; | |
}; | |
# required for the service, arion tells you what is required | |
service.capabilities.SYS_ADMIN = true; | |
# required for network | |
nixos.configuration.systemd.services.netdata.serviceConfig.AmbientCapabilit… | |
lib.mkForce [ "CAP_NET_BIND_SERVICE" ]; | |
# bind container local port to host port | |
service.ports = [ | |
"8080:19999" # host:container | |
]; | |
}; | |
} | |
``` | |
And a file arion-pkgs.nix | |
```nix | |
import <nixpkgs> { | |
system = "x86_64-linux"; | |
} | |
``` | |
And then, run `arion up -d`, you should have Netdata reachable over | |
http://localhost:8080/ , it's managed like any docker / podman | |
container, so usual commands work to stop / start / export the | |
container. | |
Of course, this example is very simple (I choose it for this reason), | |
but you can reuse any NixOS module this way. | |
# Making changes to the network | |
If you change the network parts, you may need to delete the previous | |
network creating in docker. Just use `docker network ls` to find the | |
id, and `docker network rm` to delete it, then run `arion up -d` again. | |
# Conclusion | |
Arion is a fantastic tool allowing to reuse NixOS modules anywhere. | |
These modules are a huge weight in NixOS appeal, and being able to use | |
them outside is a good step toward a ubiquitous Nix, not only to build | |
programs but also to run services. |