+++ title = "Running non Nixpkgs services on NixOS, the lazy way" date = 2025-04-05T14:09:14+01:00 draft = false +++ NixOS is really nice for self hosting. Anything that has a NixOS module can be hosted in a few lines of nix code. But what if the service we want to host doesn't come with a NixOS module written for us already in Nixpkgs? This is where NixOS can be a little hard, as a guide on setting up a service in Debian or Arch will rarely work on NixOS. Of course, the 'nix way' would be to write your own package and module for it, but that can be a daunting task. Here are some 'escape hatches' to host some of the simpler services without having to write your own Nix package or module. ## Nginx If the application is a simple static website, containing just HTML and JS, the `nginx` module on NixOS provides us with a way to manage virtual hosts complete with https. Shown is how I host my Hugo generated blog. ```nix { config, ... }: { services.nginx.virtualHosts."gabevenberg.com" = { enableACME = true; forceSSL = true; root = "/var/www/gabevenberg.com"; }; security.acme = { acceptTerms = true; defaults.email = "myname@example.com"; }; networking.firewall.allowedTCPPorts = [443 80]; } ``` The complete list of options for virtual hosts can be found [here](https://nixos.org/manual/nixos/stable/options#opt-services.nginx.virtualHosts) ## Docker If the service publishes a Docker image, one can just run that on NixOS. Here's how I host a game server using a premade docker container. Things get a bit more complicated with docker-compose, but one can use [compose2nix](https://github.com/aksiksi/compose2nix) to translate a docker-compose.yaml file into a nix file much like the one shown. ```nix { config, ... }: { virtualisation.oci-containers = { backend = "docker"; containers.factorio = { image = "factoriotools/factorio:stable"; volumes = ["/storage/factorio:/factorio"]; hostname = "factorio"; ports = ["34197:34197/tcp"]; environment = {UPDATE_MODS_ON_START = "true";}; }; }; virtualisation.docker.enable = true; } ``` There are, of course, more options for the oci-containers module, found [here](https://nixos.org/manual/nixos/stable/options#opt-virtualisation.oci-containers.containers) ## Systemd Finally, if the service is composed of a single static binary, NixOS makes it really easy to write Systemd services. (I've used a package in Nixpkgs here, but you could just as easily point the Systemd service to a binary you threw in `/opt/` or somewhere.) ```nix { config, ... }: { systemd.services.miniserve = { wantedBy = ["multi-user.target"]; after = ["network.target"]; description = "A directory miniserve instance"; environment = {MINISERVE_ENABLE_TAR_GZ="true";} serviceConfig.ExecStart = "${pkgs.miniserve}/bin/miniserve -i 127.0.0.1 -- /storage/miniserve" }; } ``` And like the last 2 times, the complete list of options for Systemd service can be found [here](https://nixos.org/manual/nixos/stable/options.html#opt-systemd.services) *(This article was originally published in issue #6 of the [Paged Out!](https://pagedout.institute/) magazine.)*