How to Django, Certbot — HTTPS Subdomains

This article will go through how I got subdomains to work on Django 3 with Certbot for https. It was a little finicky to get working, since I couldn’t find much info on some specific errors I was running into. Maybe I’m just not a high level search engine ninja, but I figured it out myself. My server was using nginx, but I think it shouldn’t matter if you use apache or something else. There are 3 components to get subdomains to work on Django with https: modifying domain records, using subdomains package for Django, and adding the subdomain to your certificate with certbot .


Hostname: subdomain
IP Address: your_server_ip
Hostname: *.subdomain
Aliases to:

pip install subdomains

pip install subdomains As of writing this, subdomains is working with Django 3.

Setup: subdomains require you to configure the app’s settings, the urlpatterns, and database object values correctly.

# subdomains settings: project/project/
# subdomains line needs to go before CommonMiddleware
# values are app's path
ROOT_URLCONF = "project.urls"
None: "project.urls",
"subdomain": "subdomain_app.urls"

Next, we need to configure the route in your of the project. Take note that there is no slash for the subdomain path.

# urlpatterns: project/project/
from django.urls import path, include
urlpatterns = [
path(r"subdomain", include("subdomain_app.urls")),

Lastly, from the setup in subdomains docs, we need to set the Site object in our database.

> python makemigrations
> python migrate
> python shell
from django.contrib.sites.models import Site
one = Site.objects.all()[0]
one.domain = '' = 'example'

Subdomains Development and Production

prj_env = "dev" # Put your env var with your favorite method
if prj_env == "dev":
DEBUG = True
ALLOWED_HOSTS = ["localhost", "subdomain.localhost"]
DEBUG = False
ALLOWED_HOSTS = ["", "", "", ""]

This should be all we need for Django to point a subdomain request to the correct view. At this point, development on localhost should be working. Follow the next steps to get it working on production.


# on prod server
> certbot -d domain1,domain2,new_subdomain --expand
# restart nginx, i'm using ubuntu here
> sudo service nginx restart

Subdomains should be working now. I’d like to hear in the comments if there is any better way to handle subdomains in Django.

Software Engineer living in Tokyo | Linux | Cats | | |