Skip to content

Commit 94cabc9

Browse files
committed
build: add manuals section about named contexts
Signed-off-by: David Karlsson <[email protected]>
1 parent a8e5875 commit 94cabc9

File tree

1 file changed

+192
-0
lines changed

1 file changed

+192
-0
lines changed

content/manuals/build/concepts/context.md

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,3 +567,195 @@ README-secret.md
567567

568568
All of the README files are included. The middle line has no effect because
569569
`!README*.md` matches `README-secret.md` and comes last.
570+
571+
## Named contexts
572+
573+
In addition to the default build context (the positional argument to the
574+
`docker build` command), you can also pass additional named contexts to builds.
575+
576+
Named contexts are specified using the `--build-context` flag, followed by a
577+
name-value pair. This lets you include files and directories from multiple
578+
sources during the build, while keeping them logically separated.
579+
580+
```console
581+
$ docker build --build-context src=./src --build-context docs=./docs .
582+
```
583+
584+
In this example:
585+
586+
- The context named `src` points to the `./src` directory on your local machine.
587+
- The context named `docs` points to the `./docs` directory on your local machine.
588+
- The `.` at the end specifies the default build context.
589+
590+
### Using named contexts in a Dockerfile
591+
592+
Dockerfile instructions can reference named contexts as if they are stages in a
593+
multi-stage build.
594+
595+
For example, the following Dockerfile:
596+
597+
1. Uses a `COPY` instruction to copy files from a named context into the
598+
current build stage.
599+
2. Bind mounts the files in a named context to process the files as part of the
600+
build.
601+
602+
```dockerfile
603+
# syntax=docker/dockerfile:1
604+
FROM buildbase
605+
WORKDIR /app
606+
607+
# Copy all files from the "src" context into /app/src in the build container
608+
COPY --from=src . /app/src
609+
RUN make bin
610+
611+
# Mount the files from the "docs" context to build the documentation
612+
RUN --mount=from=docs,target=/app/docs \
613+
make manpages
614+
```
615+
616+
### Use cases for named contexts
617+
618+
Using named contexts allows for greater flexibility and efficiency when
619+
building Docker images. Here are some scenarios where using named contexts can
620+
be useful:
621+
622+
#### Example: combine local and remote sources
623+
624+
You can define separate named contexts for different types of sources. For
625+
example, consider a project where the application source code is local, but the
626+
deployment scripts are stored in a Git repository:
627+
628+
```console
629+
$ docker build --build-context scripts=https://github.com/user/deployment-scripts.git .
630+
```
631+
632+
In the Dockerfile, you can use these contexts independently:
633+
634+
```dockerfile
635+
# syntax=docker/dockerfile:1
636+
FROM alpine:latest
637+
638+
# Copy application code from the main context
639+
COPY . /opt/app
640+
641+
# Run deployment scripts using the remote "scripts" context
642+
RUN --mount=from=scripts,target=/scripts /scripts/main.sh
643+
```
644+
645+
#### Example: dynamic builds with custom dependencies
646+
647+
In some scenarios, you might need to dynamically inject configuration files or
648+
dependencies into the build from external sources. Named contexts make this
649+
straightforward by allowing you to mount different configurations without
650+
modifying the default build context.
651+
652+
```console
653+
$ docker build --build-context config=./configs/prod .
654+
```
655+
656+
Example Dockerfile:
657+
658+
```dockerfile
659+
# syntax=docker/dockerfile:1
660+
FROM nginx:alpine
661+
662+
# Use the "config" context for environment-specific configurations
663+
COPY --from=config nginx.conf /etc/nginx/nginx.conf
664+
```
665+
666+
#### Example: pin or override images
667+
668+
You can refer to named contexts in a Dockerfile the same way you can refer to
669+
an image. That means you can change an image reference in your Dockerfile by
670+
overriding it with a named context. For example, given the following
671+
Dockerfile:
672+
673+
```dockerfile
674+
FROM alpine:{{% param example_alpine_version %}}
675+
```
676+
677+
If you want to force image reference to resolve to a different version, without
678+
changing the Dockerfile, you can pass a context with the same name to the
679+
build. For example:
680+
681+
```console
682+
docker buildx build --build-context alpine:{{% param example_alpine_version %}}=docker-image://alpine:edge .
683+
```
684+
685+
The `docker-image://` prefix marks the context as an image reference. The
686+
reference can be a local image or an image in your registry.
687+
688+
### Named contexts with Bake
689+
690+
[Bake](/manuals/build/bake/_index.md) is a tool built into `docker build` that
691+
lets you manage your build configuration with a configuration file. Bake fully
692+
supports named contexts.
693+
694+
To define named contexts in a Bake file:
695+
696+
```hcl {title=docker-bake.hcl}
697+
target "app" {
698+
contexts = {
699+
src = "./src"
700+
docs = "./docs"
701+
}
702+
}
703+
```
704+
705+
You can immediately see that this is more readable than the CLI version:
706+
707+
```console
708+
$ docker build --build-context src=./src --build-context docs=./docs .
709+
```
710+
711+
#### Linking targets with named contexts
712+
713+
In addition to making complex builds more manageable, Bake also provides
714+
additional features on top of what you can do with `docker build` on the CLI.
715+
You can use named contexts to create build pipelines, where one target depends
716+
on and builds on top of another. For example, consider a Docker build setup
717+
where you have two Dockerfiles:
718+
719+
- `base.Dockerfile`: for building a base image
720+
- `app.Dockerfile`: for building an application image
721+
722+
The `app.Dockerfile` uses the image produced by `base.Dockerfile` as it's base
723+
image:
724+
725+
```dockerfile {title=app.Dockerfile}
726+
FROM mybaseimage
727+
```
728+
729+
Normally, you would have to build the base image first, and then either load it
730+
to Docker Engine's local image store or push it to a registry. With Bake, you
731+
can reference other targets directly, creating a dependency between the `app`
732+
target and the `base` target.
733+
734+
```hcl {title=docker-bake.hcl}
735+
target "base" {
736+
dockerfile = "base.Dockerfile"
737+
}
738+
739+
target "app" {
740+
dockerfile = "app.Dockerfile"
741+
contexts = {
742+
# the target: prefix indicates that 'base' is a Bake target
743+
mybaseimage = "target:base"
744+
}
745+
}
746+
```
747+
748+
With this configuration, references to `mybaseimage` in `app.Dockerfile` use
749+
the results from building the `base` target. Building the `app` target will
750+
also trigger a rebuild of `mybaseimage`, if necessary:
751+
752+
```console
753+
$ docker buildx bake app
754+
```
755+
756+
### Further reading
757+
758+
For more information about working with named contexts, see:
759+
760+
- [`--build-context` CLI reference](/reference/cli/docker/buildx/build.md#build-context)
761+
- [Using Bake with additional contexts](/manuals/build/bake/contexts.md)

0 commit comments

Comments
 (0)