Skip to content

Instantly share code, notes, and snippets.

@iainlane
Last active May 29, 2025 11:50
Show Gist options
  • Save iainlane/b18a99fc1c59fbda500244ce977e0888 to your computer and use it in GitHub Desktop.
Save iainlane/b18a99fc1c59fbda500244ce977e0888 to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
# vim: tabstop=4:shiftwidth=4:softtabstop=4:expandtab:autoindent
# This script is a wrapper to add --buildkitd-config to a `docker buildx create`
# command if it wasn't provided by the caller.
#
# `docker buildx create` has no concept of a default configuration. But an
# organisation might want to, for example, always use a particular registry
# mirror. With this script, you can provide a default buildkit config, which
# will be applied for `docker buildx create` commands that do not have a
# config file given by the caller.
set -euo pipefail
# Try to resolve a path with a couple of fallback options, as some systems might
# not have `readlink -f` or `realpath`.
resolve_path() {
local p
# Try GNU readlink -f
if p=$(readlink -f -- "${1}" 2>/dev/null); then
printf '%s\n' "${p}"
return 0
fi
if p=$(realpath -- "${1}" 2>/dev/null); then
printf '%s\n' "${p}"
return 0
fi
if p=$(readlink -- "${1}" 2>/dev/null); then
printf '%s\n' "${p}"
return 0
fi
# Give up and just return the original path.
printf '%s\n' "${1}"
}
# Since this is a wrapper script which is going to be called `docker` and will
# be first on the PATH, we need to be able to find the real `docker` which would
# otherwise be called if we weren't here. That's the one we are wrapping.
find_real_docker_binary() {
# Where is this script?
declare -r self_path="$(resolve_path "${BASH_SOURCE[0]}")"
declare -r self_dir="$(dirname "${self_path}")"
# Rebuild PATH without self_dir
IFS=: read -r -a path_array <<<"$PATH"
local dir new_path
for dir in "${path_array[@]}"; do
# Handle empty path components. Empty means the current directory.
if [[ -z "${dir}" ]]; then
dir="."
fi
dir="$(resolve_path "${dir}")"
if [[ "${dir}" == "${self_dir}" ]]; then
continue
fi
new_path="${new_path:+${new_path}:}${dir}"
done
# Find the first "docker" in this reduced PATH
PATH="${new_path}" type -pP docker
}
# Path to real docker binary.
if ! REAL_DOCKER="$(find_real_docker_binary)"; then
echo "Error: Could not find real docker binary" >&2
exit 1
fi
declare -r REAL_DOCKER
# Path to config to be applied by default.
DEFAULT_BUILDKITD_CONFIG_FILE="${DEFAULT_BUILDKITD_CONFIG_FILE:-/etc/buildkit/default-buildkitd.toml}"
declare -r DEFAULT_BUILDKITD_CONFIG_FILE
# For non-`buildx create` commands, call the real docker.
if [[
"${1:-}" != "buildx" ||
"${2:-}" != "create" ||
! -f "${DEFAULT_BUILDKITD_CONFIG_FILE}" ]]; then
exec "${REAL_DOCKER}" "${@}"
fi
# Now we know it's `buildx create`. Check if either of `--buildkitd-config` or
# `--config` have been provided. If they have, we don't want to act.
has_config="false"
for arg in "${@}"; do
case "${arg}" in
--config | --config=* | --buildkitd-config | --buildkitd-config=*)
has_config="true"
break
;;
esac
done
# No config has been provided, so we add our default.
if [[ "${has_config}" == "false" ]]; then
set -- "${1}" "${2}" "--buildkitd-config" "${DEFAULT_BUILDKITD_CONFIG_FILE}" "${@:3}"
fi
# Otherwise, call the command as it is.
exec "${REAL_DOCKER}" "${@}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment