# Translating docker to nix?!

Feb 28, 2023
docker podman nixos

In my opinion, there are moments when the convenience of docker and its surrounding ecosystem can’t be beat. I’ve been dabbling in the self hosting world and oftentimes the best maintained packaging option is a docker image. As a result of this I’ve been playing around with the nixos approach to managing docker containers.

### nix -> docker compose -> docker run

To illustrate how to translate a simple example from the world of docker to nix let’s have a look at the config for my searxng instance.

    virtualisation.oci-containers.containers."searxng" = {
      autoStart = true;
      image = "searxng/searxng";
      volumes = [
        "/srv/searx:/etc/searxng"
      ];
      environment = {
        BASE_URL = "https://searx.jdysmcl.xyz/";
        INSTANCE_NAME = "go on big boy dont be shy";
      };
      ports = [ "8080:8080" ];
    };

Here is the same thing written in a `docker-compose.yml` style format.

    services:
      searxng:
        image: searxng/searxng
        volumes:
          - /srv/searxng:/etc/searxng
        environment:
          - BASE_URL=https://searx.jdysmcl.xyz/;
    	  - INSTANCE_NAME=go on big boy dont be shy;
        ports:
          - "8080:8080"

Also, this is what it would look like as a simple old `docker run`.

    $ docker pull searxng/searxng
    $ docker run --rm \
                 -d -p 8080:8080 \
                 -v "/srv/searxng:/etc/searxng" \
                 -e "BASE_URL=http://searx.jdysmcl.xyz/" \
                 -e "INSTANCE_NAME=go on big boy dont be shy" \
                 searxng/searxng

### bits and bobs

As you can see, nix very kindly provides you with convenient options for the most essential tasks: mounting volumes, exposing ports, passing environment variables etc. But what about some more niche configurations that aren’t exposed in oci-containers.nix. As far as I can tell, your best bet in these scenarios is `virtualisation.oci-containers.containers.<name>.extraOptions`; this lets you pass a list of command line arguments to your docker run command. For example, I had this in my config for a vpn container.

    virtualisation.oci-containers.containers."vpn".extraOptions = [
      "--cap-add=net_admin"
      "--device=/dev/net/tun"
      "--network=bridge"
    ];

With a mishmash of these different bits and bobs I was able to do everything that I needed to. It doesn’t really open any more doors than docker compose but it’s nice to have the option when you’re already invested in the nix ecosystem.

One final note: nix provides the option to choose between docker and podman with `virtualisation.oci-containers.containers.backend`. This defaults to podman.