I have a server.nix
file which is used by nixops. In that file there is app = (import app.nix. {})
. When I change something in server.nix
without changing anything in app.nix
, app.nix
still gets rebuilt. Is this how it should be? Shouldn’t nixops see that app.nix
derivation already exists with the same hash and simply use the existing stuff from the store?
If I had built app.nix with nix-build --no-out-link option then the following nix-build would not have rebuilt anything as nothing had changed.
It would be good if you could share a minimal example of the code that causes your issue.
# server.nix
{
network.enableRollback = true;
webserver = { config, pkgs, ... }:
let app = (import ./default.nix { });
in {
services.postgresql = {
enable = true;
package = pkgs.postgresql_13;
enableTCPIP = true;
};
services.postgresqlBackup.enable = true;
environment.systemPackages = with pkgs; [ htop wget emacs-nox ];
security.acme.email = "example@email.com";
security.acme.acceptTerms = true;
networking.firewall.allowedTCPPorts = [ 80 443 5432 ];
services.nginx = {
enable = true;
recommendedGzipSettings = true;
recommendedOptimisation = true;
virtualHosts."my-example-node-app.com" = {
forceSSL = true;
enableACME = true;
locations."/" = { proxyPass = "http://127.0.0.1:3000"; };
};
virtualHosts."example-nix-manual.com" = {
forceSSL = true;
enableACME = true;
locations = {
"/" = {
root =
"${config.system.build.manual.manualHTML}/share/doc/nixos/";
};
};
};
};
systemd.services.my-example-node-app = {
enable = true;
serviceConfig = {
WorkingDirectory = "${app}";
# run a nodejs server on port 3000
ExecStart = "${app}/server-bin";
};
wantedBy = [ "multi-user.target" ];
};
};
}
Hi. I use this server.nix
file with nixops (nixops create -d server-on-vbox server.nix vbox.nix
and then the deploy command).
The file called default.nix
contains building instructions of a nodejs project. If I only did nix-build default.nix --no-out-link
twice without changing a source file in my node’s project, the second build would finish without doing any building again as nothing has changed and it would take an already built derivation from the nix store.
However, when I only change something in server.nix
file and do not change anything in my nodejs project and do nixops deploy -d server-on-vbox
, it rebuilds the whole nodejs project again.
It looks like your default.nix file is in the same directory, so my first guess is that it is using the directory’s contents as a source and changing this file changes the source. Perhaps you could look into filtering the source.
# default.nix
src = builtins.filterSource (path: _:
baseNameOf path != "server.nix" && baseNameOf path != "vbox.nix") ./.;
This did what I was hoping for . Thanks @ryantm
I’ve tried to apply builtins.path
function as follows
let filteredSrc = builtins.filterSource (path: _:
baseNameOf path != "server.nix" && baseNameOf path != "vbox.nix")
(builtins.path {
path = ./.;
name = "example-proj";
});
Unfortunately, this fails with this error: while evaluating the attribute ‘src’ of the derivation … cannot refer to other paths, at …
Not sure about the error you are getting but you can probably get rid of filterSource
, since you can specify a filter inside the set passed to the builtins.path
. Like:
let filteredSrc = builtins.path {
path = ./.;
filter = path: _: baseNameOf path != "server.nix" && baseNameOf path != "vbox.nix";
name = "example-proj";
};
See builtins.path
under Introduction
Actually I’ve just tried what @ilkecan has suggested but found out that builtins.path
returns the path of the nix store path where the path, given as an argument, will be copied to, whether builtins.filterSource
returns the actual working directory path.
Using builtins.path
with filter
attribute rebuilds the project when changing server.nix
contents. Shouldn’t that work too as we filter that file? What causes nix to generate two different store paths in this case?
That sentence is a bit long and I am having a trouble understanding it. Can you explain what you mean?
Did you remove the name
attribute from the set passed to builtins.path
? Because if you removed it, the name of the directory will depend on the unfiltered one and the name of the unfiltered one depends on all the files including “server.nix”. If you didn’t remove the name
attribute I have no idea why it rebuilds.