-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathflake.nix
126 lines (117 loc) · 4.38 KB
/
flake.nix
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
{
description = "Python + UV container build utilities";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
nix2container.url = "github:nlewo/nix2container";
nix2container.inputs.nixpkgs.follows = "nixpkgs";
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { self, nixpkgs, nix2container, flake-utils }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs { inherit system; };
lib = {
uv2container = rec {
buildDepsLayer =
{ python
, uv ? pkgs.uv
, src
, extraBuildInputs ? [ ]
}: pkgs.stdenv.mkDerivation {
name = "python-venv";
inherit src;
__noChroot = true;
dontFixup = true;
nativeBuildInputs = [ python uv ] ++ extraBuildInputs;
buildPhase = ''
runHook preBuild
export UV_LINK_MODE=copy
export PATH=".venv/bin:$PATH"
export UV_PYTHON_PREFERENCE="only-system"
export UV_PYTHON="${python}/bin/python${python.pythonVersion}"
export VIRTUAL_ENV=$out
export UV_PROJECT_ENVIRONMENT=$out
mkdir -p $VIRTUAL_ENV
uv venv
uv sync --no-cache --no-install-project --locked
'';
installPhase = ''
runHook preInstall
runHook postInstall
'';
};
defaultFilesetFilter = (file: file.hasExt "py");
buildImage =
{ name
, python
, src
, extraBuildInputs ? [ ]
, runtimeLibs ? [ ]
, filesetFilter ? defaultFilesetFilter
, config ? { }
}:
let
depsLayer = buildDepsLayer {
inherit python src extraBuildInputs;
};
sourcesLayer = pkgs.lib.fileset.toSource
{
root = src;
fileset = pkgs.lib.fileset.fileFilter filesetFilter src;
};
defaultEnv = [
"PYTHONPATH=${depsLayer}/lib/python${python.pythonVersion}/site-packages:${python}/lib/python${python.pythonVersion}/site-packages"
"LD_LIBRARY_PATH=${pkgs.lib.makeLibraryPath ([ pkgs.stdenv.cc.cc.lib ] ++ runtimeLibs)}"
"PATH=${depsLayer}/bin:${python}/bin:/bin"
];
in
(nix2container.packages.${system}.nix2container.buildImage {
inherit name;
config = config // {
Env = defaultEnv ++ (if builtins.hasAttr "Env" config then config.Env else [ ]);
};
layers = [
(nix2container.packages.${system}.nix2container.buildLayer { deps = [ depsLayer ]; })
(nix2container.packages.${system}.nix2container.buildLayer { deps = ([ python ] ++ runtimeLibs); })
(nix2container.packages.${system}.nix2container.buildLayer {
copyToRoot = [ sourcesLayer ];
})
];
}).overrideAttrs (old: {
buildInputs = [ python ] ++ extraBuildInputs;
nativeBuildInputs = [ pkgs.uv ];
propagatedBuildInputs = runtimeLibs;
});
};
};
in
{
lib = lib;
packages = rec {
example-flask-app = let
python = pkgs.python314;
in lib.uv2container.buildImage {
name = "example-flask-app";
inherit python;
src = ./examples/flask-app;
config = {
Cmd = [ "python" "-m" "flask" "run" "--host=0.0.0.0" ];
WorkingDir = "/src";
ExposedPorts = {
"5000/tcp" = { };
};
};
};
example-as-dir = pkgs.runCommand "docker-as-dir" { }
"${example-flask-app.copyTo}/bin/copy-to dir:$out";
};
devShells.default = pkgs.mkShell {
inputsFrom = [ self.packages.${system}.example-flask-app ];
packages = with pkgs; [
nil
nixpkgs-fmt
];
};
formatter = pkgs.nixpkgs-fmt;
});
}