This approach allows you to run the Django application on NixOS while still having the flexibility to deploy it on Heroku (or other cloud platforms) if needed.
First, install the enviornment on NixOS. To do this, you can add the following to your NixOS configuration (/etc/nixos/configuration.nix
):
{
virtualisation.docker.enable = true;
}
Then, run sudo nixos-rebuild switch
to apply the changes.
Assuming your you already have a Django project with a requirements.txt
(or pyproject.toml
for newer versions), you need to make sure the project is ready for containerization.
The basic structure of a Django project looks like this:
my-django-app/
├── manage.py
├── myapp/
├── requirements.txt
└── other_project_files/
In the root of the Django project (my-django-app/
), create a Dockerfile
. This file tells Docker how to build the container image. Here's a basic Dockerfile
for Django with Gunicorn as the application server and a PostgreSQL database.
# Use an official Python runtime as a parent image
FROM python:3.9-slim
# Set the working directory in the container
WORKDIR /app
# Copy the current directory contents into the container at /app
COPY . /app
# Install any needed dependencies specified in requirements.txt
RUN pip install --no-cache-dir -r requirements.txt
# Expose the port the app runs on
EXPOSE 8000
# Define environment variable for Django to allow all hosts
ENV DJANGO_ALLOWED_HOSTS=*
# Run the Django development server (or use Gunicorn in production)
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "myproject.wsgi:application"]
This Dockerfile
does the following:
- Starts with the official Python 3.9 slim image.
- Sets
/app
as the working directory. - Copies the Django project files into the container.
- Installs dependencies using
pip
from therequirements.txt
. - Exposes port
8000
, which is the default port for Django’s development server (and for Gunicorn). - Sets an environment variable
DJANGO_ALLOWED_HOSTS
to allow any host (for development purposes). - Runs the Django app using Gunicorn (which is more production-ready than Django’s default development server).
Once the Dockerfile
is in place, you can build the Docker image. Open a terminal in the root of the Django project and run:
docker build -t my-django-app .
This will create a Docker image tagged my-django-app
.
After the image is built, you can run the container locally to test it:
docker run -p 8000:8000 my-django-app
This will run the Django app inside the Docker container and map port 8000 from the container to port 8000 on the host machine. You can then access the Django app by going to http://localhost:8000
.
If your Django app uses a database (e.g., PostgreSQL), you can use Docker Compose to define multiple services (like Django and PostgreSQL) in a single configuration. Create a docker-compose.yml
file:
version: '3'
services:
db:
image: postgres:13
environment:
POSTGRES_USER: myuser
POSTGRES_PASSWORD: mypassword
POSTGRES_DB: mydatabase
volumes:
- pgdata:/var/lib/postgresql/data
web:
build: .
command: gunicorn --bind 0.0.0.0:8000 myproject.wsgi:application
volumes:
- .:/app
ports:
- "8000:8000"
depends_on:
- db
volumes:
pgdata:
This docker-compose.yml
defines two services:
db
: The PostgreSQL database.web
: The Django app, built from the local directory (.
).
You can start the services with:
docker-compose up
This will bring up both the database and Django app. The app will be accessible on http://localhost:8000
.
If you still wants to deploy to Heroku, you can use Docker to push your app to Heroku. Here’s how to do it:
-
Install Heroku CLI (if not already installed).
-
Login to Heroku via the command line:
heroku login
-
Create a Heroku app (if not already created):
heroku create my-django-app
-
Push the Docker container to Heroku:
heroku container:login heroku container:push web --app my-django-app heroku container:release web --app my-django-app
This will push the Docker container to Heroku and release it as a web app.
Before deploying to production (either locally or on Heroku), you should make sure the Django app is ready for production. This includes:
- Setting up the
ALLOWED_HOSTS
in thesettings.py
file (e.g.,ALLOWED_HOSTS = ['*']
for testing or specific domains for production). - Configuring a production database (like PostgreSQL on Heroku or another external database).
- Running
python manage.py collectstatic
to gather static files. - Setting up environment variables for secrets like the Django
SECRET_KEY
, database credentials, etc. - Using Gunicorn or another WSGI server to run the app instead of the default Django development server.
This approach allows you to easily containerize your Django app and run it locally on NixOS while maintaining flexibility for deployment on platforms like Heroku or others. The Docker container ensures the environment is consistent across all stages of development and production.
Would you like to explore any of the steps in more detail or have specific questions about this process?