docker run
docker-compose.yml
While Docker Compose excels at defining and running multi-container applications using pre-built images specified via the image
directive, it also offers a direct way to build your container images as part of the application setup. This integration simplifies development workflows, especially when your application components require custom environments defined by Dockerfiles. Instead of manually building each image with docker build
and then referencing it in docker-compose.yml
, you can instruct Compose to handle the build process itself.
The primary mechanism for this is the build
keyword within a service definition in your docker-compose.yml
file. It replaces or complements the image
keyword.
build
KeywordAt its simplest, you can provide the build
keyword with a string value representing the path to the directory containing the Dockerfile
. This directory is known as the build context. Docker Compose will look for a file named Dockerfile
within that directory and use it to build the image for the service.
Consider a service for a custom Flask API designed for model inference:
# docker-compose.yml
version: '3.8' # Or a later version
services:
inference_api:
build: ./inference_service # Path to the directory with the Dockerfile
ports:
- "5001:5000" # Map host port 5001 to container port 5000
volumes:
- ./models:/app/models # Mount local models directory
environment:
- MODEL_PATH=/app/models/my_model.pkl
In this example, when you run docker-compose up
, Compose will navigate to the inference_service
directory relative to the docker-compose.yml
file. It will then execute a build process similar to docker build ./inference_service
and use the resulting image to start the inference_api
container.
Sometimes, your Dockerfile
might have a different name, or you might want to specify the build context path more explicitly, perhaps relative to a different location. For these scenarios, the build
keyword accepts an object with context
and dockerfile
keys:
# docker-compose.yml
version: '3.8'
services:
data_processor:
build:
context: ./processing # The build context directory
dockerfile: Dockerfile.processor # Specify a custom Dockerfile name
volumes:
- ./data:/data
command: python process.py /data/input /data/output
Here, Compose uses the ./processing
directory as the build context but looks specifically for a file named Dockerfile.processor
inside that directory to build the image for the data_processor
service.
Dockerfiles often use ARG
instructions to allow customization during the build process (e.g., specifying versions or enabling optional features). Docker Compose allows you to pass values for these arguments using the args
key within the build
object.
Imagine your Dockerfile
for a training environment accepts a Python version:
# Dockerfile for training
ARG PYTHON_VERSION=3.9
FROM python:${PYTHON_VERSION}-slim
# ... rest of the Dockerfile ...
You can specify the PYTHON_VERSION
in your docker-compose.yml
:
# docker-compose.yml
version: '3.8'
services:
training_env:
build:
context: ./training
dockerfile: Dockerfile.train
args:
PYTHON_VERSION: 3.10 # Pass this value to the Dockerfile ARG
# ... other service configurations ...
When Compose builds the training_env
service, it will pass PYTHON_VERSION=3.10
to the Docker build process, overriding the default value specified in the Dockerfile
.
build
and image
You can specify both build
and image
for a service. If you do this, Compose will build the image using the instructions in the build
section and then tag the resulting image with the name (and optionally tag) provided in the image
keyword.
# docker-compose.yml
version: '3.8'
services:
inference_api:
build: ./inference_service
image: my_registry/my_ml_api:1.0 # Tag the built image
ports:
- "5001:5000"
# ...
This is particularly useful if you intend to push the image built by Compose to a container registry later. Running docker-compose build
or docker-compose up --build
will create the image and tag it as my_registry/my_ml_api:1.0
. You can then use docker push my_registry/my_ml_api:1.0
to share it.
Docker Compose attempts to be efficient. It typically only builds an image if one doesn't already exist with the expected characteristics or if the build context (files in the specified directory) appears to have changed. However, changes deep within dependencies might not always be detected automatically.
To explicitly force Compose to rebuild the images for your services, use the --build
flag with the up
command:
docker-compose up --build
Alternatively, you can build images without starting the containers using:
docker-compose build
Integrating image building directly into your docker-compose.yml
file provides a streamlined approach for managing custom container environments. It ensures that the image build process is tightly coupled with the application's service definitions, promoting consistency and simplifying the setup for anyone working on the project. Just define the build context and optional parameters, and let Docker Compose handle the rest.
© 2025 ApX Machine Learning