Opening a legacy django dev environment under NixOS

Hi,

I have a Django project development environment previously created under Ubuntu that I’d like to open under NixOS. I have a requirements.txt available. I’ve been trying different solutions found online but I always hit various errors, so I’d like to start over by asking for help here instead of trying to follow out of context examples :slight_smile:

The goal is to open the project in order to demo it before it’ll be taken over by another dev, not to keep developing it under NixOS. I could probably set up a VM under Ubuntu but I thought it was a good opportunity to learn how to open legacy Python environments.

I’m running NixOS 24.11, with flakes and Home Manager (but could perfectly do without flakes regarding this specific topic).

Happy to provide any additional info that might help.

Thanks!

Same here! I am in exactly the same situation. I have inherited a legacy Django code base with the previous build environment being a different distro as well. For years I have been building my Django websites using pip tools and a Python virtual environment locally on Manjaro and deployed to Heroku (which is an Ubtuntu slug).

I appreciate that Nix offers a more nuanced way to manage development environments but I feel like I am not quite ready to fully commit to Flakes and Home Manager yet because I am also relatively new to Nix and NixOS. I am still ‘just getting my feet wet’ so to speak with nixpkgs.

Perhaps I can jump in here and use my own legacy Django project to serve as an example to add context to your inquiry, @mapper.

I’ve explored building a Django development setup using configurtation.nix with these lines explicitly:

  environment.systemPackages = [
  # Python-Django development 
  python3
  python312Packages.pip
  heroku
  postgresql
  python312Packages.psycopg2
  python312Packages.eggUnpackHook
  python312Packages.eggBuildHook
  python312Packages.eggInstallHook
];

Afterwards I initialized my virtual enviornmet with: $ python -m venv venv as I’ve been accustomed to with my prior distro. Then I activated it. Next I attempted to install all the Python packages via requirements.txt as usual but pip is choking when trying to install / build / configure Postgres and adjacent libraries showing this error:

My broken pip wheel
Collecting psycopg2==2.9.10 (from -r requirements.txt (line 61))
  Using cached psycopg2-2.9.10.tar.gz (385 kB)
  Installing build dependencies ... done
  Getting requirements to build wheel ... error
  error: subprocess-exited-with-error
  
  × Getting requirements to build wheel did not run successfully.
  │ exit code: 1
  ╰─> [5 lines of output]
      running egg_info
      writing psycopg2.egg-info/PKG-INFO
      writing dependency_links to psycopg2.egg-info/dependency_links.txt
      writing top-level names to psycopg2.egg-info/top_level.txt
      Error: pg_config --libdir failed:
      [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
error: subprocess-exited-with-error

× Getting requirements to build wheel did not run successfully.
│ exit code: 1
╰─> See above for output.

As you can see in the traceback, there are a few references to Python and egg_info which after a few Google searches lead me to adding those 3 “egg hooks” packages in my configuration.nix. After switching and upgrading these additonal packages, that did not resolve the pip errors.

I am willing to learn how to use Flakes and write Nix expressions, but I am just wondering if it is possible for now to get a Django project up and running on NixOS the old fashioned way using pip? Or is it absolutely mandatory for all NixOS developers to manage their buiild enviornments in Flakes and the Nix language?

Another interesting consideration: Heroku builds the slug based on an imported requirements.txt so if my new local development environment is written in Nix, it won’t be compatible with Heroku. I will need to arrange for some alternate webhost. Is that a fair assesment?

Error: pg_config --libdir failed:

psycopg2 needs PostgreSQL, including its pg_config binary. Add it by including postgresql in your nix-shell. Use nix-shell for other packages such as python3. Do not use python312Packages.psycopg2 if you’re going to install psycopg2 in a separate virtual environment anyway - it gains you nothing. Generally project-specific dependencies should not go into your system configuration, but in a shell.nix in the project directory.

It is absolutely possible to use “legacy” Python workflows without depending on Python modules packaged in Nixpkgs at all. See How to consume Python modules using pip in a virtual environment like I am used to on other Operating Systems?.

If the Python modules that you depend on build C extensions, you’ll need to:

Using the doc you linked to in the NixOS manual enabled me to build my two Django projects. I will yield to your advice and to the advice in the manual suggesting that pip is not a very good package manager and using pip is not very idiomatic for this community. Although this leads me back to my question from my previous post which is still unanswered:

If I began using the appropriate modern development workflow for NixOS by using flakes to build and manage my Python and Django projects, would this make them incompatible with Heroku (or any other web hosts that don’t support Nix)?

If this is the case, what web hosts are known to be reliable and scalable and affordable that are compatible with proper Nix package management?

Yes, Heroku does not natively support Nix (although there appear to be some hacks around it). They do support Poetry, which would work with the combined approach: use poetry to manage your deps (independently of Nix), and poetry2nix (sadly, unmaintained as of recently) to bring that into Nix.

If you want to build an app as a Nix derivation, then the ideal deployment environment for that app would be either NixOS, or a Linux host (i.e. a “proper” VPS or a dedicated server) with Nix installed. Then, you can simply nix-copy-closure / nix copy your built derivation.

But you seem to be looking for SaaS/PaaS hosts instead. I can think of a couple ways to deploy a Nix-packaged application to that kind of a hosting provider:

  • Use dockerTools to build a Docker image and deploy that
  • Use something like nix bundle to build your app into a single statically-linked executable.
    • Though I doubt that most PaaS providers would even take a precompiled executable - they usually operate in Docker images.