|
1 | 1 | {
|
2 |
| - description = "A Nix-flake-based Python development environment"; |
3 |
| - |
4 |
| - inputs.nixpkgs.url = "https://flakehub.com/f/NixOS/nixpkgs/0.1.*.tar.gz"; |
| 2 | + description = "AudioBookRequest"; |
5 | 3 |
|
| 4 | + inputs = { |
| 5 | + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; |
| 6 | + flake-utils = { |
| 7 | + url = "github:numtide/flake-utils"; |
| 8 | + inputs.nixpkgs.follows = "nixpkgs"; |
| 9 | + }; |
| 10 | + pyproject-nix = { |
| 11 | + url = "github:pyproject-nix/pyproject.nix"; |
| 12 | + inputs.nixpkgs.follows = "nixpkgs"; |
| 13 | + }; |
| 14 | + uv2nix = { |
| 15 | + url = "github:pyproject-nix/uv2nix"; |
| 16 | + inputs.pyproject-nix.follows = "pyproject-nix"; |
| 17 | + inputs.nixpkgs.follows = "nixpkgs"; |
| 18 | + }; |
| 19 | + pyproject-build-systems = { |
| 20 | + url = "github:pyproject-nix/build-system-pkgs"; |
| 21 | + inputs.pyproject-nix.follows = "pyproject-nix"; |
| 22 | + inputs.uv2nix.follows = "uv2nix"; |
| 23 | + inputs.nixpkgs.follows = "nixpkgs"; |
| 24 | + }; |
| 25 | + }; |
6 | 26 |
|
7 |
| - outputs = { self, nixpkgs, ... }: |
| 27 | + outputs = { self, nixpkgs, flake-utils, pyproject-nix, uv2nix, pyproject-build-systems, ... }: flake-utils.lib.eachDefaultSystem (system: |
8 | 28 | let
|
9 |
| - supportedSystems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ]; |
10 |
| - forEachSupportedSystem = f: nixpkgs.lib.genAttrs supportedSystems (system: f { |
11 |
| - pkgs = import nixpkgs { inherit system; }; |
12 |
| - }); |
| 29 | + pkgs = import nixpkgs { inherit system; }; |
| 30 | + python = pkgs.python312; |
| 31 | + workspace = uv2nix.lib.workspace.loadWorkspace { workspaceRoot = ./.; }; |
| 32 | + |
| 33 | + pyprojectOverrides = final: prev: { |
| 34 | + # both fastapi and fastapi-cli add the binary causing "FileCollisionError: Two or more packages are trying to provide the same file with different contents" |
| 35 | + fastapi-cli = prev.fastapi-cli.overrideAttrs(_: { postInstall = "rm $out/bin/fastapi"; }); |
| 36 | + }; |
| 37 | + |
| 38 | + overlay = workspace.mkPyprojectOverlay { sourcePreference = "wheel"; }; |
| 39 | + pythonSet = (pkgs.callPackage pyproject-nix.build.packages { inherit python; }).overrideScope ( |
| 40 | + pkgs.lib.composeManyExtensions [ |
| 41 | + pyproject-build-systems.overlays.default |
| 42 | + overlay |
| 43 | + pyprojectOverrides |
| 44 | + ] |
| 45 | + ); |
13 | 46 | in
|
14 |
| - { |
| 47 | + rec { |
| 48 | + packages = rec { |
| 49 | + # Creates a separate nix store virtualenv with the default dependencies (no devDependencies) |
| 50 | + default = pythonSet.mkVirtualEnv "audiobookrequest-venv" workspace.deps.default; |
15 | 51 |
|
16 |
| - devShells = forEachSupportedSystem ({ pkgs }: { |
17 |
| - default = pkgs.mkShell { |
18 |
| - venvDir = ".venv"; |
19 |
| - packages = with pkgs; [ python312 nodejs_23 sqlite nodePackages.browser-sync uv ] ++ |
20 |
| - (with pkgs.python312Packages; [ |
21 |
| - venvShellHook |
22 |
| - ]); |
| 52 | + |
| 53 | + docker = |
| 54 | + let |
| 55 | + npmDeps = pkgs.importNpmLock.buildNodeModules { |
| 56 | + package = pkgs.lib.importJSON ./package.json; |
| 57 | + packageLock = pkgs.lib.importJSON ./package-lock.json; |
| 58 | + nodejs = pkgs.nodejs_23; |
| 59 | + }; |
| 60 | + tw-init = pkgs.writeShellScriptBin "tw-init" '' |
| 61 | + ln -s ${npmDeps}/node_modules node_modules |
| 62 | + cp ${./static/tw.css} tw.css # copy over the file since tailwind looks for daisyui relative to the input file |
| 63 | + ${pkgs.tailwindcss_4}/bin/tailwindcss -i tw.css -o $out/app/static/globals.css -m |
| 64 | + ''; |
| 65 | + run = pkgs.writeShellScriptBin "run" '' |
| 66 | + ${default}/bin/alembic upgrade heads |
| 67 | + ${default}/bin/fastapi run --port $ABR_APP__PORT |
| 68 | + ''; |
| 69 | + gitignore = pkgs.nix-gitignore.gitignoreSource [ ] ./.; |
| 70 | + in |
| 71 | + pkgs.dockerTools.buildImage { |
| 72 | + name = "audiobookrequest"; |
| 73 | + |
| 74 | + copyToRoot = pkgs.buildEnv { |
| 75 | + name = "test"; |
| 76 | + paths = []; |
| 77 | + postBuild = '' |
| 78 | + mkdir -p $out/app/static |
| 79 | + ${tw-init}/bin/tw-init |
| 80 | + cp ${gitignore}/alembic.ini $out/app/alembic.ini |
| 81 | + cp -r ${gitignore}/alembic $out/app/alembic |
| 82 | + cp -r ${gitignore}/templates $out/app/templates |
| 83 | + cp -r ${gitignore}/static $out/app/static |
| 84 | + cp -r ${gitignore}/app $out/app/app |
| 85 | + ''; |
| 86 | + }; |
| 87 | + |
| 88 | + config = { |
| 89 | + WorkingDir = "/app"; |
| 90 | + Cmd = [ "${run}/bin/run" ]; |
| 91 | + ExposedPorts = { |
| 92 | + "8000/tcp" = {}; |
| 93 | + }; |
| 94 | + Env = [ |
| 95 | + "ABR_APP__PORT=8000" |
| 96 | + "ABR_APP__VERSION=${builtins.readFile ./static/version}" |
| 97 | + ]; |
| 98 | + }; |
23 | 99 | };
|
24 |
| - }); |
25 |
| - }; |
| 100 | + }; |
| 101 | + |
| 102 | + # What is run when we use `nix run . -- dev` |
| 103 | + apps.default = { |
| 104 | + type = "app"; |
| 105 | + program = "${packages.default}/bin/fastapi"; |
| 106 | + }; |
| 107 | + |
| 108 | + # Create a .venv and activates it. Allows for the venv to easily be selected in the editor for the python interpreter |
| 109 | + devShells.default = pkgs.mkShell { |
| 110 | + venvDir = ".venv"; |
| 111 | + packages = with pkgs; [ nodejs_23 sqlite nodePackages.browser-sync python312Packages.venvShellHook uv ]; |
| 112 | + postShellHook = "uv sync"; |
| 113 | + }; |
| 114 | + }); |
26 | 115 | }
|
0 commit comments