# Deploy a Django App on Render This guide walks through deploying a [Django](https://www.djangoproject.com/) Python app on Render. You can [use your existing Django project](#updating-an-existing-django-project) or [create one from scratch](#creating-a-new-django-project). > If you're new to Django, we recommend first reading the official guide to [Writing your first Django project](https://docs.djangoproject.com/en/5.2/intro/tutorial01/). ## Updating an existing Django project To prepare an existing Django project for production on Render, we'll make a couple adjustments to its configuration: - We'll update your project to use a [Render PostgreSQL database](postgresql) instead of a SQLite database. - We'll configure the [WhiteNoise](https://whitenoise.evans.io/en/stable/django.html) package to serve your project's static files. - We'll define a build script to run with each deploy. ### Use a Render PostgreSQL database As part of deploying your project, we'll also deploy a Render PostgreSQL database to serve as its backing datastore. To enable this, let's add a couple of packages to your project: | Package | Description | | -------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [psycopg2](https://www.psycopg.org/) | This is the most popular Python adapter for communicating with a PostgreSQL database. | | [DJ-Database-URL](https://github.com/jacobian/dj-database-url) | This enables you to specify your database details via the `DATABASE_URL` environment variable (you'll obtain your database's URL from the [Render Dashboard](https://dashboard.render.com)). | 1. Run the following commands to install these packages: ```bash $ pip install psycopg2-binary $ pip install dj-database-url # Add these dependencies to your requirements.txt file: $ pip freeze > requirements.txt ``` 2. Open `settings.py` in your project's main directory (e.g., `mysite/settings.py`). Make the following modifications: ```python # Import dj-database-url at the beginning of the file. import dj_database_url # highlight-line ``` ```python{3-7} # Replace the SQLite DATABASES configuration with PostgreSQL: DATABASES = { 'default': dj_database_url.config( # Replace this value with your local database's connection string. default='postgresql://postgres:postgres@localhost:5432/mysite', conn_max_age=600 ) } ``` ### Set up static file serving Django provides a [dedicated module](https://docs.djangoproject.com/en/5.0/howto/static-files/deployment/) for collecting your project's static files (HTML, CSS, JavaScript, images, and so on) into a single place for serving in production. This module supports moving files from one place to another, relying on the end web server (such as Render's default web server, or a tool like NGINX) to serve them to end users. In this step, we'll set up [WhiteNoise](https://whitenoise.evans.io) to serve these static assets from Render's web server. > The following instructions summarize the setup described in the [WhiteNoise documentation](http://whitenoise.evans.io/en/stable/django.html). 1. Add WhiteNoise as a dependency (adding [Brotli](https://en.wikipedia.org/wiki/Brotli) support is optional, but recommended): ```bash $ pip install 'whitenoise[brotli]' $ pip freeze > requirements.txt ``` 2. Open `settings.py` in your project's main directory (e.g., `mysite/settings.py`). Add the following to the `MIDDLEWARE` list, _immediately after_ `SecurityMiddleware`: ```python MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'whitenoise.middleware.WhiteNoiseMiddleware', #highlight-line ... ] ``` 3. Still in `settings.py`, find the section where static files are configured. Make the following modifications: ```python{6,9,11,15} # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/5.0/howto/static-files/ # This setting informs Django of the URI path from which your static files will be served to users # Here, they well be accessible at your-domain.onrender.com/static/... or yourcustomdomain.com/static/... STATIC_URL = '/static/' # This production code might break development mode, so we check whether we're in DEBUG mode if not DEBUG: # Tell Django to copy static assets into a path called `staticfiles` (this is specific to Render) STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') # Enable the WhiteNoise storage backend, which compresses static files to reduce disk use # and renames the files with unique names for each version to support long-term caching STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage' ``` All set! We're ready to serve static content from our Django project on Render. ### Create a build script Whenever you deploy a new version of your project, Render runs a *build command* to prepare it for production. Let's create a script for Render to run as this build command. 1. Create a new file called `build.sh` in your project's root directory and paste in the following: ```bash #!/usr/bin/env bash # Exit on error set -o errexit # Modify this line as needed for your package manager (pip, poetry, etc.) pip install -r requirements.txt # Convert static asset files python manage.py collectstatic --no-input # Apply any outstanding database migrations python manage.py migrate ``` Make sure the script is executable before adding it to version control: ```shell chmod a+x build.sh ``` We'll configure Render to run this build script whenever a new deploy is initiated. 2. We'll run your project with [Uvicorn](https://www.uvicorn.org/) and [Gunicorn](https://gunicorn.org/). Add these dependencies to your project: ```shell pip install gunicorn uvicorn pip freeze > requirements.txt ``` 3. Try running your project locally! > Replace `mysite` in the command below with your project's name. ```shell python -m gunicorn mysite.asgi:application -k uvicorn.workers.UvicornWorker ``` 4. Visit [http://localhost:8000](http://localhost:8000) in your browser to verify that your project is up and running. Commit all changes and push them to your repository. Your project is ready to deploy to Render! ## Deploying to Render There are two ways to deploy your Django project on Render, either by [declaring your services within your repository](infrastructure-as-code) using a `render.yaml` file or by manually setting up your services using the dashboard. In this tutorial, we will walk through both options. ### Use `render.yaml` for deploys 1. Create a file named `render.yaml` in the root of your project. This file will define your Django *web service*, along with the [*database*](postgresql) it connects to. Don't forget to commit and push it to your repository. > The `gunicorn` command in the highlighted line below assumes your Django project is named `mysite`. Update it for your project as needed. ```yaml databases: - name: mysitedb plan: free databaseName: mysite user: mysite services: - type: web plan: free name: mysite runtime: python buildCommand: './build.sh' startCommand: 'python -m gunicorn mysite.asgi:application -k uvicorn.workers.UvicornWorker' # highlight-line envVars: - key: DATABASE_URL fromDatabase: name: mysitedb property: connectionString - key: SECRET_KEY generateValue: true - key: WEB_CONCURRENCY value: 4 ``` 2. In the Render Dashboard, go to the [Blueprints page](https://dashboard.render.com/blueprints) and click *New Blueprint Instance*. 3. Select the repository that contains your blueprint and click *Connect*. 4. Give your blueprint project a name and click *Apply*. That's it! Your project will be live at its `.onrender.com` URL as soon as the build finishes. ### Manual deployment 1. Create a new [PostgreSQL database](postgresql-creating-connecting) on Render. Copy its *internal database URL* for now—you'll need it later. 2. Create a new *web service* on Render, pointing it to your project's GitHub/GitLab/Bitbucket repository (give Render permission to access it if you haven't already). 3. Select `Python 3` for the *Language* and set the following properties (replace `mysite` with your project's name): | Property | Value | | ----------------- | ----------------------------------------------------------------------------- | | *Build Command* | `./build.sh` | | *Start Command* | `python -m gunicorn mysite.asgi:application -k uvicorn.workers.UvicornWorker` | 4. Add the following environment variables under *Advanced*: | Key | Value | | ----------------- | ---------------------------------------------------------------- | | `DATABASE_URL` | The *internal database URL* for the database you created above | | `SECRET_KEY` | Click *Generate* to get a secure random value | | `WEB_CONCURRENCY` | `4` | That's it! Save your web service to deploy your Django application on Render. It will be live on your `.onrender.com` URL as soon as the build finishes. ### Create a Django admin account Once your application is live, create a new [Django admin account](https://docs.djangoproject.com/en/3.0/intro/tutorial02/#creating-an-admin-user) by running the following command in the Render Shell: ```shell python manage.py createsuperuser ``` See [Setting your Python Version](python-version) if you need to customize the version of Python used for your app. ## Creating a new Django project This section walks through setting up a Django project and adding an application with a simple view. The finished code for this example is available on [GitHub](https://github.com/render-examples/django), and you can view the project running [here](https://django.onrender.com). > This tutorial starts with a bare-bones installation and explains all required code modifications. Feel free to adapt it with custom configuration as needed. ### Installation & setup First, we'll set up our local development environment and create a basic project structure. We'll call our project `mysite`. You can use a different name, but make sure to modify all commands that use `mysite` below to match the name you choose. #### 1. Create your directory and virtual environment Run the following commands in your terminal (see comments for descriptions): ```shell{outputLines:1,4,5,7-8} # Create a new project directory and cd into it mkdir mysite cd mysite # Create a virtual environment using Python's venv package python -m venv venv # Activate the virtual environment to start installing other packages source venv/bin/activate ``` #### 2. Install Django and create your project Run the following from your project's root directory to install Django: ```shell{outputLines:1} # This installs Django 5.0.1 (feel free to modify the version as needed) pip install django==5.0.1 pip freeze > requirements.txt ``` Then run the following to initialize your `mysite` Django project: ```shell django-admin startproject mysite . ``` You'll end up with the following directory structure: ``` . ├── manage.py ├── mysite │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py └── venv (you can ignore everything in here for now) ├── ``` You now have a fully functional scaffold for your new Django project! To verify, you can start the development server: ```shell python manage.py runserver ``` Then visit [http://localhost:8000](http://localhost:8000) in your browser: