Files
Bagas Purwa Sentika d727c4dbce docs(09): create phase plan — custom Docker image + portable setup script
Phase 9 splits into two independent Wave 1 plans:
- 09-01: Custom Hermes Docker image (ngn-agent:latest) with aws-cli,
  terraform, helm, kubectl, and datadog CLI (pup), version-pinned
- 09-02: Portable setup-ngn-agent.sh with argument parsing,
  prerequisite checks, interactive secret prompts, config generation,
  skill/script embedding, and cron registration

Also marks Phase 8 as complete (cron reporting shipped 2026-06-15).
2026-06-15 23:13:35 +08:00

11 KiB

phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, must_haves
phase plan type wave depends_on files_modified autonomous requirements must_haves
09-tooling-portable-setup 01 execute 1
ngn-agent/docker/Dockerfile
ngn-agent/docker/build.sh
true
TOOL-01
truths artifacts key_links
Custom Docker image can be built with a single command (docker/build.sh)
Built image includes aws-cli v2, terraform, helm, kubectl, and datadog CLI (pup)
Image is tagged ngn-agent:latest (local only, no registry push)
Each tool version is pinned for reproducibility
Build uses Dockerfile from the project repo (ngn-agent/docker/Dockerfile)
path provides min_lines
ngn-agent/docker/Dockerfile Custom Hermes-compatible Docker image definition with 5 platform tools 80
path provides min_lines
ngn-agent/docker/build.sh Single-command image build entry point 15
from to via pattern
ngn-agent/docker/build.sh ngn-agent/docker/Dockerfile docker build -f docker build.*-f.*Dockerfile
from to via pattern
Dockerfile aws-cli v2 curl → unzip → aws/install awscli.amazonaws.com/awscli-exe
from to via pattern
Dockerfile terraform HashiCorp apt repo apt.releases.hashicorp.com
from to via pattern
Dockerfile helm Buildkite apt repo packages.buildkite.com/helm
from to via pattern
Dockerfile kubectl Google Kubernetes apt repo pkgs.k8s.io
from to via pattern
Dockerfile pup (Datadog CLI) GitHub releases binary download github.com/DataDog/pup/releases
**Custom Hermes Docker Image with Platform Engineering Tools**

Create a custom Docker image extending nikolaik/python-nodejs:python3.11-nodejs20 with five platform engineering CLI tools pre-installed: AWS CLI v2, Terraform, Helm, kubectl, and Datadog CLI (pup). The image is buildable with a single docker/build.sh command and tagged ngn-agent:latest for local use.

Purpose: Eliminate per-session tool installation overhead — tools are baked into the Docker image so every Hermes session has immediate access to aws-cli, terraform, helm, kubectl, and pup without runtime installs.

Output:

  • ngn-agent/docker/Dockerfile — Version-pinned tool installations on top of the base Hermes image
  • ngn-agent/docker/build.sh — Single-command build entry point

<execution_context> @/Users/bapung/.config/opencode/gsd-core/workflows/execute-plan.md @/Users/bapung/.config/opencode/gsd-core/templates/summary.md </execution_context>

@.planning/ROADMAP.md @.planning/phases/09-tooling-portable-setup/09-CONTEXT.md @.planning/phases/09-tooling-portable-setup/09-RESEARCH.md Task 1: Create Dockerfile with version-pinned tool installations ngn-agent/docker/Dockerfile Create `ngn-agent/docker/Dockerfile` that:
1. **FROM** extends `nikolaik/python-nodejs:python3.11-nodejs20` (per D-01). Add a comment above FROM noting: "D-01: Base image tag python3.11-nodejs20 — verify availability at build time; if manifest not found, update to python3.11-nodejs22-bookworm (Node.js 20 EOL April 2026)."

2. **LABEL** with `description="ngn-agent: Custom Hermes Docker image with platform engineering tools"` and `maintainer="ngn-agent"`.

3. **ARGs for version pinning** (per D-02):
   - `TERRAFORM_VERSION=1.15.6`
   - `HELM_VERSION=4.2.1`
   - `KUBECTL_VERSION=1.36.1`
   - `PUPP_VERSION=1.1.0`
   (AWS CLI v2 is the latest stable — per D-03, install without version pinning but pin to latest known at time of build.)

4. **Install system dependencies** in a single RUN:
   `curl`, `ca-certificates`, `unzip`, `gnupg`, `wget` — clean apt lists after install.

5. **Install AWS CLI v2** (per D-03):
   Use the official curl → unzip → `./aws/install` method (no apt repo for v2). Install to `/usr/local/bin` and `/usr/local/aws-cli`. Clean up zip and extracted files. Reference D-03 in a comment.

6. **Install Terraform** (per D-03):
   Add HashiCorp GPG key, add HashiCorp apt repo, `apt-get install -y terraform=${TERRAFORM_VERSION}`. Clean apt lists. Reference D-03.

7. **Install kubectl** (per D-03):
   Add Google Kubernetes GPG key, add kubernetes apt repo for v1.36, `apt-get install -y kubectl`. Do NOT version-pin kubectl (it must match the target cluster version — per D-03: "latest stable matching cluster version"). Clean apt lists. Reference D-03.

8. **Install Helm** (per D-03):
   Add Buildkite GPG key, add Helm apt repo, `apt-get install -y helm=${HELM_VERSION}`. Clean apt lists. Reference D-03.

9. **Install Datadog CLI (pup)** (per D-03):
   Download the Linux x86_64 tarball from GitHub Releases, extract `pup` binary to `/usr/local/bin/`, clean up. Reference D-03.

10. **Verify step**: Single RUN with `echo "=== Tool versions ===" && aws --version && terraform --version && helm version --short && kubectl version --client --output=yaml 2>/dev/null | grep gitVersion && pup --version`. Use `|| true` on version checks that may exit non-zero so build doesn't fail on a single tool being unreachable.

11. **CMD** `["bash"]` — matching base image behavior.

**Build hygiene:**
- Do NOT `COPY .` or any full-directory copy — this prevents leaking secrets into image layers (T-09-02 mitigation).
- Order tool installs from most-frequently-changed to least-changed to optimize layer caching.
- Use `--no-install-recommends` on all apt-get install commands.
- Remove apt lists after each apt install to keep image small.
- All tool downloads use HTTPS URLs (T-09-01 mitigation).
- Add inline comments referencing each D-NN decision for traceability.
test -f /Users/bapung/Razer/ngn-agent/docker/Dockerfile && wc -l /Users/bapung/Razer/ngn-agent/docker/Dockerfile - Dockerfile exists at ngn-agent/docker/Dockerfile - All 5 tools (aws-cli, terraform, helm, kubectl, pup) are installed via RUN commands - Tool versions are pinned via ARGs (except kubectl which matches cluster version) - D-01 through D-03 are referenced in comments - No `COPY .` or directory-wide copy present Task 2: Create build.sh and verify image builds successfully ngn-agent/docker/build.sh Create `ngn-agent/docker/build.sh` (per D-04):
1. Shebang: `#!/bin/bash` with `set -euo pipefail`.

2. Constants:
   - `IMAGE_NAME="ngn-agent"`
   - `IMAGE_TAG="latest"`
   - `DOCKER_DIR` resolved from script location: `"$(cd "$(dirname "$0")" && pwd)"`

3. Print build banner: `echo "==> Building ${IMAGE_NAME}:${IMAGE_TAG}..."`

4. `docker build` command:
   - `-t "${IMAGE_NAME}:${IMAGE_TAG}"`
   - `-f "${DOCKER_DIR}/Dockerfile"`
   - Build context: `"${DOCKER_DIR}"` (not the repo root — prevents leaking files)
   - Per D-05: tag is `ngn-agent:latest` (local only, no registry push)

5. Print completion banner: `echo "==> Build complete: ${IMAGE_NAME}:${IMAGE_TAG}"` followed by `docker images "${IMAGE_NAME}:${IMAGE_TAG}"`.

6. Make the script executable: `chmod +x /Users/bapung/Razer/ngn-agent/docker/build.sh`.

**Verify the build** by running `docker/build.sh` (or `bash docker/build.sh` if script path issues). If the base image tag `python3.11-nodejs20` fails with a manifest error, update the Dockerfile FROM line to `nikolaik/python-nodejs:python3.11-nodejs22-bookworm` as recommended by research, add a comment noting the change, and retry. After successful build:

- Run `docker run --rm ngn-agent:latest aws --version` — confirms aws-cli is installed and executable
- Run `docker run --rm ngn-agent:latest terraform --version` — confirms terraform works
- Run `docker run --rm ngn-agent:latest helm version --short` — confirms helm works
- Run `docker run --rm ngn-agent:latest kubectl version --client` — confirms kubectl works
- Run `docker run --rm ngn-agent:latest pup --version` — confirms pup works

If any tool fails in the container, fix the Dockerfile and rebuild. The image must have all 5 tools working.
docker run --rm ngn-agent:latest sh -c 'aws --version && terraform --version && helm version --short && kubectl version --client && pup --version' - build.sh exists and is executable - `ngn-agent:latest` image builds successfully - All 5 tools execute correctly inside the container - Build script references D-04 and D-05 decisions - If base image tag was updated to python3.11-nodejs22-bookworm due to deprecation, the FROM line is updated and a comment explains the change

<threat_model>

Trust Boundaries

Boundary Description
Docker build host → Docker daemon Docker context is read by build daemon
Docker build → external tool repos Tool downloads cross HTTPS boundaries
Docker image layers → local storage Built image stored on host filesystem

STRIDE Threat Register

Threat ID Category Component Disposition Mitigation Plan
T-09-01 Tampering Tool download MITM (curl/wget from S3, GitHub, apt repos) mitigate All downloads use HTTPS. apt repos use GPG key verification to sign packages.
T-09-02 Information Disclosure Build context leak (COPY . could send .env into Docker daemon) mitigate Build context is docker/ directory only — not repo root. Dockerfile does not COPY . anywhere.
T-09-03 Tampering Base image supply chain (nikolaik/python-nodejs) accept Widely used community image; no custom base image available.
T-09-04 Denial of Service Base image tag python3.11-nodejs20 may not exist mitigate Dockerfile comment flags potential deprecation. If build fails with manifest error, update to python3.11-nodejs22-bookworm.

Package Legitimacy Gate

Package Registry Verdict Disposition
(none) No npm/pip/cargo packages installed. All tools via apt or curl binary downloads.
</threat_model>
- Automated: `docker run --rm ngn-agent:latest sh -c 'aws --version && terraform --version && helm version --short && kubectl version --client && pup --version'` passes with all 5 tools - Manual: User can inspect `docker/images` output to confirm tag and creation date

<success_criteria>

  1. The image ngn-agent:latest exists in local Docker daemon
  2. Running docker run --rm ngn-agent:latest <tool> --version succeeds for all 5 tools
  3. docker/build.sh is the single entry point for rebuilding
  4. Both files are committed to the ngn-agent git repo
  5. Tool versions are pinned (ARGS in Dockerfile) for future reproducibility </success_criteria>