Skip to content

Instantly share code, notes, and snippets.

@luochen1990
Last active March 29, 2024 12:18
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save luochen1990/030ddc18716e5b8b14374621be524d9a to your computer and use it in GitHub Desktop.
Save luochen1990/030ddc18716e5b8b14374621be524d9a to your computer and use it in GitHub Desktop.
Nix Script to simulate FHS environment with python3 & pip & venv
#!/usr/bin/env -S bash -c 'nix-shell --pure $0 -A env'
# Usage:
# 1. run directly to enter bash (inside venv): `./venv-py37.nix`
# 2. build a standalone executable: `nix bundle -f ./venv-py37.nix` #this not works yet since it cause nested `unshare -U` call
# 3. run bash with extra arguments: `nix run -f ./venv-py37.nix '' -- -c 'python --version'`
# More:
# 1. commit id of nixpkgs can be found here: https://lazamar.co.uk/nix-versions/?channel=nixpkgs-unstable&package=python3
let
makeOverridable = f: f {} // { override = y: makeOverridable (x: f (x // y)); };
in
makeOverridable ({
pyver ? "37",
prepare ? ''
#pip3 config set global.index-url https://mirrors.aliyun.com/pypi/simple/
pip3 install --upgrade pip setuptools wheel
cd ${builtins.toString ./.} && pip3 install -r requirements-freeze.txt && cd -
'',
pkgs ? import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/c9a97ff47bb0db44f4a504015a5d1cedb3094c85.tar.gz") {}
}: (
let systemLevelPackages = with pkgs; [
# search: https://search.nixos.org/packages?&query=python+gssapi
pkgs."python${pyver}Packages".gssapi
heimdal.dev #for gssapi & krb5; See: https://github.com/NixOS/nixpkgs/issues/33103#issuecomment-796419851
];
in pkgs.buildFHSUserEnv {
name = "venv-py${pyver}";
targetPkgs = pkgs: ((with pkgs; [
pkgs."python${pyver}"
pythonManylinuxPackages.manylinux2014Package
openssl
zlib
(lib.hiPrio gcc) #for native build wheel
]) ++ systemLevelPackages);
profile = ''
export PROMPT_COMMAND='PS1="\[\033[01;32m\]venv-py${pyver}\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ ";unset PROMPT_COMMAND'
python3 -m venv --system-site-packages ${builtins.toString ./.venv-py${pyver}}
source ${builtins.toString ./.venv-py${pyver}/bin/activate}
'' + prepare;
runScript = "bash";
})
)
#!/usr/bin/env -S bash --norc -c 'nix-shell --pure $0 -A env'
(import ./venv37.nix).override { pyver = "38"; }
@luochen1990
Copy link
Author

luochen1990 commented Mar 3, 2022

We can also parameterize the python version as pyver as following:

let pyver = "37"; in {
  targetPkgs = [
    pkgs."python${pyver}"
    pkgs."python${pyver}Packages".pip
  ];
}

@luochen1990
Copy link
Author

Shebang can be replaced as following, so that it's independent with the filename:

#!/usr/bin/env -S bash -c 'nix-shell --pure $0 -A env'

@luochen1990
Copy link
Author

Known limitation:

  • This script not works with nix bundle, since unshare -U cannot be nested
  • This script not works inside a docker container, since unshare -U cannot be nested

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment