Merge pull request #191 from cerc-io/dboreham/builder-js-uid

Support docker containers with non-root users and host user uid not equal to 1000

Former-commit-id: 10548beedf
This commit is contained in:
David Boreham 2023-02-24 23:06:13 -07:00 committed by GitHub
commit 6a73d3adee
6 changed files with 49 additions and 4 deletions

View File

@ -83,7 +83,9 @@ def command(ctx, include, exclude):
container_build_env = { container_build_env = {
"CERC_NPM_URL": "http://gitea.local:3000/api/packages/cerc-io/npm/", "CERC_NPM_URL": "http://gitea.local:3000/api/packages/cerc-io/npm/",
"CERC_NPM_AUTH_TOKEN": config("CERC_NPM_AUTH_TOKEN", default="<token-not-supplied>"), "CERC_NPM_AUTH_TOKEN": config("CERC_NPM_AUTH_TOKEN", default="<token-not-supplied>"),
"CERC_REPO_BASE_DIR": dev_root_path "CERC_REPO_BASE_DIR": dev_root_path,
"CERC_HOST_UID": f"{os.getuid()}",
"CERC_HOST_GID": f"{os.getgid()}"
} }
def process_container(container): def process_container(container):
@ -106,7 +108,7 @@ def command(ctx, include, exclude):
build_command = os.path.join(container_build_dir, "default-build.sh") + f" {container}:local {repo_dir_or_build_dir}" build_command = os.path.join(container_build_dir, "default-build.sh") + f" {container}:local {repo_dir_or_build_dir}"
if not dry_run: if not dry_run:
if verbose: if verbose:
print(f"Executing: {build_command}") print(f"Executing: {build_command} with environment: {container_build_env}")
build_result = subprocess.run(build_command, shell=True, env=container_build_env) build_result = subprocess.run(build_command, shell=True, env=container_build_env)
if verbose: if verbose:
print(f"Return code is: {build_result.returncode}") print(f"Return code is: {build_result.returncode}")

View File

@ -116,7 +116,11 @@ def command(ctx, include, exclude):
if not dry_run: if not dry_run:
if verbose: if verbose:
print(f"Executing: {build_command}") print(f"Executing: {build_command}")
envs = {"CERC_NPM_AUTH_TOKEN": npm_registry_url_token} | ({"CERC_SCRIPT_DEBUG": "true"} if debug else {}) # Originally we used the PEP 584 merge operator:
# envs = {"CERC_NPM_AUTH_TOKEN": npm_registry_url_token} | ({"CERC_SCRIPT_DEBUG": "true"} if debug else {})
# but that isn't available in Python 3.8 (default in Ubuntu 20) so for now we use dict.update:
envs = {"CERC_NPM_AUTH_TOKEN": npm_registry_url_token}
envs.update({"CERC_SCRIPT_DEBUG": "true"} if debug else {})
try: try:
docker.run(builder_js_image_name, docker.run(builder_js_image_name,
remove=True, remove=True,

View File

@ -1,14 +1,30 @@
# Originally from: https://github.com/devcontainers/images/blob/main/src/javascript-node/.devcontainer/Dockerfile # Originally from: https://github.com/devcontainers/images/blob/main/src/javascript-node/.devcontainer/Dockerfile
# Which depends on: https://github.com/nodejs/docker-node/blob/main/Dockerfile-debian.template
# [Choice] Node.js version (use -bullseye variants on local arm64/Apple Silicon): 18, 16, 14, 18-bullseye, 16-bullseye, 14-bullseye, 18-buster, 16-buster, 14-buster # [Choice] Node.js version (use -bullseye variants on local arm64/Apple Silicon): 18, 16, 14, 18-bullseye, 16-bullseye, 14-bullseye, 18-buster, 16-buster, 14-buster
ARG VARIANT=16-bullseye ARG VARIANT=16-bullseye
FROM node:${VARIANT} FROM node:${VARIANT}
# Set these args to change the uid/gid for the base container's "node" user to match that of the host user (so bind mounts work as expected).
ARG CERC_HOST_UID=1000
ARG CERC_HOST_GID=1000
# Make these values available at runtime to allow a consistency check.
ENV HOST_UID=${CERC_HOST_UID}
ENV HOST_GID=${CERC_HOST_GID}
ARG USERNAME=node ARG USERNAME=node
ARG NPM_GLOBAL=/usr/local/share/npm-global ARG NPM_GLOBAL=/usr/local/share/npm-global
# Add NPM global to PATH. # Add NPM global to PATH.
ENV PATH=${NPM_GLOBAL}/bin:${PATH} ENV PATH=${NPM_GLOBAL}/bin:${PATH}
RUN \
if [ ${CERC_HOST_GID} -ne 1000 ] ; then \
groupmod -g ${CERC_HOST_GID} ${USERNAME} ; \
fi \
&& if [ ${CERC_HOST_UID} -ne 1000 ] ; then \
usermod -u ${CERC_HOST_UID} -g ${CERC_HOST_GID} ${USERNAME} && chown ${CERC_HOST_UID}:${CERC_HOST_GID} /home/${USERNAME} ; \
fi
RUN \ RUN \
# Configure global npm install location, use group to adapt to UID/GID changes # Configure global npm install location, use group to adapt to UID/GID changes
if ! cat /etc/group | grep -e "^npm:" > /dev/null 2>&1; then groupadd -r npm; fi \ if ! cat /etc/group | grep -e "^npm:" > /dev/null 2>&1; then groupadd -r npm; fi \
@ -39,6 +55,7 @@ RUN mkdir /scripts
COPY build-npm-package.sh /scripts COPY build-npm-package.sh /scripts
COPY yarn-local-registry-fixup.sh /scripts COPY yarn-local-registry-fixup.sh /scripts
COPY build-npm-package-local-dependencies.sh /scripts COPY build-npm-package-local-dependencies.sh /scripts
COPY check-uid.sh /scripts
ENV PATH="${PATH}:/scripts" ENV PATH="${PATH}:/scripts"
COPY entrypoint.sh . COPY entrypoint.sh .

View File

@ -0,0 +1,21 @@
#!/bin/bash
# Make the container usable for uid/gid != 1000
if [[ -n "$CERC_SCRIPT_DEBUG" ]]; then
set -x
fi
current_uid=$(id -u)
current_gid=$(id -g)
# Don't check if running as root
if [[ ${current_uid} == 0 ]]; then
exit 0
fi
# Check the current uid/gid vs the uid/gid used to build the container.
# We do this because both bind mounts and npm tooling require the uid/gid to match.
if [[ ${current_gid} != ${HOST_GID} ]]; then
echo "Warning: running with gid: ${current_gid} which is not the gid for which this container was built (${HOST_GID})"
exit 0
fi
if [[ ${current_uid} != ${HOST_UID} ]]; then
echo "Warning: running with gid: ${current_uid} which is not the uid for which this container was built (${HOST_UID})"
exit 0
fi

View File

@ -1,2 +1,3 @@
#!/bin/sh #!/bin/sh
/scripts/check-uid.sh
exec "$@" exec "$@"

View File

@ -11,4 +11,4 @@ fi
image_tag=$1 image_tag=$1
build_dir=$2 build_dir=$2
echo "Building ${image_tag} in ${build_dir}" echo "Building ${image_tag} in ${build_dir}"
docker build -t ${image_tag} ${build_dir} docker build -t ${image_tag} --build-arg CERC_HOST_UID=${CERC_HOST_UID} --build-arg CERC_HOST_GID=${CERC_HOST_GID} ${build_dir}