Why Docker helped
The project originally ran directly on an Ubuntu server. Moving it to Debian exposed the usual server migration problem: packages, Python dependencies, database clients, and environment setup can drift.
Docker made the runtime more explicit.
Dockerfile shape
The application image started from a slim Python base:
FROM python:3.12-slim
WORKDIR /app
The image needed system packages for Python dependencies such as MySQL client bindings:
RUN apt-get update && apt-get install -y \
build-essential \
default-libmysqlclient-dev \
pkg-config
The important part was not the exact package list. It was capturing all runtime assumptions in one file.
Database and environment
The app still needed correct environment variables and a database connection. Docker does not remove configuration work; it makes the boundary clearer.
The Django container, MariaDB, volume paths, and network settings had to agree.
Migration lesson
Server migration is easier when the application runtime is described as code. Docker made it possible to rebuild the same app shape on Debian without manually repeating every Ubuntu setup step.
The result was not a perfect production platform, but it was a cleaner base for repeatable deployment.