About me: My name is Solène Rapenne, pronouns she/her. I like learning and sharing knowledge. Hobbies: '(NixOS BSD OpenBSD Lisp cmdline gaming internet-stuff). I love percent and lambda characters. OpenBSD developer solene@.

Contact me: solene on libera.chat, solene+www at dataswamp dot org or @solene@bsd.network (mastodon). If for some reason you want to support my work, this is my paypal address: donate@perso.pw.

Using Arion to use NixOS modules in containers

Written by Solène, on 21 September 2022.
Tags: #nixos #containers #docker #podman

Comments on Fediverse/Mastodon

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.AmbientCapabilities =
      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

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.