Deploy a Django App
Django (opens in a new tab) is a robust, full-featured web framework for Python that simplifies building scalable, performant web applications and sites. With a large community and an impressive list of features and integrations, Django takes a batteries-included approach to bundling functionality while allowing users to swap out or add additional components as they see fit.
This guide explains how to deploy a Django application on Koyeb using:
- Git-driven deployment to automatically build and deploy a new version of your application each time a change is detected on your branch.
- Pre-built containers you can deploy from any public or private registry.
To successfully follow this documentation, you will need to have a Koyeb account (opens in a new tab). You can optionally install the Koyeb CLI if you prefer to follow this guide without leaving the terminal.
You can deploy and preview the Django application from this guide using the Deploy to Koyeb button below.
You can consult the repository on GitHub (opens in a new tab) to find out more about the example application that this guide uses.
Create the Django app
Get started by creating a minimalistic Django application that we will deploy on Koyeb. You will need Python (opens in a new tab) installed on your machine.
Create a virtual environment
In your terminal, run the following commands to create the directory that will hold the application code:
mkdir example-django
cd example-django
In the folder you created, create a new virtual environment folder. Virtual environments provide isolation from the system software, allowing each project to manage its own installation directories, dependencies, etc.
On some platforms, the Python interpreter is installed as python3
instead of python
. For these
platforms, substitute python3
for python
in the command below.
Create a new virtual environment for the project by typing:
python -m venv venv
Activate and load your virtual environment by typing:
source venv/bin/activate
Your prompt should now include the venv
environment name, indicating that the virtual environment is now active.
Install dependencies
Next, install:
- Django (opens in a new tab): the Python web framework
- Gunicorn (opens in a new tab): the WSGI HTTP server we will use to serve the application
- WhiteNoise (opens in a new tab): to help serve static content without a full-fledged web server
pip install Django gunicorn whitenoise
Koyeb detects Python applications when one of the Python matching criteria is met. Create a requirements.txt
file to store the dependencies and versions of each package required to run the application. This file is necessary in order for Koyeb to identify this as a Python project:
pip freeze > requirements.txt
Create and configure a Django project
Next, use the django-admin startproject
command to start a new project. Because you already created a project directory to store the virtual environment, you can tell Django to install the new project within the context of the current directory:
django-admin startproject example_django ./
This will generate a project management script called manage.py
as well as a directory called example_django
containing the main project code.
Your directory structure should now look like this. You can see similar output using tree -L 2
or du -d 2 -a
:
example-django
├── example_django
│ ├── asgi.py
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── manage.py
├── requirements.txt
└── venv
├── . . .
Open the example_django/settings.py
file in your editor to configure the project.
Towards the top of the file, add a line to import the os
module:
import os
from pathlib import Path
Afterwards, find the ALLOWED_HOSTS
setting. Use the os
module to modify this entry so that Django looks for permitted hosts in an environment variable called DJANGO_ALLOWED_HOSTS
:
#ALLOWED_HOSTS = []
ALLOWED_HOSTS = os.getenv("DJANGO_ALLOWED_HOSTS", "localhost,127.0.0.1,[::1]").split(",")
This configuration uses the environment variable if it is set and falls back to Django's default setting otherwise.
Next, find the MIDDLEWARE
dictionary. Directly below Django's SecurityMiddleware
entry, add the WhiteNoise middleware:
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
Finally, set up the static file configuration. Locate the STATIC_URL
setting and add the following lines:
STATIC_URL = 'static/'
STATIC_ROOT = BASE_DIR / 'staticfiles'
STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage"
Setting STATIC_ROOT
tells Django where to gather static assets. The STATICFILES_STORAGE
value enables compression and caching.
Run the Django app locally
Now, you can launch the application locally to make sure everything is running as expected.
First, launch the application using Django's native development server. Run the following command from the project root directory where the manage.py
file is located:
python manage.py runserver
You will see a note about unapplied migrations that we can safely ignore for this demo. Access the demo server by visiting http://127.0.0.1:8000
in your browser.
If you navigate to http://127.0.0.1:8000/admin
, you will see the log in page for Django's default administration interface. Django's development server automatically serves the static assets associated with the site.
Press CTRL-C to stop the development server after verifying.
Next, check to make sure that gunicorn
can serve the project correctly. From the same directory, type:
gunicorn example_django.wsgi
Again, verify that the application is being served at http://127.0.0.1:8000
. Check the administration interface at http://127.0.0.1:8000/admin
again and refresh the page. Since we are no longer serving the site using Django's development server, WhiteNoise is responsible for serving the static files correctly.
Press CTRL-C to stop the development server when you are finished.
This example application should run on any modern version of Python. If your application requires a specific
Python version, create a runtime.txt
file in your repository with the version number. Consult the build
with Python page to learn more.
Push the project to GitHub
In the project root directory, initialize a new git repository by running the following command:
git init
We will use this repository to version the application code and push the changes to a GitHub repository. If you don't have an existing GitHub repository to push the code to, create one now.
Pull down GitHub's default .gitignore
file for Python to help avoid accidentally committing unnecessary and unwanted files:
curl -L https://raw.githubusercontent.com/github/gitignore/master/Python.gitignore -o .gitignore
Run the following commands to commit and push changes to the repository. Remember to replace the values of <YOUR_GITHUB_USERNAME>
and <YOUR_REPOSITORY_NAME>
with your own information:
git add .
git commit -m "Initial commit"
git remote add origin git@github.com:<YOUR_GITHUB_USERNAME>/<YOUR_REPOSITORY_NAME>.git
git push -u origin main
Deploy to Koyeb using git-driven deployment
To deploy the Django app on Koyeb, using the control panel (opens in a new tab) follow the steps below:
-
Click Create Web Service on the Overview tab of the Koyeb control panel.
-
Select GitHub as the deployment option.
-
Choose the GitHub repository and branch containing your application code. Alternatively, you can enter our public Django example repository (opens in a new tab) into the Public GitHub repository at the bottom of the page:
https://github.com/koyeb/example-django
. -
In the Builder section, keep Buildpack selected. Click the Override toggle associated with the Run command. In the command field, enter the
gunicorn
command from earlier:gunicorn example_django.wsgi
-
In the Environment variables section and click Add variable. Add a variable named
DJANGO_ALLOWED_HOSTS
set to the string{{ KOYEB_PUBLIC_DOMAIN }}
. -
Click the Deploy button.
A Koyeb App and Service will be created. Your application will be built and deployed to Koyeb. Once the build has finished, you will be able to access your application running on Koyeb by clicking the URL ending with .koyeb.app
.
Deploy to Koyeb using a pre-built container
As an alternative to using git-driven deployment, you can deploy a pre-built container from any public or private registry. This can be useful if your application needs specific system dependencies or you need more control over how the build is performed.
To dockerize the Django application, create a Dockerfile
in your project root directory and copy the content below:
FROM python:3-alpine AS builder
WORKDIR /app
RUN python3 -m venv venv
ENV VIRTUAL_ENV=/app/venv
ENV PATH="$VIRTUAL_ENV/bin:$PATH"
COPY requirements.txt .
RUN pip install -r requirements.txt
# Stage 2
FROM python:3-alpine AS runner
WORKDIR /app
COPY --from=builder /app/venv venv
COPY example_django example_django
ENV VIRTUAL_ENV=/app/venv
ENV PATH="$VIRTUAL_ENV/bin:$PATH"
ENV PORT=8000
EXPOSE ${PORT}
CMD gunicorn --bind :${PORT} --workers 2 example_django.wsgi
The Dockerfile above provides the minimum requirements to run the Django application. You can easily extend it depending on your needs.
To build and push the Docker image to a registry and deploy it on Koyeb, refer to the Deploy an app from a Docker image.
During configuration, be sure to add an environment variable called DJANGO_ALLOWED_HOSTS
set to {{ KOYEB_PUBLIC_DOMAIN }}
. This will tell Django to allow connections to your Koyeb subdomain URL.