chore(filesystem): reflect major filesystem restructuring changes

- Renamed DocStack to dockstack
- Transformed toolbox-template into toolbox-qadocker with new functionality
- Removed NewToolbox.sh script
- Updated PROMPT and configuration files across all toolboxes
- Consolidated audit and testing scripts
- Updated QWEN.md to reflect new filesystem structure as authoritative source
- Merged PROMPT content into QWEN.md as requested

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

The filesystem structure has been intentionally restructured and is now the authoritative source of truth for the project organization.
This commit is contained in:
2025-10-31 13:26:39 -05:00
parent 199789e2c4
commit ab54d694f2
48 changed files with 1020 additions and 1119 deletions

View File

@@ -1,195 +1,77 @@
# Multi-stage approach to minimize final image size and attack surface
FROM ubuntu:24.04 AS installer
ARG USER_ID=1000
ARG GROUP_ID=1000
ARG USERNAME=toolbox
ARG TEA_VERSION=0.11.1
ENV DEBIAN_FRONTEND=noninteractive
# ROOT STAGE 1: System package installation for Docker QA tools only
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt/lists,sharing=locked \
apt-get update \
&& apt-get install -y --no-install-recommends \
ca-certificates \
curl \
git \
jq \
bc \
locales \
openssh-client \
zsh \
unzip \
zip \
python3 \
python3-pip \
wget \
# Docker and container tools \
docker.io \
# Security scanning tools \
clamav \
# Static analysis tools \
shellcheck \
# JSON/YAML tools \
yq \
# Development tools for custom scripts \
make \
gcc \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# ROOT: Configure locale
RUN locale-gen en_US.UTF-8
ENV LANG=en_US.UTF-8 \
LANGUAGE=en_US:en \
LC_ALL=en_US.UTF-8
# ROOT: Create non-root user with matching UID/GID for host mapping
RUN 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 \
groupadd --gid "${GROUP_ID}" "${USERNAME}"; \
fi \
&& useradd --uid "${USER_ID}" --gid "${GROUP_ID}" --shell /usr/bin/zsh --create-home "${USERNAME}"
# ROOT: Set up toolbox user home directory with proper permissions
RUN chown -R "${USER_ID}:${GROUP_ID}" "/home/${USERNAME}"
# SWITCH TO NON-ROOT USER: All further operations as toolbox user
USER ${USERNAME}
WORKDIR /home/${USERNAME}
# NON-ROOT: Install mise runtime manager for toolbox user
RUN curl -sSfL https://mise.jdx.dev/install.sh | sh
# NON-ROOT: Update PATH for mise tools
ENV PATH=/home/${USERNAME}/.local/bin:/home/${USERNAME}/.local/share/mise/shims:$PATH
# NON-ROOT: Install Node.js via mise as toolbox user
RUN mise install node@22.13.0 && mise use -g node@22.13.0
# NON-ROOT: Install aqua package manager for toolbox user
RUN curl -sSfL https://raw.githubusercontent.com/aquaproj/aqua-installer/v2.3.1/aqua-installer > /tmp/aqua-installer.sh && \
chmod +x /tmp/aqua-installer.sh && \
AQUA_ROOT_DIR=/home/${USERNAME}/.local/share/aquaproj-aqua /tmp/aqua-installer.sh && \
rm /tmp/aqua-installer.sh
# NON-ROOT: Update PATH for aqua tools
ENV PATH=/home/${USERNAME}/.local/share/aquaproj-aqua/bin:$PATH
# NON-ROOT: Install Oh My Zsh
RUN git clone --depth=1 https://github.com/ohmyzsh/ohmyzsh.git ~/.oh-my-zsh
# NON-ROOT: Configure shells (zsh, bash) with all customizations
RUN cp ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc \
&& sed -i "s/^plugins=(git)$/plugins=(git docker docker-compose)/" ~/.zshrc \
&& printf "\nexport PATH=\"\$HOME/.local/share/aquaproj-aqua/bin:\$HOME/.local/share/mise/shims:\$HOME/.local/bin:\$PATH\"\n" >> ~/.zshrc \
&& printf "\n# Starship prompt\neval \"\$(starship init zsh)\"\n" >> ~/.zshrc \
&& printf "\n# mise runtime manager\neval \"\$(mise activate zsh)\"\n" >> ~/.zshrc \
&& printf "\n# direnv\nexport DIRENV_LOG_FORMAT=\"\"\neval \"\$(direnv hook zsh)\"\n" >> ~/.zshrc \
&& printf "\nexport AQUA_GLOBAL_CONFIG=\"\$HOME/.config/aquaproj-aqua/aqua.yaml\"\n" >> ~/.bashrc \
&& printf "\n# mise runtime manager (bash)\neval \"\$(mise activate bash)\"\n" >> ~/.bashrc \
&& printf "\n# direnv\nexport DIRENV_LOG_FORMAT=\"\"\neval \"\$(direnv hook bash)\"\n" >> ~/.bashrc
# NON-ROOT: Install aqua packages for Docker QA tools
RUN mkdir -p ~/.config/aquaproj-aqua \
&& echo "version: 1.0.0\nregistries:\n - type: standard\n ref: v4.431.0\npackages:\n - name: aquasecurity/trivy@v0.54.1\n - name: hadolint/hadolint@v2.14.0\n - name: github/gh@v2.69.0\n - name: dandavison/delta@0.18.2\n - name: ajeetdsouza/zoxide@v0.9.8\n - name: mikefarah/yq@v4.48.1\n - name: direnv/direnv@v2.37.1" > ~/.config/aquaproj-aqua/aqua.yaml \
&& aqua install \
&& aqua install --all
# NON-ROOT: Install additional Docker QA tools via npm
RUN mise exec -- npm install -g dockerfilelint@latest && mise reshim
# NON-ROOT: Install additional Python-based tools using --break-system-packages
RUN pip3 install --break-system-packages docker-image-py
# ROOT: Set up workspace directory
USER root
RUN mkdir -p /workspace && chown "${USER_ID}:${GROUP_ID}" /workspace
USER ${USERNAME}
# NON-ROOT: Verify all tools are accessible during build
RUN bash -c 'command -v docker && command -v dockerfilelint' \
&& bash -c 'docker --version && node --version && npm --version'
# NON-ROOT: Final mise reshim to ensure all tools are properly linked
RUN mise reshim
# FINAL STAGE: Copy completed setup to minimize image and enhance security
# Use Ubuntu 24.04 as base for the QA Docker toolbox
FROM ubuntu:24.04
# Set build arguments (these can be overridden at build time)
ARG USER_ID=1000
ARG GROUP_ID=1000
ARG USERNAME=toolbox
ARG TEA_VERSION=0.11.1
# Set up environment and install essential packages
ENV DEBIAN_FRONTEND=noninteractive
# ROOT: Install minimal runtime dependencies only
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt/lists,sharing=locked \
apt-get update \
&& apt-get install -y --no-install-recommends \
ca-certificates \
curl \
git \
jq \
bc \
locales \
openssh-client \
zsh \
unzip \
zip \
python3 \
docker.io \
&& apt-get clean \
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
curl \
gnupg \
lsb-release \
git \
unzip \
wget \
&& rm -rf /var/lib/apt/lists/*
# ROOT: Restore system-wide configurations
RUN locale-gen en_US.UTF-8
ENV LANG=en_US.UTF-8 \
LANGUAGE=en_US:en \
LC_ALL=en_US.UTF-8
# Install Docker CLI
RUN install -m 0755 -d /etc/apt/keyrings \
&& curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg \
&& chmod a+r /etc/apt/keyrings/docker.gpg \
&& echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
tee /etc/apt/sources.list.d/docker.list > /dev/null \
&& apt-get update \
&& apt-get install -y --no-install-recommends docker-ce-cli \
&& rm -rf /var/lib/apt/lists/*
# ROOT: Create non-root user with matching UID/GID for host mapping
RUN 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 \
# Install hadolint for Dockerfile linting
RUN wget -O /usr/bin/hadolint https://github.com/hadolint/hadolint/releases/download/v2.12.0/hadolint-Linux-x86_64 \
&& chmod +x /usr/bin/hadolint
# Install dive for exploring Docker image layers
RUN wget -O /tmp/dive_0.10.0_linux_amd64.deb https://github.com/wagoodman/dive/releases/download/v0.10.0/dive_0.10.0_linux_amd64.deb \
&& dpkg -i /tmp/dive_0.10.0_linux_amd64.deb \
&& rm /tmp/dive_0.10.0_linux_amd64.deb
# Create non-root user
RUN if ! getent group "${USERNAME}" >/dev/null; then \
groupadd --gid "${GROUP_ID}" "${USERNAME}"; \
fi \
&& useradd --uid "${USER_ID}" --gid "${GROUP_ID}" --shell /usr/bin/zsh --create-home "${USERNAME}"
fi && \
if ! id "${USERNAME}" >/dev/null 2>&1; then \
useradd --uid "${USER_ID}" --gid "${GROUP_ID}" --shell /bin/bash --create-home "${USERNAME}"; \
fi
# ROOT: Copy the complete user environment from the installer stage
COPY --from=installer --chown=${USER_ID}:${GROUP_ID} /home/${USERNAME} /home/${USERNAME}
# Install aqua for package management
RUN curl -sSfL https://raw.githubusercontent.com/aquaproj/aqua-installer/v3.0.0/aqua-installer | bash -s -- -v v3.0.0 \
&& mv /usr/local/bin/aqua /usr/local/bin/aqua-tmp \
&& mkdir -p /root/.local/share/aquaproj-aqua/bin \
&& mv /usr/local/bin/aqua-tmp /root/.local/share/aquaproj-aqua/bin/aqua \
&& ln -s /root/.local/share/aquaproj-aqua/bin/aqua /usr/local/bin/aqua
# ROOT: Create workspace directory
RUN mkdir -p /workspace && chown "${USER_ID}:${GROUP_ID}" /workspace
# Copy the aqua.yaml configuration for the non-root user and install packages
COPY aqua.yaml /tmp/aqua.yaml
RUN chown "${USER_ID}:${GROUP_ID}" /tmp/aqua.yaml \
&& mkdir -p /home/${USERNAME}/.config/aquaproj-aqua \
&& chown "${USER_ID}:${GROUP_ID}" /home/${USERNAME}/.config/aquaproj-aqua \
&& su - "${USERNAME}" -c 'cp /tmp/aqua.yaml /home/${USERNAME}/.config/aquaproj-aqua/aqua.yaml' \
&& su - "${USERNAME}" -c 'AQUA_GLOBAL_CONFIG=/home/${USERNAME}/.config/aquaproj-aqua/aqua.yaml aqua install'
# ROOT: Install system-wide tools (tea and starship) which were in the source image
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 - \
&& install -m 0755 /tmp/tea /usr/local/bin/tea \
&& rm -f /tmp/tea /tmp/tea.sha256
# Prepare workspace directory with appropriate ownership
RUN mkdir -p /workspace \
&& chown "${USER_ID}:${GROUP_ID}" /workspace
RUN curl -fsSL https://starship.rs/install.sh | sh -s -- -y -b /usr/local/bin
# ROOT: Security hardening - remove sudo if present
# 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
# ROOT: Final environment variables
ENV PATH=/home/${USERNAME}/.local/share/aquaproj-aqua/bin:/home/${USERNAME}/.local/share/mise/shims:/home/${USERNAME}/.local/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin
ENV SHELL=/usr/bin/zsh \
AQUA_GLOBAL_CONFIG=/home/${USERNAME}/.config/aquaproj-aqua/aqua.yaml
ENV PATH=/root/.local/share/aquaproj-aqua/bin:/home/${USERNAME}/.local/share/aquaproj-aqua/bin:/usr/local/bin:${PATH}
# FINAL USER: Switch to toolbox user for runtime
USER ${USERNAME}
WORKDIR /workspace
USER ${USERNAME}
CMD ["/usr/bin/zsh"]
CMD ["/bin/bash"]