Dockerfile partials and devcontainer bake files for re-use across multiple applications.
The github-cache-bake.hcl
bake config file provides a basic bake configuration for use in repos that produce container images using GitHub Actions and targeted to the GitHub container registry.
The file configures registry outputs and registry cache-to and cache-from, all directed to the specified registry. It infers naming and tagging config for the image based on the context (local vs. CI, protected vs. development versions), such that while each context can push both image and cache content, development and local contexts do not collide with each other or with releases.
The configuration of the bake file requires the use of a Docker builder with the docker-container driver. To set one up, use the following command:
docker builder create --use --bootstrap --driver docker-container
The bake file requires at least IMAGE_NAME
variable to be set, and REGISTRY
should nearly always be overridden (see GitHub cache bake file inputs). Export them:
REGISTRY=ghcr.io/[your account]
IMAGE_NAME=[image name]
By default, the github-cache-bake.hcl
file expects a Dockerfile in the bake command execution directory (via cwd://Dockerfile
), which is used for the build. It sets the default context
to BAKE_CMD_CONTEXT
such that the filesystem local to the bake execution are available to the image build.
To build your image using the GitHub cache bake file via remote bake definition, run this command:
REGISTRY=ghcr.io/[your account] IMAGE_NAME=[image name] docker buildx bake --file github-cache-bake.hcl https://github.com/rcwbr/dockerfile-partials.git#0.1.0
The GitHub cache bake file can be configured using the following inputs:
Variable | Required | Default | Effect |
---|---|---|---|
IMAGE_NAME |
✓ | N/A | The name of the image, specifically not fully-qualified. This is the reference loaded to the host Docker daemon. |
GITHUB_REF_NAME |
✗ | "local-${HOST}" |
The human-friendly ref name for the GitHub context. Used to inform the image tag. |
GITHUB_REF_PROTECTED |
✗ | "false" |
Indicates if the CI context is for a protected (vs. development) ref. Indicates whether to append a unique version ID to the tag |
GITHUB_SHA |
✗ | "local" |
The commit SHA of the CI context. Appended to tags after VERSION unless GITHUB_REF_PROTECTED is true. |
HOST |
✗ | $HOSTNAME |
The name of the host device. Used to qualify image and cache names and avoid collisions between users. |
HOSTNAME |
✗ | N/A | The name of the host device, for some OSs. |
REGISTRY |
✗ | "ghcr.io/" |
The registry to which to push remote content. Generally, "ghcr.io/[user/org]/" . |
IMAGE_REF |
✗ | "${REGISTRY}${IMAGE_NAME}" |
The fully-qualified image name used as the base for version and cache references. |
VERSION |
✗ | ${GITHUB_REF_NAME} , sanitized |
This is the default tag for the image. |
Each Dockerfile partial is accompanied by a devcontainer-bake.hcl
bake config file, and a common bake file is defined at the repository root. These are intended to make composition of devcontainer image contents trivial. They are designed to work with the devcontainer-cache-build initialize script.
Using these bake files remotely requires setting the primary build context to this repo by remote definition. Because of this limitation of remote bake build contexts
We don't currently support reading a remote Dockerfile with a local context when doing a remote invocation because we automatically derive the dockerfile from the context atm
this means that any build contexts required by the Dockerfile partial must be provided via a local directory contexts
context rather than the primary build context. For example, the pre-commit
Dockerfile reads from the local_context
context set to BAKE_CMD_CONTEXT
. This allows it to consume contents of the downstream build context.
In a devcontainer.json
leveraging the devcontainer-cache-build initialize script, add the following configuration to the initializeCommand
before the curl
to the initialize script:
...
"initializeCommand": [
...
"export DEVCONTAINER_DEFINITION_TYPE=bake",
"&& export DEVCONTAINER_DEFINITION_FILES=\"devcontainer-bake.hcl [path to each desired partial bake file] cwd://.devcontainer/devcontainer-bake.hcl\"",
"&& export DEVCONTAINER_BUILD_ADDITIONAL_ARGS=https://github.com/rcwbr/dockerfile-partials.git#0.1.0",
...
]
...
DEVCONTAINER_DEFINITION_FILES
must begin with devcontainer-bake.hcl
and end with cwd://.devcontainer/devcontainer-bake.hcl
(see Devcontainer bake files devcontainer-cache-build .devcontainer/devcontainer-bake.hcl config, and with each desired partial bake file in between (ordering is important for override priority). For example:
export DEVCONTAINER_DEFINITION_FILES=\"devcontainer-bake.hcl useradd/devcontainer-bake.hcl pre-commit/devcontainer-bake.hcl cwd://.devcontainer/devcontainer-bake.hcl\""
To join the devcontainer partial bake files, you must define a bake file local to your project that configures targets from each partial you select. It must define at least the devcontainer_layers
variable as a list with the names of each selected partial, and override the base_context
for at least the first partial target. For example:
variable "devcontainer_layers" {
default = [
"useradd",
"pre-commit"
]
}
target "useradd" {
contexts = {
base_context = "docker-image://python:3.12.4"
}
}
Optionally, target
s may be configured for each layer. Values provided to these will override those defined in the partials devcontainer-bake.hcl
.
The partial bake files may be used manually through a command like this:
docker buildx bake --file devcontainer-bake.hcl [--file arg for each desired partial bake file] --file cwd://.devcontainer/devcontainer-bake.hcl https://github.com/rcwbr/dockerfile-partials.git#0.1.0
The docker-client Dockerfile defines steps to install the Docker CLI client in a Docker image. It copies the CLI executable from the Docker docker image.
The recommended usage is via the Devcontainer bake files. It is also possible to use the Dockerfile partial directly.
Use a Bake config file, and set the base_context
context as the image to which to apply the docker-client installation. For example:
target "base" {
dockerfile = "Dockerfile"
}
target "default" {
context = "https://github.com/rcwbr/dockerfile_partials.git#0.1.0"
dockerfile = "docker-client/Dockerfile"
contexts = {
base_context = "target:base"
}
}
The args accepted by the Dockerfile include:
Variable | Required | Default | Effect |
---|---|---|---|
DOCKER_GID |
✗ | 800 |
Group ID of the docker user group |
USER |
✗ | "root" |
Username to grant access to the Docker daemon |
The docker-client partial contains a devcontainer bake config file. See Devcontainer bake files for general usage. The docker-client bake config file accepts the following inputs:
Variable | Required | Default | Effect |
---|---|---|---|
DOCKER_GID |
✗ | 800 |
See docker-client Dockerfile |
USER |
✗ | "root" |
See docker-client Dockerfile |
The docker-client partial installs only the client CLI by default. To leverage the container host's Docker daemon, the relevant socket must be mounted at runtime. In a devcontainer.json
, the following content must be included:
{
"image": "[image including docker-client layers]",
"mounts": [
{ "source": "/var/run/docker.sock", "target": "/var/run/docker.sock", "type": "bind" }
]
}
The pre-commit Dockerfile defines steps to install pre-commit and install the hooks required by a repo configuration.
The recommended usage is via the Devcontainer bake files. It is also possible to use the Dockerfile partial directly.
Use a Bake config file, and set the base_context
context as the image to which to apply the pre-commit installation, and the local_context
to the directory from which the .pre-commit-config.yaml
can be loaded (generally BAKE_CMD_CONTEXT
). Additionally, provide appropriate values for the USER
build arg. For example:
target "base" {
dockerfile = "Dockerfile"
}
target "default" {
context = "https://github.com/rcwbr/dockerfile_partials.git#0.1.0"
dockerfile = "pre-commit/Dockerfile"
contexts = {
base_context = "target:base"
local_context = BAKE_CMD_CONTEXT
}
args = {
USER = "myuser"
}
}
The args accepted by the Dockerfile include:
Variable | Required | Default | Effect |
---|---|---|---|
USER |
✗ | "root" |
Username to assume for hook pre-loading |
The pre-commit partial contains a devcontainer bake config file. See Devcontainer bake files for general usage. The pre-commit bake config file accepts the following inputs:
Variable | Required | Default | Effect |
---|---|---|---|
USER |
✗ | "root" |
See pre-commit Dockerfile |
For use in Codespaces devcontainers, the build args must be set to the following values:
USER
:codespace
These values may be hard-coded in the Bake config file, or may be exposed as variables for compatibility with local environments.
variable "USER" {
default = "root"
}
...
args = {
USER = "${USER}"
}
...
If exposed as variables, the appropriate values for Codespaces use must be set as secrets so as to be available during Codespace provisioning.
The useradd Dockerfile defines steps to add a user to the image, with configurable user name, id, and group id.
The recommended usage is via the Devcontainer bake files. It is also possible to use the Dockerfile partial directly.
Use a Bake config file, and set the base_context
context as the image to which to apply the user addition. Additionally, provide appropriate values for the USER
, USER_UID
, and USER_GID
build args. For example:
target "base" {
dockerfile = "Dockerfile"
}
target "default" {
context = "https://github.com/rcwbr/dockerfile_partials.git#0.1.0"
dockerfile = "useradd/Dockerfile"
contexts = {
base_context = "target:base"
}
args = {
USER = "myuser"
USER_UID = 1000
USER_GID = 1000
}
}
The args accepted by the Dockerfile include:
Variable | Required | Default | Effect |
---|---|---|---|
USER |
✓ | N/A | Username of the user to create |
EXTRA_GID_ARGS |
✗ | "" |
Extra --gid [id] args to apply to the useradd command |
USER_UID |
✗ | 1000 |
User UID for the user to create |
USER_GID |
✗ | $USER_UID |
User GID for the user to create |
The useradd partial contains a devcontainer bake config file. See Devcontainer bake files for general usage. The useradd bake config file accepts the following inputs:
Variable | Required | Default | Effect |
---|---|---|---|
USER |
✗ | "root" |
See useradd Dockerfile |
EXTRA_GID_ARGS |
✗ | "" or DOCKER_CLIENT_EXTRA_GID_ARGS if defined |
See useradd Dockerfile |
UID |
✗ | 0 |
Maps to USER_UID . See useradd Dockerfile |
GID |
✗ | ${UID} |
Maps to USER_GID .See useradd Dockerfile |
For use in Codespaces devcontainers, the build args must be set to the following values:
USER
:codespace
UID
:1000
These values may be hard-coded in the Bake config file, or may be exposed as variables for compatibility with local environments.
variable "USER" {
default = "root"
}
variable "UID" {
default = 0
}
variable "GID" {
// Use the user id as group id unless set
default = "${UID}"
}
...
args = {
USER = "${USER}"
USER_UID = "${UID}"
USER_GID = "${GID}"
}
...
If exposed as variables, the appropriate values for Codespaces use must be set as secrets so as to be available during Codespace provisioning.
This repo contains a devcontainer definition in the .devcontainer
folder. It leverages the devcontainer cache build tool and the Dockerfile partials defined in this repo.
The devcontainer cache build tool requires authentication to the GitHub package registry, as a token stored as DOCKERFILE_PARTIALS_DEVCONTAINER_INITIALIZE
(see instructions).
For use with Codespaces, the DOCKERFILE_PARTIALS_DEVCONTAINER_INITIALIZE
token (see devcontainer basic usage) must be stored as a Codespaces secret (see instructions), as must values for USER
, and UID
(see useradd Codespaces usage).
This repo uses the release-it-gh-workflow, with the conventional-changelog image defined at any given ref, as its automation.
The GitHub repo settings for this repo are defined as code using the Probot settings GitHub App. Settings values are defined in the .github/settings.yml
file. Enabling automation of settings via this file requires installing the app.
The settings applied are as recommended in the release-it-gh-workflow usage, including tag and branch protections, GitHub App and environment authentication, and required checks.