Docker made my model portable, and my results reproducible
There is a specific kind of despair that comes from an experiment that ran perfectly last Tuesday and refuses to run today. Same code. Same data. Different answer.
Almost always, the culprit is the environment.
The invisible dependency
A machine learning project depends on far more than its import statements. It depends on the Python
minor version, the CUDA version, a system library that happened to be installed, and the exact
version of a package that changed its default parameter three releases ago.
None of that is in your repository. All of it changes your results.
Containers as a lab notebook
A Dockerfile is the honest version of your setup instructions — it fails loudly if a step is
missing, which is exactly what a README never does.
FROM python:3.11-slim
WORKDIR /app
# Dependencies first: this layer is cached until requirements.txt changes.
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "train.py"] Copying requirements.txt before the rest of the source is the small trick that saves the most time.
Docker caches layers, so editing train.py no longer reinstalls every dependency.
Things that surprised me
- Pin your versions.
pip install pandastoday and in six months are different programs.pandas==2.2.3is a fact;pandasis a wish. - Slim images are worth it. Swapping the full Python image for
-slimcut my image by hundreds of megabytes, and I never missed what was removed. - Data does not belong inside the image. Mount it as a volume. An image that carries a dataset is an image nobody wants to pull.
.dockerignorematters more than expected. Without it I was copying.git, virtual environments, and checkpoints into every build.
The part that actually changed how I work
Once the container existed, “run my experiment” became one command that behaves identically on my laptop and on a cloud instance. Reproducibility stopped being a thing I hoped for and became a property of the setup.
That is the whole point of MLOps, as far as I can tell: making the boring parts boring.
got thoughts?
Let's talk