Django deployments require coordinating several moving parts: the WSGI server, Celery workers, a message broker, static file collection, and database migrations. Without containers, this means Supervisor configs, virtualenvs that may or may not match, and a deployment script that runs collectstatic and migrate - hopefully in the right order.
With Docker, each component runs in its own container from the same image. Migrations run as an init container or entrypoint step. Static files are collected at build time. The entire stack spins up with docker compose up.