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.