Looking for a nixops python/django example


I am trying to deploy a Django application using NixOps and I am not able to. Here is what I have tried:

I build the python package like this (I have a setup.py):

with import <nixpkgs> { };

python38Packages.callPackage buildPythonApplication rec {
  name = "django-example";
  src = ./backend;
  doCheck = false;
  propagatedBuildInputs = [

Then in a droplet.nix I want to add lines similar to this (hoping the nginx reverse proxy config will be easy)

# django-example = import ./django-example/default.nix;
# systemd.services.django-example = {
#   enable = true;
#   script = ''
#     ${pkgs.python38Packages.gunicorn}/bin/gunicorn -b -p 8000 --chdir ${django-example} django-example.wsgi:application
#   '';
# };

This is throwing an error about about tmp files. I assume because gunicorn tries to create a tmp directory in django-example but it can’t.

The idea I was trying was:

  1. build python package. I found setup.py and poetry for this and got setup.py working first.
  2. Get nix to build the python package. This is what I pasted above.
  3. deploy using NixOps. It seems to me systemd might be a good fit here.

Is there an example deployment that uses gunicorn that I can use?

I started the project django-nixos some time ago. I’m using this on a regular basis to deploy django projects.
It has examples for nixos and nixops including reverse nginx with auto letsencrypt and so on.

It includes:

  • A PostgreSQL DB with access configured for django
  • A systemd service which serves the project via gunicorn
  • A defined way of passing secrets to Django without leaking them into /nix/store
  • Your static files as a separated build artifact (by default served via whitenoise)
  • Ability to configure some common options like (allowed-hosts, port, processes, threads) through your nix config.
  • Having your manage.py globally callable via manage-projectname (only via root/sudo)

Let me know if you have any more questions! Also feel free to contribute.

It appears to me that the specific problem you have with gunicorn is to use –chdir to be able to access your python project. Better use –pythonpath instead.


If found an example here on reddit:

I adapted it to my needs and made sure that the permissions to the sqlite3 file are restricted by rwx------. You can find the example here: