Bloc notes | Python, Nix and Docker


Posted on January 5, 2018 by Alex comments [python nix docker]

Initialise Python project

mkdir sample_python_nix_docker; cd sample_python_nix_docker
echo "flask" > requirements.txt
cat <<EOF > hello.py
#!/usr/bin/env python

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"

if __name__ == "__main__":
    app.run("0.0.0.0")
EOF
cat <<EOF > setup.py
from pip.req import parse_requirements
from setuptools import setup

install_reqs = parse_requirements('requirements.txt', session='dev')
reqs = [str(ir.req) for ir in install_reqs]

setup(
    name='hello',
    scripts=['hello.py'],
    install_requires=reqs,
)
EOF

Initialise Nix

Generate requirements.nix

nix-shell -p pypi2nix --run "pypi2nix -r ./requirements.txt -V3"

Create Python environement

nix-build requirements.nix -A interpreter -o .env

Now, .env can be used with pycharm, emacs …

Build my app !

cat <<EOF > default.nix
{ }:

let
  pkgs = import <nixpkgs> {};
  python = import ./requirements.nix { inherit pkgs; };
in python.mkDerivation {
  name = "hello-1.0.0";
  src = ./.;
  buildInputs = [
    python.packages."Flask"
  ];
  propagatedBuildInputs = [
    python.packages."Flask"
  ];
}
EOF

./result/bin/hello.py

Initialise Docker

cat <<EOF > docker.nix
with import <nixpkgs> {};

let
  hello = import ./default.nix {};
in {
  helloImage = dockerTools.buildImage {
    name = "hello";
    contents = [
      hello
    ];
    config = {
      EntryPoint = ["hello.py"];
      ExposedPorts = {
        "5000/tcp" = {};
      };
    };
  };
}
EOF
nix-build docker.nix -o docker-img
cat docker-img | docker load
docker run -it --rm -p 5000:5000 hello

Sources : https://github.com/apeyroux/sample_python_nix_docker