NixOS configuration conditional on the vmVariant

Yesterday I learned about

nix run .#nixosConfigurations.<hostname>.config.system.build.vm

and the

  virtualisation.vmVariant = {
    virtualisation.forwardPorts = [
      { from = "host"; host.port = 8888; guest.port = 80; }
    ];
    virtualisation.memorySize = 8096;
    virtualisation.diskSize = 50000;
    users.users.root.initialPassword = "test";
  };

option which allows me to test a server configuration locally (where I need root to have a password and I need some port forwarding) without uncommenting these settings for testing. Very neat!

I found that there other options I’d like to be different when building a vm from when building for production, mostly around SSL. For example, in production, I have

  services.nginx.virtualHosts = {
    "loogle.lean-lang.org" = {
      enableACME = true;
      default = true;
      forceSSL = true;
      locations = {
        "/" = {
          proxyPass = "http://localhost:8080";
        };
      };
    };
  };

but for local testing forceSSL is quite annoying.

What is the idiomatic way of setting that option to true for production, but to false when using the vm build?


I currently work around it using

let
  # a bit of a hack
  inVM = config.networking.dhcpcd.extraConfig == "noarp";
in

based on a line in nixos/modules/virtualisation/qemu-vm.nix, and this allows me to write

      forceSSL = !inVM;

but that’s of course not particularly elegant.

You could create your own option with default = true and set things like forceSSL depending on the value of that option. Then you just set it to false in the vmVariant config. I like this anyway, because it lets you make semantically relevant configuration options.

Side note, do you want to disable ACME with this as well? I imagine LetsEncrypt probably doesn’t like it when you request certificates in the VM and never answer the challenge :stuck_out_tongue:

1 Like

I never defined my own options before, but it’s probably a good time to learn how to do so :slight_smile:

Yes, I should also remove ACME stuff as well to avoid the logspam it entails. The forceSSL was more annoying however.