translating docker to nix?!
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.