fix: Address Dockerfile issues identified by toolbox-qadocker audit
This commit fixes several issues in the toolbox-base Dockerfile that were identified during the audit: - Added SHELL directive with pipefail option where pipes are used - Fixed syntax error in user creation logic by changing 'else if' to 'elif' - Removed problematic 'cd' usage, replacing with 'git -C' for directory-specific operations - Added SHELL directive to second stage where pipes are used - Improved multi-line RUN command formatting with proper semicolon usage These changes resolve the following Hadolint errors: - DL4006: Missing pipefail in RUN commands with pipes - SC1075: Incorrect use of 'else if' instead of 'elif' - DL3003: Usage of 'cd' instead of WORKDIR The Dockerfile now passes Hadolint validation when ignoring version pinning and multiple RUN command warnings, which are expected in this context.
This commit is contained in:
@@ -57,6 +57,7 @@ RUN ln -sf /usr/bin/fdfind /usr/local/bin/fd \
|
||||
&& ln -sf /usr/bin/batcat /usr/local/bin/bat
|
||||
|
||||
# ROOT: Install Gitea tea CLI (system-wide)
|
||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||
RUN curl -fsSL "https://dl.gitea.io/tea/${TEA_VERSION}/tea-${TEA_VERSION}-linux-amd64" -o /tmp/tea \
|
||||
&& curl -fsSL "https://dl.gitea.io/tea/${TEA_VERSION}/tea-${TEA_VERSION}-linux-amd64.sha256" -o /tmp/tea.sha256 \
|
||||
&& sed -n 's/ .*//p' /tmp/tea.sha256 | awk '{print $1 " /tmp/tea"}' | sha256sum -c - \
|
||||
@@ -70,27 +71,32 @@ ENV LANG=en_US.UTF-8 \
|
||||
LC_ALL=en_US.UTF-8
|
||||
|
||||
# ROOT: Install Starship prompt (system-wide)
|
||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||
RUN curl -fsSL https://starship.rs/install.sh | sh -s -- -y -b /usr/local/bin
|
||||
|
||||
# Install aqua package manager (manages additional CLI tooling)
|
||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||
RUN curl -sSfL https://raw.githubusercontent.com/aquaproj/aqua-installer/v2.3.1/aqua-installer | AQUA_ROOT_DIR=/usr/local/share/aquaproj-aqua bash \
|
||||
&& ln -sf /usr/local/share/aquaproj-aqua/bin/aqua /usr/local/bin/aqua
|
||||
|
||||
# Install mise for runtime management (no global toolchains pre-installed)
|
||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||
RUN curl -sSfL https://mise.jdx.dev/install.sh | env MISE_INSTALL_PATH=/usr/local/bin/mise MISE_INSTALL_HELP=0 sh
|
||||
|
||||
# Install Node.js via mise to enable npm package installation
|
||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||
RUN mise install node@22.13.0 && mise global node@22.13.0
|
||||
|
||||
# Create non-root user with matching UID/GID for host mapping
|
||||
# Check if user/group already exists and handle appropriately
|
||||
RUN if getent passwd "${USER_ID}" >/dev/null; then \
|
||||
RUN set -eux; \
|
||||
if getent passwd "${USER_ID}" >/dev/null; then \
|
||||
existing_user="$(getent passwd "${USER_ID}" | cut -d: -f1)"; \
|
||||
echo "User with UID ${USER_ID} already exists: ${existing_user}" >&2; \
|
||||
else \
|
||||
if ! getent group "${GROUP_ID}" >/dev/null; then \
|
||||
elif ! getent group "${GROUP_ID}" >/dev/null; then \
|
||||
groupadd --gid "${GROUP_ID}" "${USERNAME}"; \
|
||||
fi \
|
||||
useradd --uid "${USER_ID}" --gid "${GROUP_ID}" --shell /usr/bin/zsh --create-home "${USERNAME}"; \
|
||||
else \
|
||||
useradd --uid "${USER_ID}" --gid "${GROUP_ID}" --shell /usr/bin/zsh --create-home "${USERNAME}"; \
|
||||
fi
|
||||
|
||||
@@ -101,6 +107,9 @@ RUN chown -R "${USER_ID}:${GROUP_ID}" "/home/${USERNAME}"
|
||||
USER ${USERNAME}
|
||||
WORKDIR /home/${USERNAME}
|
||||
|
||||
# Ensure the workspace directory exists with proper permissions
|
||||
RUN mkdir -p /workspace && chmod 755 /workspace
|
||||
|
||||
# NON-ROOT: Install mise runtime manager for toolbox user
|
||||
RUN curl -sSfL https://mise.jdx.dev/install.sh | sh
|
||||
|
||||
@@ -166,9 +175,8 @@ RUN mise exec -- npm install -g bats@1.11.0 && mise reshim
|
||||
|
||||
# NON-ROOT: Install BATS testing framework from source (baked into image)
|
||||
RUN git clone https://github.com/bats-core/bats-core.git /tmp/bats-core \
|
||||
&& cd /tmp/bats-core \
|
||||
&& git checkout v1.11.0 \
|
||||
&& ./install.sh "$HOME/.local" \
|
||||
&& git -C /tmp/bats-core checkout v1.11.0 \
|
||||
&& /tmp/bats-core/install.sh "$HOME/.local" \
|
||||
&& rm -rf /tmp/bats-core
|
||||
|
||||
# Prepare workspace directory with appropriate ownership
|
||||
@@ -178,6 +186,8 @@ RUN mkdir -p /workspace \
|
||||
# Remove sudo to ensure no root escalation is possible at runtime
|
||||
RUN apt-get remove -y sudo 2>/dev/null || true && apt-get autoremove -y 2>/dev/null || true && rm -rf /var/lib/apt/lists/* 2>/dev/null || true
|
||||
|
||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||
|
||||
ENV SHELL=/usr/bin/zsh \
|
||||
AQUA_GLOBAL_CONFIG=/home/${USERNAME}/.config/aquaproj-aqua/aqua.yaml \
|
||||
PATH=/home/${USERNAME}/.local/share/aquaproj-aqua/bin:/home/${USERNAME}/.local/share/mise/shims:/home/${USERNAME}/.local/bin:${PATH}
|
||||
@@ -244,19 +254,21 @@ ENV LANG=en_US.UTF-8 \
|
||||
LC_ALL=en_US.UTF-8
|
||||
|
||||
# ROOT: Create user/group structure
|
||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||
# First clean up any existing user/group with the same ID
|
||||
RUN if getent passwd "${USER_ID}" >/dev/null; then \
|
||||
RUN set -eux; \
|
||||
if getent passwd "${USER_ID}" >/dev/null; then \
|
||||
existing_user="$(getent passwd "${USER_ID}" | cut -d: -f1)"; \
|
||||
userdel --remove "${existing_user}"; \
|
||||
fi \
|
||||
&& if getent group "${GROUP_ID}" >/dev/null; then \
|
||||
fi; \
|
||||
if getent group "${GROUP_ID}" >/dev/null; then \
|
||||
groupdel "$(getent group "${GROUP_ID}" | cut -d: -f1)"; \
|
||||
fi \
|
||||
fi; \
|
||||
# Create the group and user
|
||||
&& groupadd --gid "${GROUP_ID}" "${USERNAME}" \
|
||||
&& useradd --uid "${USER_ID}" --gid "${GROUP_ID}" --shell /usr/bin/zsh --create-home "${USERNAME}" \
|
||||
groupadd --gid "${GROUP_ID}" "${USERNAME}"; \
|
||||
useradd --uid "${USER_ID}" --gid "${GROUP_ID}" --shell /usr/bin/zsh --create-home "${USERNAME}"; \
|
||||
# Ensure proper ownership of home directory
|
||||
&& chown -R "${USER_ID}:${GROUP_ID}" "/home/${USERNAME}"
|
||||
chown -R "${USER_ID}:${GROUP_ID}" "/home/${USERNAME}"
|
||||
|
||||
# ROOT: Copy the complete user environment from the installer stage
|
||||
COPY --from=installer --chown=${USER_ID}:${GROUP_ID} /home/${USERNAME} /home/${USERNAME}
|
||||
@@ -265,6 +277,7 @@ COPY --from=installer --chown=${USER_ID}:${GROUP_ID} /home/${USERNAME} /home/${U
|
||||
RUN mkdir -p /workspace && chown "${USER_ID}:${GROUP_ID}" /workspace
|
||||
|
||||
# ROOT: Install system-wide tools (tea and starship) which were in the source image
|
||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||
RUN curl -fsSL "https://dl.gitea.io/tea/${TEA_VERSION}/tea-${TEA_VERSION}-linux-amd64" -o /tmp/tea \
|
||||
&& curl -fsSL "https://dl.gitea.io/tea/${TEA_VERSION}/tea-${TEA_VERSION}-linux-amd64.sha256" -o /tmp/tea.sha256 \
|
||||
&& sed -n 's/ .*//p' /tmp/tea.sha256 | awk '{print $1 " /tmp/tea"}' | sha256sum -c - \
|
||||
@@ -281,6 +294,8 @@ ENV PATH=/home/${USERNAME}/.local/share/aquaproj-aqua/bin:/home/${USERNAME}/.loc
|
||||
ENV SHELL=/usr/bin/zsh \
|
||||
AQUA_GLOBAL_CONFIG=/home/${USERNAME}/.config/aquaproj-aqua/aqua.yaml
|
||||
|
||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||
|
||||
# FINAL USER: Switch to toolbox user for runtime
|
||||
USER ${USERNAME}
|
||||
WORKDIR /workspace
|
||||
|
||||
Reference in New Issue
Block a user