So I am making a flake for a little project. I am struggling with splitting it up into multiple files. I am both outputting packages and a nixos module. I would prefer to break up the nixos module in related parts. But I want to include a package I am making in both that nixos module and the packages part of the flake. One issue that I have is that most examples I have seen have the nixosModules
output free from any references to system, but the package itself has a dependency on system somewhere.
Here are simplified versions of the structure I have been aiming at:
flake.nix
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
pyproject-nix = {
url = "github:pyproject-nix/pyproject.nix";
inputs.nixpkgs.follows = "nixpkgs";
};
uv2nix = {
url = "github:pyproject-nix/uv2nix";
inputs.pyproject-nix.follows = "pyproject-nix";
inputs.nixpkgs.follows = "nixpkgs";
};
pyproject-build-systems = {
url = "github:pyproject-nix/build-system-pkgs";
inputs.pyproject-nix.follows = "pyproject-nix";
inputs.uv2nix.follows = "uv2nix";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs =
{
self,
nixpkgs,
flake-utils,
uv2nix,
pyproject-nix,
pyproject-build-systems,
...
}@inputs:
flake-utils.lib.eachDefaultSystem (system: let
inherit (nixpkgs) lib;
workspace = uv2nix.lib.workspace.loadWorkspace { workspaceRoot = ./.; };
# Create package overlay from workspace.
overlay = workspace.mkPyprojectOverlay {
sourcePreference = "wheel"; # or sourcePreference = "sdist";
};
pyprojectOverrides = final: prev: {
# various overrides
};
pkgs = import nixpkgs {
inherit system;
config.allowUnfree = true;
# TODO: maybe use overlay here?
};
python = pkgs.python312;
pythonSet = (pkgs.callPackage pyproject-nix.build.packages { inherit python; })
.overrideScope (lib.composeManyExtensions [
pyproject-build-systems.overlays.default
overlay
pyprojectOverrides
]);
venv = (pythonSet.mkVirtualEnv "env" workspace.deps.default).overrideAttrs(old: {
venvIgnoreCollisions = [ "*" ];
});
# Wrapper script to run FastAPI inside the environment
fastapiRunner = pkgs.writeShellScriptBin "fastapi-server" ''
cd ${venv}/lib/python3.12/site-packages
ls
exec ${venv}/bin/python -m fastapi --verbose run --app hello_world.main:app
'';
in
{
packages = {
default = venv;
web-service-env = venv;
};
# Make hello runnable with `nix run`
apps = {
default = {
type = "app";
program = "${self.packages.${system}.default}/bin/geotopo";
};
};
}) // {
nixosModules.default = {
imports = [
./nix
];
};
};
}
/nix/default.nix
{ config, lib, pkgs, ...}:
with lib; let
cfg = config.services.something;
in {
imports = [
./web-service
];
options.services = {
# various options
};
config = mkIf cfg.enable {
# set a few things
};
}
/nix/web-service/default.nix
{ config, lib, pkgs, utils, ...}:
with lib; let
cfg = config.services.thingy.web-service;
# TODO: how to refer to own package?
web-service-env = pkgs.web-service-env;
in {
imports = [
];
options.services.thingy.web-service = {
enable = mkOption {
type = types.bool;
default = false;
example = true;
description = ''
Whether or not to enable the geotopo web service module.
'';
};
package = mkOption {
type = types.package;
default = web-service-env;
description = "package to use for this service (defaults to the one in the flake)";
};
};
config = mkIf cfg.enable {
assertions = [
];
# Systemd service
systemd.services.my-web-service = {
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
ExecStart = "${cfg.package}/bin/app";
};
};
};
}
In this last file I am trying to access the package somehow. I have tried quite a few approaches but to no avail.