I’m very new to nix, so please forgive if I haven’t grasped all the concepts.
I have a project in an interpreted language, e.g. R. So far I have come up with this flake.nix
.
I have three modes, test, development, production, with shared and distinct packages.
Now I can do e.g. nix develop .#test
and I’m dropped into a shell that has only the correct packages and the APP_ENV
environment variable set.
How do I go on from here, obviously I don’t only want a development shell but also provide some entry points, e.g. for test a way to run the tests, for production to start a random command that is the entry point.
Ultimately I want to build a docker image from the production set of packages. So far I have a rather peculiar non-nix setup that build two docker images: one base image with all libraries and one that pulls in the base image and slaps the code on top. This way I can greatly reduce CI build times because in most cases I can just pull in the unchanged base image.
I would also be fine to have a setup of regular dockerfiles that internally use nix, orchestrated by shell scripts for now that just install the layers that are necessary, and then have a nix ...
entrypoint.
So these are a few questions at the same time, but basically, how do I continue from a development shell to entrypoints for other things like running scripts, and how do I make sure that these scripts don’t result in any build work at runtime?
Thanks alot!
{
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
inputs.flake-utils.url = "github:numtide/flake-utils";
outputs = { self, nixpkgs, flake-utils }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = nixpkgs.legacyPackages.${system};
base = with pkgs; [ R ];
production = base ++ (with pkgs.rPackages; [ box dplyr sf ]);
test = production ++ (with pkgs.rPackages; [ tinytest ]);
development = test ++ (with pkgs; [ nixfmt-classic ])
++ (with pkgs.rPackages; [ languageserver styler lintr ]);
in {
devShells = {
default = pkgs.mkShell {
nativeBuildInputs = [ pkgs.bashInteractive ];
buildInputs = development;
shellHook = ''
export APP_ENV="development"
'';
};
test = pkgs.mkShell {
nativeBuildInputs = [ pkgs.bashInteractive ];
buildInputs = test;
shellHook = ''
export APP_ENV="test"
'';
};
production = pkgs.mkShell {
nativeBuildInputs = [ pkgs.bashInteractive ];
buildInputs = production;
shellHook = ''
export APP_ENV="production"
'';
};
};
});
}