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-djangoIn 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 venvActivate and load your virtual environment by typing:
source venv/bin/activateYour 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 whitenoiseKoyeb 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.txtCreate 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 PathAfterwards, 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 runserverYou 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.wsgiAgain, 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 initWe 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 .gitignoreRun 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 mainDeploy 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:
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
gunicorncommand from earlier:gunicorn example_django.wsgi -
In the Environment variables and files section and click Add variable. Add a variable named
DJANGO_ALLOWED_HOSTSset 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.wsgiThe 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.