docker run
docker-compose.yml
While pre-built Docker images from registries like Docker Hub provide a convenient starting point, you'll often need to create custom environments tailored specifically to your machine learning project's requirements. You might need a precise version of Python, specific ML libraries (like TensorFlow, PyTorch, or Scikit-learn), system dependencies, or your own project code included. This is where Dockerfiles come into play.
A Dockerfile is a text document that contains a series of instructions Docker uses to assemble a custom container image, step by step. Think of it as a recipe or a blueprint for creating your environment. By writing a Dockerfile, you define everything needed for your application to run: the operating system base, system tools, language runtimes, code dependencies, your application code, and how the application should be started.
This automation is fundamental for reproducibility in machine learning. If you share your Dockerfile along with your code, anyone else can build the exact same image, ensuring the environment is consistent across development, testing, and production systems. This eliminates the common "it works on my machine" problem often encountered due to subtle differences in library versions or system configurations.
A Dockerfile consists of a sequence of instructions, typically written in uppercase, followed by arguments. Docker reads these instructions from top to bottom, executing each one to form layers of the final image. Here are some of the most common instructions you'll encounter:
FROM
: Every Dockerfile must start with a FROM
instruction. It specifies the base image upon which you are building. This could be a minimal operating system (like ubuntu:22.04
), a language-specific image (like python:3.9-slim
), or even a specialized image containing ML frameworks or CUDA drivers (like nvidia/cuda:11.8.0-base-ubuntu22.04
or tensorflow/tensorflow:latest-gpu
). Choosing the right base image is an important consideration we'll cover later.
FROM python:3.9-slim
RUN
: This instruction executes commands in a new layer on top of the current image. It's commonly used for installing system packages (using apt-get
or yum
) or Python libraries (using pip
or conda
). Multiple RUN
instructions create multiple layers, but you can chain commands using &&
for better layer management.
RUN apt-get update && apt-get install -y --no-install-recommends git \
&& rm -rf /var/lib/apt/lists/*
RUN pip install --no-cache-dir scikit-learn==1.2.0 pandas==1.5.2
COPY
: This instruction copies files or directories from your local machine (the build context) into the filesystem of the container image. You'll use this to add your Python scripts, requirement files (requirements.txt
), configuration files, or even pre-trained model files into the image.
COPY ./requirements.txt /app/requirements.txt
COPY ./src /app/src
WORKDIR
: Sets the working directory for any subsequent RUN
, CMD
, ENTRYPOINT
, COPY
, and ADD
instructions. If the directory doesn't exist, it will be created. This helps organize your container's filesystem.
WORKDIR /app
CMD
: Specifies the default command to execute when a container is started from the image. There can only be one CMD
instruction in a Dockerfile. If you provide a command when running the container (docker run my-image <command>
), it will override the default CMD
. It's often used to start the main process of the application, like running a Python script.
CMD ["python", "src/train.py"]
ENTRYPOINT
: Also configures a container that will run as an executable. It's similar to CMD
, but commands passed via docker run
are appended as arguments to the ENTRYPOINT
executable. This is useful for creating images that act like specific tools.
EXPOSE
: Informs Docker that the container listens on the specified network ports at runtime. It doesn't actually publish the port; it functions as documentation between the person who builds the image and the person who runs the container.
EXPOSE 8000
Comments in a Dockerfile start with #
.
Here’s a minimal Dockerfile that sets up an environment with Python 3.9 and installs Scikit-learn and Pandas:
# Use an official Python runtime as a parent image
FROM python:3.9-slim
# Set the working directory in the container
WORKDIR /app
# Copy the requirements file into the container at /app
COPY requirements.txt .
# Install any needed packages specified in requirements.txt
# Use --no-cache-dir to reduce image size
RUN pip install --no-cache-dir -r requirements.txt
# Copy the rest of the application code
COPY . .
# Specify the command to run on container start
CMD ["python", "your_script.py"]
To build an image from this Dockerfile (assuming it's saved as Dockerfile
in the current directory), you would typically run a command like:
docker build -t my-ml-app .
The -t my-ml-app
tag gives your image a recognizable name, and the .
indicates that the build context (the set of files available to the COPY
instruction) is the current directory. Docker executes the instructions line by line, caching results where possible, to create your final image my-ml-app
.
Understanding Dockerfiles is essential for harnessing Docker's power in ML. They allow you to precisely define, version, and share the environments needed to run your training scripts or serve your models, ensuring consistency and simplifying collaboration and deployment. In the next chapter, we will explore how to write more sophisticated Dockerfiles specifically for building robust ML environments.
© 2025 ApX Machine Learning