docker rundocker-compose.ymlWhile 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 imageYou 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.
Was this section helpful?
build reference, Docker, 2024 (Docker) - Official documentation detailing the build keyword in Docker Compose, including context, Dockerfile specification, build arguments, and combining with the image directive. This resource is essential for understanding how to build custom images directly within your Compose setup.build keyword relies on Dockerfiles for image creation, making this a foundational reference for understanding the underlying build process.build feature enhances.© 2026 ApX Machine LearningEngineered with