Django Dev here using docker for prod and dev env -- any guide to switch to Nix

Hi there,

I have been using docker for both my dev and prod env for my Django headless apps.

I discovered nix. I find it interesting. I am reluctant to abandon Docker. So I am wondering if there’s any guide to help ease the transition.

I did find this in discourse Looking for a nixops python/django example - #2 by DavHau but I was hoping for something that involves moving from Docker rather than simply make a Django in Nix

Thank you

I’m afraid there is currently no hands on tutorial to do exactly that.

In general I think it is a good idea to get a general understanding of how nix works and take some time to play around with it, before you move any project to nix.

To give you a rough idea of my django setup:

For the development itself, all you need is a python environment with all the libraries you are using.
To create the python environment I use mach-nix. The mach-nix based expression goes into a python.nix file.
Also I create a shell.nix with the following content:

(import ./python.nix).env

Now when executing nix-shell in that directory your python environment is loaded. (also you might want to take a look at direnv which simplifies that even further)

If you’re using an IDE like pycharm, you also need to execute

nix-build python.nix -o ./interpreter

To get a ./interpreter symlink of the python environment in your current directory.

In pycharm you can then load the interpreter by adding it as system interpreter in the project settings. Everytime you add a library you need to execute the above command again and restart pycharm. Sadly it is not able to pick up the changes automatically.

As mentioned in the other thread, for deployment I’m using django-nixos. It includes examples. Just pass (import ./python.nix) as python argument to django-nixos, to use the same python environment as in your dev env.

Concerning the manage.py in your dev env:

Always execute it via python manage.py, since the shebang inside manage.py is messed up for some reason.

2 Likes

I found this very interesting article about using Mach-nix together with Niv Niv and Mach-Nix for Nix Python :: Rohit Goswami — Reflections

2 cents from a nix noob: I’ve had success using poetry and poetry2nix. Here’s what I have for a FastAPI project:

# release.nix
let sources = import ./nix/sources.nix;
in { pkgs ? import sources.nixpkgs { } }:

let
  projectCfg = {
    projectDir = ./core;

    overrides = [
      pkgs.poetry2nix.defaultPoetryOverrides
      (self: super: {
        publicsuffix2 = super.publicsuffix2.override { preferWheel = true; };
      })
    ];
  };

  project = pkgs.poetry2nix.mkPoetryApplication projectCfg;
  env = pkgs.poetry2nix.mkPoetryEnv projectCfg;
in {

  project = project;

  shell = pkgs.mkShell {
    buildInputs = [
      pkgs.python3
      pkgs.python3Packages.pip
      pkgs.python3Packages.importmagic
      pkgs.python3Packages.epc
      pkgs.python3Packages.flake8
      pkgs.python3Packages.yapf
      pkgs.poetry
      pkgs.python-language-server
      env
    ];
    shellHook = ''
      export LOCALE_ARCHIVE="${pkgs.glibcLocales}/lib/locale/locale-archive";
    '';
  };
}

And two other files for nix:

# default.nix
(import ./release.nix { }).project
# shell.nix
(import ./release.nix { }).shell

I use Emacs for editing, so this nix configuration sets up all the dev-tools I need. I am using direnv and lorri, which allow me to have a workflow like:

  1. cd into my project to have python, poetry, and all the requirements set in my own shell. No need to leave my fine-tuned zsh for nix-shell’s default bash
  2. Open any project file, and Emacs automatically pick the right python, python-language-server etc thanks to emacs-direnv plugin
  3. Adding a dependency is just running poetry add <dep>

Overall this is a pretty sweat deal comparison to docker. With docker I used to get my just my application isolated, with nix, I can have the complete dev-toolchain isolated in its own directory.

This is specially a win because I am not a regular python dev. I usually do [java|type]script for work, and get to python projects occasionally when I have some time to fiddle on something and I feel like using python. It was also helpful when passing projects around to colleagues who don’t have right tools (i.e poetry) installed.

1 Like