Learn through the super-clean Baeldung Pro experience:
>> Membership and Baeldung Pro.
No ads, dark-mode and 6 months free of IntelliJ Idea Ultimate to start with.
Last updated: November 12, 2024
Docker Compose plays an important part in running multi-container Docker applications. One feature that Docker Compose often implements when building Docker images is context.
In this tutorial, we’ll discuss the meaning of context, its importance, and how it works.
In Docker, context represents the directory where Docker searches for all the files needed to build an image for a service. Such files include the Dockerfile, application code, configuration files, and dependencies.
To define the context, we need to use the context field in the docker-compose.yml file to specify the context path. Docker considers the context path as its working directory for finding the necessary files. This path can be a relative path, an absolute path, or perhaps a URL to a remote Git repository:
version: "3"
services:
app:
build:
context: .
ports:
- "8000:8000"
volumes:
- ./app:/app
command: >
sh -c "python manage.py runserver 0.0.0.0:8000"
Above, context: . instructs Docker to use the current directory, the location of the docker-compose.yml file, as the build context for the app service. Docker looks for the Dockerfile and other files in this directory to build the service’s image.
Context defines what the Docker daemon receives during the build process. To clarify, Docker packages the entire build context and sends it to the daemon when it’s building an image:
my_django_project
├── app
│ ├── Dockerfile
│ ├── manage.py
│ └── myapp
├── docker-compose.yml
└── .git
In this example, if context: . is defined in docker-compose.yml, then Docker packages everything in the my_django_project directory. It packages unnecessary files like the .git directory. However, if we only need the files in the app/ directory, we can modify the context path in the context field:
version: "3"
services:
app:
build:
context: ./app
ports:
- "8000:8000"
volumes:
- ./app:/app
command: >
sh -c "python manage.py runserver 0.0.0.0:8000"
In this modification, Docker excludes the unnecessary files and only includes the app directory, which makes the build process faster.
Meanwhile, Dockerfile helps to outline the steps for building an image — for instance, how to install dependencies, set up the runtime environment, and copy application files. The Docker daemon uses context as the directory to search for the Dockerfile when building an image.
If the Dockerfile exists in the build context, Docker automatically finds the file and uses it. However, if the Dockerfile doesn’t exist in the build context, we need to specify its location using the dockerfile field:
services:
app:
build:
context: .
dockerfile: ./app/Dockerfile
ports:
- "8000:8000"
...
Above, Docker uses the current directory as the context but looks for the Dockerfile in the app/ directory. So, the dockerfile field enables us to specify the location of the Dockerfile outside of the main context path.
There are a few practices we can implement to manage build context.
First, we can maintain a small context by setting the context to the smallest possible directory. This improves the speed of the build process and reduces the risk of sending unnecessary files to the Docker daemon.
Next, we can use a .dockerignore file to ignore files that don’t need to be included in the Docker image, for instance, .git, *.log files, or unnecessary large files:
# Version control directory
.git
# Logs files
*.log
# Environment files
.env
.env.local
# Python cache files and compiled bytecode
__pycache__/
*.pyc
# Docker Compose file
docker-compose.yml
Above, the .dockerignore file excludes the .git directory, log files, environment files, Python cache files, and the docker-compose.yml file from the context.
Further, we can monitor the build output. When we run docker-compose build, we need to review the output to note the files being sent to the Docker daemon.
In this article, we dove into how context is fundamental for determining which files are included in the build process for services.
Context management enables us to create Docker images that are efficient and manageable. For instance, we can use tools such as .dockerignore or keep the context small. Thus, we can streamline the build process, even for large projects.