Recommended way to run multiple different applications on a single nixos VPS?

I have a small VPS that should suffice for several of my small side projects. Currently it’s running two old PHP applications. I got help to setup that from Tutorial for setting up the LAMP stack on a NixOS server?. However, now I wish to also deploy a couple of applications in other programming languages to the same VPS. How would you recommend me to manage this? What I’m currently thinking is to run each application as a docker container, and have nginx installed directly on the nixos host system work as a reverse proxy to the containers.

2 Likes

It’s a good idea, that I too use a lot with nixos containers it’s straightforward

Thanks for responding! How are you managing deployment of the different applications? Currently I have one git repo for managing the VPS, and different repos for my applications. I’m looking for a good way to be able to deploy the different applications from their own repositories. Perhaps have a script in each of the app repos that pushes a new docker image version to the VPS?

Docker? You don’t really need Docker, but of course it’s a way to do it if you prefer it. I do it as follows…

Every application defines a default.nix or a release.nix that at least publishes a package for it, sometimes even some more stuff for installing it into a NixOS host / container, for an example see SoL.

The other side is the installation on the system, where the applications are running in their own nixos container, publishing their stuff on an assigned localhost port. This is an example module that uses that SoL repo above:

{ config, pkgs, ... }:
  let
    solHash = "2993c64097b86d2ad2b1a2bb8dff6d66483acab3";
    sol4 = builtins.fetchTarball {
      url = "https://gitlab.com/metapensiero/SoL/-/archive/${solHash}/SoL-${solHash}.tar.gz";
      sha256 = "0a0yprnp9pvwgpib0rlcdz6960x4ahgwr6z3krb49mi602xm05jr";
      name = "Sol4";
    };
    # when developing:
    # sol4 = ../../../sol/SoL;
  in {
    containers = {
      sol4 = {
        autoStart = true;
        bindMounts = {
          var = {
            hostPath = "/mnt/sol4";
            mountPoint = "/var/lib/sol";
            isReadOnly = false;
          };
        };
        config =  { config, pkgs, ... }: {
          imports = [
            (sol4 + "/nixos/config.nix")
          ];
          config = {
            services.sol = {
              enable = true;
              configPath = ./secret/sol4-config.ini;
              policy = "upgrade";
            };
          };
        };
      };
    };
  }

This uses the “system configuration” from the SoL repo itself, see nixos/config.nix · master · metapensiero / SoL · GitLab

And then Nginx soes the reverse proxying:

{ config, pkgs, ... }: {

  # the web services are used just to get a certificate for free

  services.nginx = {
    enable = true;

    recommendedGzipSettings = true;
    recommendedProxySettings = true;

    virtualHosts = {
      "sol.metapensiero.it" = {
        forceSSL = true;
        enableACME = true;
        serverAliases = [
          "sol4.metapensiero.it" "sol4.arstecnica.it"
          "sol.arstecnica.it"
        ];
        locations."/" = {
          proxyPass = "http://localhost:6996";
        };
      };
    };
  };
}

Piece of cake, with NixOS!

Of course that’s for the installation on my spare server. Clients usually pack much more applications together, and have precise rules about logging, backup… so generally for them I develop “libraries” of configuration modules that help automate most of that stuff, and more :wink:

2 Likes