Skip to main content
Software Django Release

A Django release you can explain

The first production release is finished when someone who was not in the room can say what is deployed, how to roll it back, and where the logs are.

LesterTechLabs Engineering Estimated 3 min read

The first production release is finished when someone who was not in the room can say what is deployed, how to roll it back, and where the logs are.

Settings are data

Secrets, the public site address, and the database host do not belong in the repository. They belong in the environment the process actually runs. A release checklist should include the migration command, the static files, and a health check that does not require a login. If the health check needs the database, say that, and do not pretend the process is up while the database is down.

Migrations are applied, not re-run from scratch

Django records the migrations it has applied. A deploy runs the new ones. It does not drop the database, and it does not ask you to type them by hand. If a migration will lock a busy table, know that before the morning you ship. Write the rollback as “deploy the previous image,” and make sure the previous image can boot against the new schema or that the migration is backward compatible.

One person should be able to read the log

A traceback in a file nobody can open is not an operation. Send application logs to the place the on-call person already looks. Include the request id if you have one. The first incident will be a timeout or a bad environment variable, and the log should show which one without a redeploy.

A health check that means ready

The process being up is not the same as the site being able to serve. The check that your proxy calls should touch the dependency you cannot serve without, usually the database, and it should fail when that dependency fails. It should not require a session, and it should not write a row on every probe.

Keep the check cheap. A proxy that calls it every few seconds will take the site down if the check runs a migration or a full table scan. One SELECT 1 is enough to learn that the connection works.

Python · apps/core/health.py

from django.db import connection
from django.http import JsonResponse

def health(request):
    try:
        with connection.cursor() as cursor:
            cursor.execute("SELECT 1")
            cursor.fetchone()
    except Exception:
        return JsonResponse({"status": "down"}, status=503)
    return JsonResponse({"status": "ok"})

The release note

Write four lines where the person who deploys will see them. The image tag. The migrate command. The health URL. The command that puts the previous image back. If a migration is not safe to roll back, say so on that note, and ship it in a window when someone who understands the table is awake.

Read the logs for the first requests after the deploy. A traceback in that minute is part of the release, not a separate incident you discover in the morning.

Settings the process actually reads

The public site address, the database host, and the secret key come from the environment of the running process. A value that is correct on your laptop and wrong in the container is the usual first outage. Write the names of the variables in the release note, not the values. Confirm the process can see them by booting it and hitting the health check, not by printing the environment into the log.

Migrations run forward against the database you mean. They do not drop it, and they are not typed by hand on a server. If this migration adds a column the old image does not know, the old image must still boot, which means the column is nullable or defaulted until the new image is the only one running. Then a later change can tighten it.

Static files are collected as part of the same release as the templates that reference them. A template that points at a hashed file you forgot to collect is a page of unstyled HTML, which your health check will still call healthy. Open the home page after the deploy. The health check is necessary and it is not sufficient.

On the release note

  1. Write the exact migrate and health-check commands on the release note.
  2. Confirm the previous image still starts.
  3. Open the logs once before you call the release done.

On the site

Software

Have a system to build?

We design and ship custom software with a scope you can track, from the first request to handover.