This commit is contained in:
2025-10-28 19:57:51 -05:00
parent 9f17603c1e
commit 65b278e33f
27 changed files with 875 additions and 227 deletions

View File

@@ -0,0 +1,14 @@
{
"name": "TSYSDevStack Toolbox Base",
"dockerComposeFile": [
"../docker-compose.yml"
],
"service": "toolbox-base",
"workspaceFolder": "/workspace",
"remoteUser": "toolbox",
"runServices": [
"toolbox-base"
],
"overrideCommand": false,
"postCreateCommand": "zsh -lc 'starship --version >/dev/null'"
}

View File

@@ -0,0 +1,80 @@
FROM ubuntu:24.04
ARG USER_ID=1000
ARG GROUP_ID=1000
ARG USERNAME=toolbox
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
ca-certificates \
curl \
fish \
fzf \
git \
jq \
locales \
openssh-client \
ripgrep \
tmux \
fd-find \
bat \
wget \
zsh \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Provide common aliases for fd and bat binaries
RUN ln -sf /usr/bin/fdfind /usr/local/bin/fd \
&& ln -sf /usr/bin/batcat /usr/local/bin/bat
# Configure locale to ensure consistent tool behavior
RUN locale-gen en_US.UTF-8
ENV LANG=en_US.UTF-8 \
LANGUAGE=en_US:en \
LC_ALL=en_US.UTF-8
# Install Starship prompt
RUN curl -fsSL https://starship.rs/install.sh | sh -s -- -y -b /usr/local/bin
# Install aqua package manager (manages additional CLI tooling)
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
# 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}"
# Install Oh My Zsh for the unprivileged user
RUN su - "${USERNAME}" -c 'git clone --depth=1 https://github.com/ohmyzsh/ohmyzsh.git ~/.oh-my-zsh' \
&& su - "${USERNAME}" -c 'cp ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc' \
&& su - "${USERNAME}" -c 'mkdir -p ~/.config' \
&& su - "${USERNAME}" -c 'sed -i "s/^plugins=(git)$/plugins=(git fzf)/" ~/.zshrc' \
&& su - "${USERNAME}" -c 'printf "\nexport PATH=\"\$HOME/.local/share/aquaproj-aqua/bin:\$HOME/.local/bin:\$PATH\"\n" >> ~/.zshrc' \
&& su - "${USERNAME}" -c 'printf "\n# Starship prompt\neval \"\$(starship init zsh)\"\n" >> ~/.zshrc'
COPY aqua.yaml /tmp/aqua.yaml
RUN chown "${USER_ID}:${GROUP_ID}" /tmp/aqua.yaml \
&& su - "${USERNAME}" -c 'mkdir -p ~/.config/aquaproj-aqua' \
&& su - "${USERNAME}" -c 'cp /tmp/aqua.yaml ~/.config/aquaproj-aqua/aqua.yaml' \
&& su - "${USERNAME}" -c 'AQUA_GLOBAL_CONFIG=~/.config/aquaproj-aqua/aqua.yaml aqua install'
# Prepare workspace directory with appropriate ownership
RUN mkdir -p /workspace \
&& chown "${USER_ID}:${GROUP_ID}" /workspace
ENV SHELL=/usr/bin/zsh \
PATH=/home/${USERNAME}/.local/share/aquaproj-aqua/bin:/home/${USERNAME}/.local/bin:${PATH}
WORKDIR /workspace
USER ${USERNAME}
CMD ["/usr/bin/zsh"]

View File

@@ -0,0 +1,8 @@
version: 1.0.0
registries:
- type: standard
ref: v4.200.0
packages:
- name: cli/cli@latest
- name: go-gitea/tea@latest
- name: jesseduffield/lazygit@latest

View File

@@ -0,0 +1,19 @@
#!/usr/bin/env bash
set -euo pipefail
IMAGE_NAME="tsysdevstack-toolboxstack-toolbox-base"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
USER_ID="${USER_ID_OVERRIDE:-$(id -u)}"
GROUP_ID="${GROUP_ID_OVERRIDE:-$(id -g)}"
USERNAME="${USERNAME_OVERRIDE:-toolbox}"
echo "Building ${IMAGE_NAME} with UID=${USER_ID} GID=${GROUP_ID} USERNAME=${USERNAME}"
docker build \
--build-arg USER_ID="${USER_ID}" \
--build-arg GROUP_ID="${GROUP_ID}" \
--build-arg USERNAME="${USERNAME}" \
--tag "${IMAGE_NAME}" \
"${SCRIPT_DIR}"

View File

@@ -0,0 +1,18 @@
services:
toolbox-base:
container_name: tsysdevstack-toolboxstack-toolbox-base
image: tsysdevstack-toolboxstack-toolbox-base
build:
context: .
args:
USER_ID: ${LOCAL_UID:-1000}
GROUP_ID: ${LOCAL_GID:-1000}
USERNAME: ${LOCAL_USERNAME:-toolbox}
user: "${LOCAL_UID:-1000}:${LOCAL_GID:-1000}"
working_dir: /workspace
command: ["sleep", "infinity"]
init: true
tty: true
stdin_open: true
volumes:
- .:/workspace:rw

View File

@@ -0,0 +1,31 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
COMPOSE_FILE="${SCRIPT_DIR}/docker-compose.yml"
export LOCAL_UID="${USER_ID_OVERRIDE:-$(id -u)}"
export LOCAL_GID="${GROUP_ID_OVERRIDE:-$(id -g)}"
export LOCAL_USERNAME="${USERNAME_OVERRIDE:-toolbox}"
if [[ ! -f "${COMPOSE_FILE}" ]]; then
echo "Error: docker-compose.yml not found at ${COMPOSE_FILE}" >&2
exit 1
fi
ACTION="${1:-up}"
shift || true
case "${ACTION}" in
up)
docker compose -f "${COMPOSE_FILE}" up --build --detach "$@"
;;
down)
docker compose -f "${COMPOSE_FILE}" down "$@"
;;
*)
echo "Usage: $0 [up|down] [additional docker compose args]" >&2
exit 1
;;
esac