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