From c0810f8a2249dae3e5d7c74e86eead22e03b8588 Mon Sep 17 00:00:00 2001 From: Mike Date: Sun, 12 Apr 2026 15:05:33 -0400 Subject: [PATCH 1/6] Add kubeseal tool, commented mounts in example dev container json --- .devcontainer/example/devcontainer.json | 5 +++-- Dockerfile | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/.devcontainer/example/devcontainer.json b/.devcontainer/example/devcontainer.json index 54fd492..618aba6 100755 --- a/.devcontainer/example/devcontainer.json +++ b/.devcontainer/example/devcontainer.json @@ -24,8 +24,9 @@ // Mount the workspace into /workspace inside the container. // This is where VS Code will open the terminal and where your files live. - "workspaceFolder": "/workspace", - "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind,consistency=cached", + // Use this when you need to override the default mount behavior + // "workspaceFolder": "/workspace", + // "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind,consistency=cached", // Mount credentials read-only so tooling inside the container can use them. // These are never copied into the image — they exist only in the live session. diff --git a/Dockerfile b/Dockerfile index eaa0e72..60676f7 100755 --- a/Dockerfile +++ b/Dockerfile @@ -35,6 +35,8 @@ ARG GH_VERSION=2.89.0 # Containerization tools ARG K9S_VERSION=v0.50.18 ARG KUBECTL_VERSION=v1.35.3 +# The kubeseal version specifically does NOT have the v prefix +ARG KUBESEAL_VERSION=0.36.6 # Infrastructure as code tools ARG ANSIBLE_VERSION=13.5.0 @@ -112,6 +114,7 @@ ENV PIPX_BIN_DIR="/usr/local/bin" # Terraform # Installed via HashiCorp's official binary release (not apt) so we can pin # to an exact patch version rather than relying on repo availability. +# URL: https://developer.hashicorp.com/terraform # ----------------------------------------------------------------------------- RUN curl -fsSL \ "https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_${TARGETARCH}.zip" \ @@ -124,6 +127,7 @@ RUN curl -fsSL \ # ----------------------------------------------------------------------------- # kubectl # Installed via official Kubernetes binary release for exact version pinning. +# URL: https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/ # ----------------------------------------------------------------------------- RUN curl -fsSL \ "https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/${TARGETARCH}/kubectl" \ @@ -136,6 +140,7 @@ RUN curl -fsSL \ # Terminal UI for Kubernetes cluster management. Installed via GitHub release # binary — no official apt package exists. Pinned for the same reproducibility # reasons as all other binary tools in this image. +# URL: https://github.com/derailed/k9s # ----------------------------------------------------------------------------- RUN curl -fsSL \ "https://github.com/derailed/k9s/releases/download/${K9S_VERSION}/k9s_Linux_${TARGETARCH}.tar.gz" \ @@ -145,6 +150,19 @@ RUN curl -fsSL \ && chmod +x /usr/local/bin/k9s \ && k9s version +# ----------------------------------------------------------------------------- +# kubeseal +# Tool used to manage SealedSecrets in a Kubernetes cluster. Installed via +# GitHub release binary — no official apt package exists. +# URL: https://github.com/bitnami-labs/sealed-secrets +# ----------------------------------------------------------------------------- + +RUN curl -OL "https://github.com/bitnami-labs/sealed-secrets/releases/download/v${KUBESEAL_VERSION}/kubeseal-${KUBESEAL_VERSION}-linux-${TARGETARCH}.tar.gz" \ + && tar -xvzf kubeseal-${KUBESEAL_VERSION}-linux-${TARGETARCH}.tar.gz kubeseal \ + && install -m 755 kubeseal /usr/local/bin/kubeseal \ + && rm kubeseal \ + && rm kubeseal-${KUBESEAL_VERSION}-linux-amd64.tar.gz + # ----------------------------------------------------------------------------- # Python development tooling # Installed into the base Python environment so they are available for From f3eeb28c501368b0f4a1d6cd4b842edbc590aca0 Mon Sep 17 00:00:00 2001 From: Mike Date: Sun, 12 Apr 2026 15:09:48 -0400 Subject: [PATCH 2/6] Updated README for kubeseal --- README.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/README.md b/README.md index f0e3aaf..39a0055 100755 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ with Docker and VS Code — no local setup required. | [Terraform](https://www.terraform.io) | See [Dockerfile](./Dockerfile) | Infrastructure as code | | [kubectl](https://kubernetes.io/docs/reference/kubectl/) | See [Dockerfile](./Dockerfile) | Kubernetes cluster management | | [k9s](https://k9scli.io) | See [Dockerfile](./Dockerfile) | Kubernetes terminal UI | +| [kubeseal](https://github.com/bitnami-labs/sealed-secrets) | See [Dockerfile](./Dockerfile) | Kubernetes SealedSecrets CLI | | [Ansible](https://www.ansible.com) | See [Dockerfile](./Dockerfile) | Configuration management and automation | | [.NET SDK](https://dotnet.microsoft.com) | See [Dockerfile](./Dockerfile) | .NET development | | [Python](https://www.python.org) | See [Dockerfile](./Dockerfile) | Scripting and development | @@ -107,10 +108,6 @@ Then, add a `.devcontainer/devcontainer.json` to your project repository with th "image": "taegost/devops-toolbox:latest", "workspaceFolder": "/workspace", "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind,consistency=cached", - "mounts": [ - "source=${localEnv:HOME}/.kube,target=/home/vscode/.kube,type=bind,readonly", - "source=${localEnv:HOME}/.ssh,target=/home/vscode/.ssh,type=bind,readonly" - ], "remoteUser": "vscode", "customizations": { "vscode": { From bd29fa3b5c2af4631f5027f23ae25da551900ae7 Mon Sep 17 00:00:00 2001 From: Mike Date: Sun, 12 Apr 2026 15:20:32 -0400 Subject: [PATCH 3/6] Fix arch in kubeseal removal line --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 60676f7..2701125 100755 --- a/Dockerfile +++ b/Dockerfile @@ -161,7 +161,7 @@ RUN curl -OL "https://github.com/bitnami-labs/sealed-secrets/releases/download/v && tar -xvzf kubeseal-${KUBESEAL_VERSION}-linux-${TARGETARCH}.tar.gz kubeseal \ && install -m 755 kubeseal /usr/local/bin/kubeseal \ && rm kubeseal \ - && rm kubeseal-${KUBESEAL_VERSION}-linux-amd64.tar.gz + && rm kubeseal-${KUBESEAL_VERSION}-linux-${TARGETARCH}..tar.gz # ----------------------------------------------------------------------------- # Python development tooling From 12428961e0f65ba9b55ae937d5e80708ea77072f Mon Sep 17 00:00:00 2001 From: Mike Date: Sun, 12 Apr 2026 15:21:49 -0400 Subject: [PATCH 4/6] Added a period --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 2701125..b2e8f07 100755 --- a/Dockerfile +++ b/Dockerfile @@ -161,7 +161,7 @@ RUN curl -OL "https://github.com/bitnami-labs/sealed-secrets/releases/download/v && tar -xvzf kubeseal-${KUBESEAL_VERSION}-linux-${TARGETARCH}.tar.gz kubeseal \ && install -m 755 kubeseal /usr/local/bin/kubeseal \ && rm kubeseal \ - && rm kubeseal-${KUBESEAL_VERSION}-linux-${TARGETARCH}..tar.gz + && rm kubeseal-${KUBESEAL_VERSION}-linux-${TARGETARCH}.tar.gz # ----------------------------------------------------------------------------- # Python development tooling From 280477473740313c9eb40bd6afd14b89b403cf53 Mon Sep 17 00:00:00 2001 From: Mike Date: Sun, 12 Apr 2026 16:19:11 -0400 Subject: [PATCH 5/6] Changed install order and added more kubernetes tools --- .env.example | 32 +++-- Dockerfile | 329 +++++++++++++++++++++++++++++++-------------------- README.md | 19 ++- 3 files changed, 236 insertions(+), 144 deletions(-) diff --git a/.env.example b/.env.example index d5f4c36..0636240 100755 --- a/.env.example +++ b/.env.example @@ -1,7 +1,7 @@ # ============================================================================= # DevOps Toolbox — Local Build Environment # ============================================================================= -# This file documents all ARG values available for local Docker builds. +# This file documents all values available for local Docker builds. # It is committed to the repository as a reference — it contains no secrets. # # USAGE: @@ -10,7 +10,7 @@ # 3. Build using: # # docker build \ -# $(grep -v '^#' .env | grep -v '^$' | sed 's/^/--build-arg /') \ +# $(grep -v '^#' .env | grep -v '^$' | sed 's/^/--build-/') \ # -t devops-toolbox:local . # # VERSION REFERENCE: @@ -23,19 +23,25 @@ # ============================================================================= # Cloud cli tools -ARG AWS_CLI_VERSION=2.34.28 -ARG AZURE_CLI_VERSION=2.85.0 -ARG GCLOUD_VERSION=564.0.0 -ARG GH_VERSION=2.89.0 +AWS_CLI_VERSION=2.34.28 +AZURE_CLI_VERSION=2.85.0 +GCLOUD_VERSION=564.0.0 +GH_VERSION=2.89.0 -# Containerization tools -ARG K9S_VERSION=v0.50.18 -ARG KUBECTL_VERSION=v1.35.3 +# Kubernetes tools +K9S_VERSION=v0.50.18 +KUBECTL_VERSION=v1.35.3 +# The kubeseal version specifically does NOT have the v prefix +KUBESEAL_VERSION=0.36.6 +HELM_VERSION=v4.1.4 +KUBELOGIN_VERSION=v0.2.17 +KUSTOMIZE_VERSION=v5.8.1 +STERN_VERSION=v1.33.1 # Infrastructure as code tools -ARG ANSIBLE_VERSION=13.5.0 -ARG TERRAFORM_VERSION=1.14.8 +ANSIBLE_VERSION=13.5.0 +TERRAFORM_VERSION=1.14.8 # Programming languages -ARG DOTNET_VERSION=10.0.201 -ARG PYTHON_VERSION=3.12 +DOTNET_VERSION=10.0.201 +PYTHON_VERSION=3.12 diff --git a/Dockerfile b/Dockerfile index b2e8f07..f13341a 100755 --- a/Dockerfile +++ b/Dockerfile @@ -21,30 +21,11 @@ ARG TARGETARCH # ----------------------------------------------------------------------------- # Tool version pins -# All versions are declared here for visibility and ease of updating. -# To override during a local build: -# docker build --build-arg TERRAFORM_VERSION=1.10.0 -t devops-toolbox . +# Tool versions are pinned in their respective install section to cut down on +# the amount of layer rebuilds when updating a tool. # ----------------------------------------------------------------------------- -# Cloud cli tools -ARG AWS_CLI_VERSION=2.34.28 -ARG AZURE_CLI_VERSION=2.85.0 -ARG GCLOUD_VERSION=564.0.0 -ARG GH_VERSION=2.89.0 - -# Containerization tools -ARG K9S_VERSION=v0.50.18 -ARG KUBECTL_VERSION=v1.35.3 -# The kubeseal version specifically does NOT have the v prefix -ARG KUBESEAL_VERSION=0.36.6 - -# Infrastructure as code tools -ARG ANSIBLE_VERSION=13.5.0 -ARG TERRAFORM_VERSION=1.14.8 - -# Programming languages -ARG DOTNET_VERSION=10.0.201 -ARG PYTHON_VERSION=3.12 +# Python version is in the System Packages section below # ----------------------------------------------------------------------------- # System packages @@ -54,6 +35,8 @@ ARG PYTHON_VERSION=3.12 # Prevent interactive prompts during apt operations ENV DEBIAN_FRONTEND=noninteractive +ARG PYTHON_VERSION=3.12 + RUN apt-get update && apt-get install -y --no-install-recommends \ # Core utilities unzip \ @@ -78,6 +61,12 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ bash-completion \ && rm -rf /var/lib/apt/lists/* +# Ensure pipx binaries are on PATH for all subsequent RUN steps and terminals +ENV PATH="/root/.local/bin:/home/vscode/.local/bin:${PATH}" +ENV PIPX_HOME="/usr/local/pipx" +ENV PIPX_BIN_DIR="/usr/local/bin" + + # ----------------------------------------------------------------------------- # .NET SDK # Installed via Microsoft's official install script rather than the Ubuntu apt @@ -89,7 +78,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ # # DOTNET_INSTALL_DIR: Install to /usr/local/dotnet so the SDK is accessible # to all users, not just the user that ran the install script. -# ----------------------------------------------------------------------------- +# -----------------------------------------------------------------------------\ +ARG DOTNET_VERSION=10.0.201 + ENV DOTNET_INSTALL_DIR="/usr/local/dotnet" ENV PATH="${DOTNET_INSTALL_DIR}:${PATH}" RUN curl -fsSL https://dot.net/v1/dotnet-install.sh -o /tmp/dotnet-install.sh \ @@ -105,10 +96,29 @@ RUN curl -fsSL https://dot.net/v1/dotnet-install.sh -o /tmp/dotnet-install.sh \ ENV DOTNET_CLI_TELEMETRY_OPTOUT=1 ENV DOTNET_NOLOGO=1 -# Ensure pipx binaries are on PATH for all subsequent RUN steps and terminals -ENV PATH="/root/.local/bin:/home/vscode/.local/bin:${PATH}" -ENV PIPX_HOME="/usr/local/pipx" -ENV PIPX_BIN_DIR="/usr/local/bin" +# ----------------------------------------------------------------------------- +# gcloud CLI (Google Cloud SDK) +# Installed via Google's versioned archive for exact version pinning. +# gcloud uses x86_64/arm naming — does NOT match TARGETARCH directly. +# Remapped inline: amd64 -> x86_64, arm64 -> arm. +# ----------------------------------------------------------------------------- +ARG GCLOUD_VERSION=564.0.0 + +ENV CLOUDSDK_ROOT_DIR="/usr/local/google-cloud-sdk" +RUN GCLOUD_ARCH=$([ "${TARGETARCH}" = "arm64" ] && echo "arm" || echo "x86_64") \ + && curl -fsSL \ + "https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-cli-${GCLOUD_VERSION}-linux-${GCLOUD_ARCH}.tar.gz" \ + -o /tmp/google-cloud-sdk.tar.gz \ + && tar -xzf /tmp/google-cloud-sdk.tar.gz -C /usr/local \ + && rm /tmp/google-cloud-sdk.tar.gz \ + && ${CLOUDSDK_ROOT_DIR}/install.sh \ + --quiet \ + --usage-reporting=false \ + --path-update=false \ + --bash-completion=false \ + && ${CLOUDSDK_ROOT_DIR}/bin/gcloud version +ENV PATH="${CLOUDSDK_ROOT_DIR}/bin:${PATH}" +ENV CLOUDSDK_CORE_DISABLE_PROMPTS=1 # ----------------------------------------------------------------------------- # Terraform @@ -116,6 +126,8 @@ ENV PIPX_BIN_DIR="/usr/local/bin" # to an exact patch version rather than relying on repo availability. # URL: https://developer.hashicorp.com/terraform # ----------------------------------------------------------------------------- +ARG TERRAFORM_VERSION=1.14.8 + RUN curl -fsSL \ "https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_${TARGETARCH}.zip" \ -o /tmp/terraform.zip \ @@ -125,54 +137,20 @@ RUN curl -fsSL \ && terraform version # ----------------------------------------------------------------------------- -# kubectl -# Installed via official Kubernetes binary release for exact version pinning. -# URL: https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/ +# GitHub CLI (gh) +# Installed via official GitHub binary release — single static binary. +# gh uses amd64/arm64 naming — maps directly from TARGETARCH. # ----------------------------------------------------------------------------- -RUN curl -fsSL \ - "https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/${TARGETARCH}/kubectl" \ - -o /usr/local/bin/kubectl \ - && chmod +x /usr/local/bin/kubectl \ - && kubectl version --client +ARG GH_VERSION=2.89.0 -# ----------------------------------------------------------------------------- -# k9s -# Terminal UI for Kubernetes cluster management. Installed via GitHub release -# binary — no official apt package exists. Pinned for the same reproducibility -# reasons as all other binary tools in this image. -# URL: https://github.com/derailed/k9s -# ----------------------------------------------------------------------------- RUN curl -fsSL \ - "https://github.com/derailed/k9s/releases/download/${K9S_VERSION}/k9s_Linux_${TARGETARCH}.tar.gz" \ - -o /tmp/k9s.tar.gz \ - && tar -xzf /tmp/k9s.tar.gz -C /usr/local/bin k9s \ - && rm /tmp/k9s.tar.gz \ - && chmod +x /usr/local/bin/k9s \ - && k9s version - -# ----------------------------------------------------------------------------- -# kubeseal -# Tool used to manage SealedSecrets in a Kubernetes cluster. Installed via -# GitHub release binary — no official apt package exists. -# URL: https://github.com/bitnami-labs/sealed-secrets -# ----------------------------------------------------------------------------- - -RUN curl -OL "https://github.com/bitnami-labs/sealed-secrets/releases/download/v${KUBESEAL_VERSION}/kubeseal-${KUBESEAL_VERSION}-linux-${TARGETARCH}.tar.gz" \ - && tar -xvzf kubeseal-${KUBESEAL_VERSION}-linux-${TARGETARCH}.tar.gz kubeseal \ - && install -m 755 kubeseal /usr/local/bin/kubeseal \ - && rm kubeseal \ - && rm kubeseal-${KUBESEAL_VERSION}-linux-${TARGETARCH}.tar.gz - -# ----------------------------------------------------------------------------- -# Python development tooling -# Installed into the base Python environment so they are available for -# general Python development work independent of Ansible. -# ----------------------------------------------------------------------------- -COPY dependencies/python-dev-requirements.txt /tmp/python-dev-requirements.txt -RUN grep -v '^\s*#' /tmp/python-dev-requirements.txt \ - | grep -v '^\s*$' \ - | xargs -I {} pipx install {} \ - && rm /tmp/python-dev-requirements.txt + "https://github.com/cli/cli/releases/download/v${GH_VERSION}/gh_${GH_VERSION}_linux_${TARGETARCH}.tar.gz" \ + -o /tmp/gh.tar.gz \ + && tar -xzf /tmp/gh.tar.gz -C /tmp \ + && mv /tmp/gh_${GH_VERSION}_linux_${TARGETARCH}/bin/gh /usr/local/bin/gh \ + && rm -rf /tmp/gh.tar.gz /tmp/gh_${GH_VERSION}_linux_${TARGETARCH} \ + && chmod +x /usr/local/bin/gh \ + && gh version # ----------------------------------------------------------------------------- # Ansible @@ -181,18 +159,9 @@ RUN grep -v '^\s*#' /tmp/python-dev-requirements.txt \ # PIPX_HOME/PIPX_BIN_DIR are set above so binaries land in /usr/local/bin, # making them available to all users including the non-root 'vscode' user. # ----------------------------------------------------------------------------- -RUN pipx install --include-deps ansible==${ANSIBLE_VERSION} +ARG ANSIBLE_VERSION=13.5.0 -# ----------------------------------------------------------------------------- -# Python toolbox packages for Ansible -# Injected into Ansible's pipx virtualenv so Ansible modules (e.g. cloud -# inventory plugins, k8s module) can import them directly. -# See dependencies/python-requirements.txt for the full list and rationale. -# ----------------------------------------------------------------------------- -COPY dependencies/python-ansible-requirements.txt /tmp/python-ansible-requirements.txt -RUN pipx inject ansible \ - $(grep -v '^\s*#' /tmp/python-ansible-requirements.txt | grep -v '^\s*$' | tr '\n' ' ') \ - && rm /tmp/python-ansible-requirements.txt +RUN pipx install --include-deps ansible==${ANSIBLE_VERSION} # ----------------------------------------------------------------------------- # Ansible Galaxy collections @@ -207,7 +176,7 @@ RUN ansible-galaxy collection install \ && rm /tmp/ansible-requirements.yml # ----------------------------------------------------------------------------- -# Azure collection Python dependencies +# Azure Ansible collection Python dependencies # The azure.azcollection ships its own requirements file inside the installed # collection directory. These must be installed separately after the collection # is installed — they cannot be pre-listed in python-ansible-requirements.txt @@ -217,6 +186,17 @@ RUN ansible-galaxy collection install \ RUN pipx runpip ansible install \ -r /usr/local/pipx/venvs/ansible/lib/python${PYTHON_VERSION}/site-packages/ansible_collections/azure/azcollection/requirements.txt +# ----------------------------------------------------------------------------- +# Python toolbox packages for Ansible +# Injected into Ansible's pipx virtualenv so Ansible modules (e.g. cloud +# inventory plugins, k8s module) can import them directly. +# See dependencies/python-requirements.txt for the full list and rationale. +# ----------------------------------------------------------------------------- +COPY dependencies/python-ansible-requirements.txt /tmp/python-ansible-requirements.txt +RUN pipx inject ansible \ + $(grep -v '^\s*#' /tmp/python-ansible-requirements.txt | grep -v '^\s*$' | tr '\n' ' ') \ + && rm /tmp/python-ansible-requirements.txt + # ----------------------------------------------------------------------------- # Azure CLI # Installed via Microsoft's official apt repository rather than a raw binary. @@ -227,6 +207,8 @@ RUN pipx runpip ansible install \ # # Telemetry is disabled via environment variable at the end of this block. # ----------------------------------------------------------------------------- +ARG AZURE_CLI_VERSION=2.85.0 + RUN curl -fsSL https://packages.microsoft.com/keys/microsoft.asc \ | gpg --dearmor \ | tee /etc/apt/keyrings/microsoft.gpg > /dev/null \ @@ -241,48 +223,14 @@ RUN curl -fsSL https://packages.microsoft.com/keys/microsoft.asc \ && az version ENV AZURE_CORE_COLLECT_TELEMETRY=false -# ----------------------------------------------------------------------------- -# gcloud CLI (Google Cloud SDK) -# Installed via Google's versioned archive for exact version pinning. -# gcloud uses x86_64/arm naming — does NOT match TARGETARCH directly. -# Remapped inline: amd64 -> x86_64, arm64 -> arm. -# ----------------------------------------------------------------------------- -ENV CLOUDSDK_ROOT_DIR="/usr/local/google-cloud-sdk" -RUN GCLOUD_ARCH=$([ "${TARGETARCH}" = "arm64" ] && echo "arm" || echo "x86_64") \ - && curl -fsSL \ - "https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-cli-${GCLOUD_VERSION}-linux-${GCLOUD_ARCH}.tar.gz" \ - -o /tmp/google-cloud-sdk.tar.gz \ - && tar -xzf /tmp/google-cloud-sdk.tar.gz -C /usr/local \ - && rm /tmp/google-cloud-sdk.tar.gz \ - && ${CLOUDSDK_ROOT_DIR}/install.sh \ - --quiet \ - --usage-reporting=false \ - --path-update=false \ - --bash-completion=false \ - && ${CLOUDSDK_ROOT_DIR}/bin/gcloud version -ENV PATH="${CLOUDSDK_ROOT_DIR}/bin:${PATH}" -ENV CLOUDSDK_CORE_DISABLE_PROMPTS=1 - -# ----------------------------------------------------------------------------- -# GitHub CLI (gh) -# Installed via official GitHub binary release — single static binary. -# gh uses amd64/arm64 naming — maps directly from TARGETARCH. -# ----------------------------------------------------------------------------- -RUN curl -fsSL \ - "https://github.com/cli/cli/releases/download/v${GH_VERSION}/gh_${GH_VERSION}_linux_${TARGETARCH}.tar.gz" \ - -o /tmp/gh.tar.gz \ - && tar -xzf /tmp/gh.tar.gz -C /tmp \ - && mv /tmp/gh_${GH_VERSION}_linux_${TARGETARCH}/bin/gh /usr/local/bin/gh \ - && rm -rf /tmp/gh.tar.gz /tmp/gh_${GH_VERSION}_linux_${TARGETARCH} \ - && chmod +x /usr/local/bin/gh \ - && gh version - # ----------------------------------------------------------------------------- # AWS CLI v2 # Installed via AWS's official versioned zip installer. # AWS CLI uses x86_64/aarch64 naming — does NOT match TARGETARCH directly. # Remapped inline: amd64 -> x86_64, arm64 -> aarch64. # ----------------------------------------------------------------------------- +ARG AWS_CLI_VERSION=2.34.28 + RUN AWS_ARCH=$([ "${TARGETARCH}" = "arm64" ] && echo "aarch64" || echo "x86_64") \ && curl -fsSL \ "https://awscli.amazonaws.com/awscli-exe-linux-${AWS_ARCH}-${AWS_CLI_VERSION}.zip" \ @@ -294,6 +242,131 @@ RUN AWS_ARCH=$([ "${TARGETARCH}" = "arm64" ] && echo "aarch64" || echo "x86_64") && rm -rf /tmp/awscliv2.zip /tmp/aws \ && aws --version +# ----------------------------------------------------------------------------- +# kubectl +# Installed via official Kubernetes binary release for exact version pinning. +# URL: https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/ +# ----------------------------------------------------------------------------- +ARG KUBECTL_VERSION=v1.35.3 + +RUN curl -fsSL \ + "https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/${TARGETARCH}/kubectl" \ + -o /usr/local/bin/kubectl \ + && chmod +x /usr/local/bin/kubectl \ + && kubectl version --client + +# ----------------------------------------------------------------------------- +# k9s +# Terminal UI for Kubernetes cluster management. Installed via GitHub release +# binary — no official apt package exists. Pinned for the same reproducibility +# reasons as all other binary tools in this image. +# URL: https://github.com/derailed/k9s +# ----------------------------------------------------------------------------- +ARG K9S_VERSION=v0.50.18 + +RUN curl -fsSL \ + "https://github.com/derailed/k9s/releases/download/${K9S_VERSION}/k9s_Linux_${TARGETARCH}.tar.gz" \ + -o /tmp/k9s.tar.gz \ + && tar -xzf /tmp/k9s.tar.gz -C /usr/local/bin k9s \ + && rm /tmp/k9s.tar.gz \ + && chmod +x /usr/local/bin/k9s \ + && k9s version + +# ----------------------------------------------------------------------------- +# kubeseal +# Tool used to manage SealedSecrets in a Kubernetes cluster. Installed via +# GitHub release binary — no official apt package exists. +# URL: https://github.com/bitnami-labs/sealed-secrets +# ----------------------------------------------------------------------------- +# The kubeseal version specifically does NOT have the v prefix +ARG KUBESEAL_VERSION=0.36.6 + +RUN curl -OL "https://github.com/bitnami-labs/sealed-secrets/releases/download/v${KUBESEAL_VERSION}/kubeseal-${KUBESEAL_VERSION}-linux-${TARGETARCH}.tar.gz" \ + && tar -xvzf kubeseal-${KUBESEAL_VERSION}-linux-${TARGETARCH}.tar.gz kubeseal \ + && install -m 755 kubeseal /usr/local/bin/kubeseal \ + && rm kubeseal \ + && rm kubeseal-${KUBESEAL_VERSION}-linux-${TARGETARCH}.tar.gz + +# ----------------------------------------------------------------------------- +# Helm +# Package manager for Kubernetes. +# Helm uses amd64/arm64 naming — maps directly from TARGETARCH. +# ----------------------------------------------------------------------------- +ARG HELM_VERSION=v4.1.4 + +RUN curl -fsSL \ + "https://get.helm.sh/helm-${HELM_VERSION}-linux-${TARGETARCH}.tar.gz" \ + -o /tmp/helm.tar.gz \ + && tar -xzf /tmp/helm.tar.gz -C /tmp \ + && mv /tmp/linux-${TARGETARCH}/helm /usr/local/bin/helm \ + && rm -rf /tmp/helm.tar.gz /tmp/linux-${TARGETARCH} \ + && chmod +x /usr/local/bin/helm \ + && helm version + +# ----------------------------------------------------------------------------- +# kubelogin (Azure/kubelogin) +# Kubernetes credential plugin implementing Azure AD authentication. +# Required for authenticating kubectl against AKS clusters using Azure AD / +# OIDC. Note: this is Azure/kubelogin, not int128/kubelogin (which is a +# general OIDC plugin). Uses amd64/arm64 naming — maps directly from TARGETARCH. +# ----------------------------------------------------------------------------- +ARG KUBELOGIN_VERSION=v0.2.17 + +RUN curl -fsSL \ + "https://github.com/Azure/kubelogin/releases/download/${KUBELOGIN_VERSION}/kubelogin-linux-${TARGETARCH}.zip" \ + -o /tmp/kubelogin.zip \ + && unzip /tmp/kubelogin.zip -d /tmp/kubelogin \ + && mv /tmp/kubelogin/bin/linux_${TARGETARCH}/kubelogin /usr/local/bin/kubelogin \ + && rm -rf /tmp/kubelogin.zip /tmp/kubelogin \ + && chmod +x /usr/local/bin/kubelogin \ + && kubelogin --version + +# ----------------------------------------------------------------------------- +# Kustomize +# Template-free Kubernetes configuration management. Installed as a standalone +# binary to get a newer version than the one bundled inside kubectl, which +# lags behind. Used natively by ArgoCD alongside Helm. +# Kustomize uses amd64/arm64 naming — maps directly from TARGETARCH. +# ----------------------------------------------------------------------------- +ARG KUSTOMIZE_VERSION=v5.8.1 + +RUN curl -fsSL \ + "https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize%2F${KUSTOMIZE_VERSION}/kustomize_${KUSTOMIZE_VERSION}_linux_${TARGETARCH}.tar.gz" \ + -o /tmp/kustomize.tar.gz \ + && tar -xzf /tmp/kustomize.tar.gz -C /usr/local/bin kustomize \ + && rm /tmp/kustomize.tar.gz \ + && chmod +x /usr/local/bin/kustomize \ + && kustomize version + +# ----------------------------------------------------------------------------- +# Stern +# Multi-pod and container log tailing for Kubernetes. Significantly better +# than 'kubectl logs' for watching logs across multiple pods simultaneously +# during troubleshooting. Supports regex pod/container filtering. +# Stern uses amd64/arm64 naming — maps directly from TARGETARCH. +# ----------------------------------------------------------------------------- +# The stern version specifically does NOT have the v prefix +ARG STERN_VERSION=1.33.1 + +RUN curl -fsSL \ + "https://github.com/stern/stern/releases/download/v${STERN_VERSION}/stern_${STERN_VERSION}_linux_${TARGETARCH}.tar.gz" \ + -o /tmp/stern.tar.gz \ + && tar -xzf /tmp/stern.tar.gz -C /usr/local/bin stern \ + && rm /tmp/stern.tar.gz \ + && chmod +x /usr/local/bin/stern \ + && stern --version + +# ----------------------------------------------------------------------------- +# Python development tooling +# Installed into the base Python environment so they are available for +# general Python development work independent of Ansible. +# ----------------------------------------------------------------------------- +COPY dependencies/python-dev-requirements.txt /tmp/python-dev-requirements.txt +RUN grep -v '^\s*#' /tmp/python-dev-requirements.txt \ + | grep -v '^\s*$' \ + | xargs -I {} pipx install {} \ + && rm /tmp/python-dev-requirements.txt + # ----------------------------------------------------------------------------- # Shell completions # Written to the system-wide completions directory so they are available to @@ -350,14 +423,14 @@ RUN aws_completer_path=$(which aws_completer) \ RUN echo '\n# Load bash completions\nif [ -f /usr/share/bash-completion/bash_completion ]; then\n . /usr/share/bash-completion/bash_completion\nfi' \ >> /etc/bash.bashrc -# ----------------------------------------------------------------------------- -# Shell completion loading -# Ensures bash-completion is sourced for all interactive shell sessions. -# The completion scripts in /etc/bash_completion.d/ are only automatically -# loaded if the bash-completion package is explicitly sourced at shell startup. -# ----------------------------------------------------------------------------- -RUN echo '\n# Load bash completions\nif [ -f /usr/share/bash-completion/bash_completion ]; then\n . /usr/share/bash-completion/bash_completion\nfi' \ ->> /etc/bash.bashrc +# Shell completions — Helm +RUN helm completion bash > /etc/bash_completion.d/helm + +# Shell completions — Kustomize +RUN kustomize completion bash > /etc/bash_completion.d/kustomize + +# Shell completions — Stern +RUN stern --completion bash > /etc/bash_completion.d/stern # ----------------------------------------------------------------------------- # Final ownership and user setup diff --git a/README.md b/README.md index 39a0055..21bb393 100755 --- a/README.md +++ b/README.md @@ -17,6 +17,10 @@ with Docker and VS Code — no local setup required. | [kubectl](https://kubernetes.io/docs/reference/kubectl/) | See [Dockerfile](./Dockerfile) | Kubernetes cluster management | | [k9s](https://k9scli.io) | See [Dockerfile](./Dockerfile) | Kubernetes terminal UI | | [kubeseal](https://github.com/bitnami-labs/sealed-secrets) | See [Dockerfile](./Dockerfile) | Kubernetes SealedSecrets CLI | +| [Helm](https://helm.sh) | See [Dockerfile](./Dockerfile) | Kubernetes package manager | +| [kubelogin](https://azure.github.io/kubelogin/) | See [Dockerfile](./Dockerfile) | Azure AD authentication for kubectl | +| [Kustomize](https://kustomize.io) | See [Dockerfile](./Dockerfile) | Kubernetes configuration management | +| [Stern](https://github.com/stern/stern) | See [Dockerfile](./Dockerfile) | Multi-pod log tailing | | [Ansible](https://www.ansible.com) | See [Dockerfile](./Dockerfile) | Configuration management and automation | | [.NET SDK](https://dotnet.microsoft.com) | See [Dockerfile](./Dockerfile) | .NET development | | [Python](https://www.python.org) | See [Dockerfile](./Dockerfile) | Scripting and development | @@ -172,14 +176,23 @@ the most recent base image security patches, even without a code change. ## Updating Tool Versions -All tool versions are pinned as `ARG` declarations at the top of the -[Dockerfile](./Dockerfile). To update a tool: +Tool versions are pinned as `ARG` declarations directly above each tool's +install block in the [Dockerfile](./Dockerfile), rather than grouped at the +top of the file. This is intentional — it ensures that changing one tool's +version only invalidates the Docker layer cache from that tool downward, +leaving unrelated tools fully cached. -1. Update the relevant `ARG` value in the Dockerfile +1. Find the tool's `ARG` declaration in the Dockerfile — it will be + immediately above its install block, with a comment header identifying + the tool 2. Update the matching entry in [`.env.example`](./.env.example) 3. Open a pull request — the pipeline will build and validate the image 4. Merge and tag a new release (ex. `v1.1.0`) to publish semver tags +To find a tool's current version quickly without reading the full Dockerfile, +check [`.env.example`](./.env.example) — it mirrors all version pins and +includes links to each tool's release page. + --- ## Local Builds From 882fa4f127615df455635523abe7255a417968d2 Mon Sep 17 00:00:00 2001 From: Mike Date: Sun, 12 Apr 2026 16:39:51 -0400 Subject: [PATCH 6/6] Updated README with WSL settings. Fixes #2 --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 21bb393..cb49e81 100755 --- a/README.md +++ b/README.md @@ -102,6 +102,12 @@ Or use environment variables in `devcontainer.json`: Add the [Dev Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) extension from Microsoft to VS Code. +**NOTE:** If you're running this in WSL through VS Code, you should change these settings: +``` +Enable Dev › Containers: Execute In WSL +Enable Dev › Containers: Forward WSL Services if you use things like X, Wayland, or SSH Agents such as Bitwarden +``` + Then, add a `.devcontainer/devcontainer.json` to your project repository with the. VS Code will detect it automatically and offer to reopen the project inside the container. **NOTE:** This is just a quick example. For the latest, fully detailed version of the sample, please see [the devcontainer.json in source control](./.devcontainer/example/devcontainer.json)