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:
@@ -60,6 +60,17 @@ I am the QWEN instance operating in the ToolboxStack component of the TSYSDevSta
|
|||||||
- **toolbox-template**: Template directory for creating new toolboxes
|
- **toolbox-template**: Template directory for creating new toolboxes
|
||||||
- **PROMPT files**: Guidance for AI collaboration in various components
|
- **PROMPT files**: Guidance for AI collaboration in various components
|
||||||
|
|
||||||
|
## Build and Release Workflow
|
||||||
|
- Default build workflow: `./build.sh` produces a `:dev` tag; `./release.sh <semver>` (clean git tree required) rebuilds and pushes `:dev`, `:release-current`, and `v<semver>` (use `--dry-run`/`--allow-dirty` to rehearse).
|
||||||
|
- Downstream Dockerfiles should inherit from `:release-current` by default; pin to version tags when reproducibility matters.
|
||||||
|
|
||||||
|
## Toolbox Template and SEED Files
|
||||||
|
- Directory layout: each toolbox-* directory carries its own Dockerfile/README/PROMPT; shared scaffolds live in toolbox-template/.devcontainer and docker-compose.yml.
|
||||||
|
- Use ./NewToolbox.sh <name> to scaffold a new toolbox-* directory from toolbox-template.
|
||||||
|
- Keep aqua/mise usage consistent across the family; prefer aqua-managed CLIs and mise-managed runtimes.
|
||||||
|
- Reference toolbox-template when bootstrapping a new toolbox. Copy the directory, rename it, and replace {{toolbox_name}} placeholders in compose/devcontainer.
|
||||||
|
- Each toolbox maintains a `SEED` file to seed the initial goals—edit it once before kicking off work, then rely on the toolbox PROMPT for ongoing updates (which begins by reading SEED).
|
||||||
|
|
||||||
## My Responsibilities
|
## My Responsibilities
|
||||||
- Maintain and enhance the ToolboxStack component
|
- Maintain and enhance the ToolboxStack component
|
||||||
- Assist with creating new toolboxes from the template using NewToolbox.sh
|
- Assist with creating new toolboxes from the template using NewToolbox.sh
|
||||||
@@ -170,3 +181,72 @@ For detailed information about previous work, challenges, and solutions, see:
|
|||||||
|
|
||||||
## Ready State
|
## Ready State
|
||||||
I am ready to proceed with any directed tasks. Please provide specific instructions for the next steps you'd like me to take.
|
I am ready to proceed with any directed tasks. Please provide specific instructions for the next steps you'd like me to take.
|
||||||
|
|
||||||
|
## Directory Structure Note
|
||||||
|
**IMPORTANT**: The filesystem structure has been recently updated. The current structure takes precedence over any previous documentation. Key changes:
|
||||||
|
- The original toolbox-template has been transformed into toolbox-qadocker
|
||||||
|
- The DocStack has been renamed to dockstack
|
||||||
|
- The NewToolbox.sh script has been removed
|
||||||
|
- Various PROMPT files have been updated across toolboxes
|
||||||
|
|
||||||
|
## Audit and Assessment Responsibilities
|
||||||
|
|
||||||
|
As part of my role in maintaining the ToolboxStack, I may conduct ongoing audits of the directory tree with the following focus areas:
|
||||||
|
|
||||||
|
- Docker build optimization
|
||||||
|
- Dockerfile correctness
|
||||||
|
- Build caching
|
||||||
|
- Security best practices
|
||||||
|
- Docker development environment best practices
|
||||||
|
- Best common practices for (dockerized) development/tooling stacks
|
||||||
|
- Assessment of all existing toolboxes (base, DocStack, QADocker, and any others)
|
||||||
|
|
||||||
|
### Audit Process
|
||||||
|
|
||||||
|
When conducting audits, I will produce:
|
||||||
|
|
||||||
|
- Human-readable reports to: `collab/audits/YYYY/MM/DD/HHMM/QAReport.md` (using local system time)
|
||||||
|
- LLM-optimized reports to: `collab/audits/YYYY/MM/DD/HHMM/QAReport.LLM` (using local system time)
|
||||||
|
|
||||||
|
The human-readable reports should use icons, headers, tables, graphics and be very beautiful and easy to digest.
|
||||||
|
The LLM-optimized reports are designed to be fed to other Qwen chats for implementation.
|
||||||
|
|
||||||
|
### Advisory Role
|
||||||
|
|
||||||
|
In addition to audits, I can provide advice on:
|
||||||
|
|
||||||
|
- Tools to add
|
||||||
|
- How to split up containers
|
||||||
|
- What needs to go into base toolbox vs specialized toolboxes
|
||||||
|
|
||||||
|
For advisory tasks, I will write:
|
||||||
|
- Human-readable reports to: `collab/advisor/YYYY/MM/DD/HHMM/AdvisorReport.md` (using local system time)
|
||||||
|
- LLM-optimized reports to: `collab/advisor/YYYY/MM/DD/HHMM/AdvisorReport.LLM` (using local system time)
|
||||||
|
|
||||||
|
### Enhanced Audit Process
|
||||||
|
|
||||||
|
The audit process now includes automated assessment of all existing toolboxes using the script at `collab/audit-all-toolboxes.sh`.
|
||||||
|
|
||||||
|
When performing an audit, this script will be run automatically to analyze all toolboxes in the system, and the results will be incorporated into both the human-readable and LLM-optimized reports.
|
||||||
|
|
||||||
|
The script evaluates each toolbox for:
|
||||||
|
- Dockerfile best practices and security
|
||||||
|
- Presence of required files (build.sh, run.sh, test.sh, etc.)
|
||||||
|
- Documentation completeness (README.md, PROMPT, SEED)
|
||||||
|
- Tool configuration (aqua.yaml, etc.)
|
||||||
|
|
||||||
|
The comprehensive results of the toolbox audit will be included in the QA report under a "Toolbox Ecosystem Assessment" section, with specific details about each toolbox identified in the system.
|
||||||
|
|
||||||
|
### Project Context
|
||||||
|
|
||||||
|
The projects span:
|
||||||
|
|
||||||
|
- Extensive documentation generation needs (PDFs, websites) of governance documents, reports, proposals, project plans, budgets etc.
|
||||||
|
- Software development (full SDLC) across: node, python, php, ruby, perl, java, rust, c and c++ (including embedded development, cross compiling),
|
||||||
|
nix (embedded systems builds for aeronautical applications where we need complete reproducibility), web application development, desktop GUI development etc
|
||||||
|
|
||||||
|
The ToolboxStack is for "inner loop" operations (edit/compile/test) only.
|
||||||
|
|
||||||
|
There are other stacks for:
|
||||||
|
- Build/packaging/release operations
|
||||||
|
- Support functions (like atuin/mailhog etc)
|
||||||
@@ -1,176 +0,0 @@
|
|||||||
# GEMINI-AUDIT-TOOLBOX-20251030-1309
|
|
||||||
|
|
||||||
## Audit Report: ToolboxStack Project
|
|
||||||
|
|
||||||
**Auditor:** G-Toolbox
|
|
||||||
**Date:** October 30, 2025, 13:09
|
|
||||||
|
|
||||||
This report details a comprehensive audit of the ToolboxStack project, focusing on adherence to best practices, efficiency, security, and overall code quality. The findings reveal a project riddled with fundamental flaws, inefficiencies, and a disregard for established development and security principles.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 1. `docker-compose.yml` (Both `output/toolbox-base/docker-compose.yml` and `output/toolbox-template/docker-compose.yml`)
|
|
||||||
|
|
||||||
**Issue:** Excessive duplication of volume mounts.
|
|
||||||
**Details:** Both `docker-compose.yml` files contain numerous identical volume mounts for AI CLI tool configurations and cache directories. This redundancy makes the files unnecessarily long, difficult to read, and prone to errors during maintenance.
|
|
||||||
**Impact:** Increased file size, reduced readability, higher maintenance burden.
|
|
||||||
**Recommendation:** Consolidate duplicate volume mounts. Utilize YAML anchors or a more programmatic approach if dynamic volume generation is required.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 2. `Dockerfile` (Both `output/toolbox-base/Dockerfile` and `output/toolbox-template/Dockerfile`)
|
|
||||||
|
|
||||||
**Issue:** Pervasive redundancy, inefficiency, and poor Dockerfile practices.
|
|
||||||
**Details:**
|
|
||||||
* **Redundant Installations:** `apt-get install` commands repeatedly install `ca-certificates` and `curl`. `mise` and `npm` packages are installed globally twice (once as root, once as the non-root user), as are `aqua` packages. This significantly inflates image size and build times.
|
|
||||||
* **Inefficient Layering:** The repeated use of `su - "${USERNAME}" -c '...'` for multiple commands creates numerous unnecessary Docker layers, further increasing image size and build complexity. A single `RUN` instruction executing a multi-command script would be far more efficient.
|
|
||||||
* **Bad Practices:**
|
|
||||||
* Global `npm` package installations (`-g`) are generally discouraged in Docker images. Local `node_modules` are preferred for better dependency management and conflict avoidance.
|
|
||||||
* The `userdel --remove` logic for user creation is a hack. Proper user management should involve checking for user existence and creating only if necessary, without resorting to potentially dangerous deletion.
|
|
||||||
* Error suppression (`2>/dev/null || true`) in `apt-get remove sudo` hides critical information.
|
|
||||||
* `starship` is installed from an unpinned script, introducing a risk of non-reproducible builds and unexpected changes.
|
|
||||||
* `BATS` installation is inefficient, involving a `git clone` followed by an `npm install` of the same tool.
|
|
||||||
* **Template Flaws:** The `toolbox-template/Dockerfile` redundantly creates the non-root user and removes `sudo`, despite inheriting from a base image that already handles these. This demonstrates a fundamental misunderstanding of Docker layering and inheritance.
|
|
||||||
**Impact:** Bloated image sizes, extended build times, reduced reproducibility, increased attack surface, potential security vulnerabilities, and a high maintenance burden.
|
|
||||||
**Recommendation:**
|
|
||||||
* Refactor `Dockerfile`s to use multi-stage builds.
|
|
||||||
* Consolidate `RUN` commands to minimize layers.
|
|
||||||
* Implement proper user management without `userdel` hacks.
|
|
||||||
* Pin all external script installations (e.g., `starship`).
|
|
||||||
* Streamline `BATS` installation.
|
|
||||||
* Remove redundant package installations.
|
|
||||||
* Ensure the template `Dockerfile` correctly leverages the base image without duplicating its setup.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 3. `build.sh` (Both `output/toolbox-base/build.sh` and `output/toolbox-template/build.sh`)
|
|
||||||
|
|
||||||
**Issue:** Lack of robustness, inefficiency, and security theater.
|
|
||||||
**Details:**
|
|
||||||
* **Lack of Error Handling:** Scripts lack robust error handling, failing to check the exit status of critical commands. This allows failures to propagate silently.
|
|
||||||
* **Inefficient Verification:** The `toolbox-template/build.sh` performs multiple `docker run` commands for tool verification. This is highly inefficient; a single `docker run` executing an internal script would be significantly faster.
|
|
||||||
* **Maintenance Burden:** Hardcoded tool lists in `toolbox-template/build.sh` necessitate manual updates whenever the `Dockerfile` changes.
|
|
||||||
* **Security Theater:** The `sanitized_input` function is a prime example of security theater. Its naive approach to preventing command injection is easily bypassed and provides a false sense of security.
|
|
||||||
**Impact:** Fragile build processes, slow execution, high maintenance overhead, and a false sense of security.
|
|
||||||
**Recommendation:**
|
|
||||||
* Implement comprehensive error handling (`set -euo pipefail` is a start, but explicit checks are needed).
|
|
||||||
* Refactor verification steps into a single `docker run` command.
|
|
||||||
* Dynamically generate tool lists or use a more robust configuration management approach.
|
|
||||||
* Remove the `sanitized_input` function; true command injection prevention requires proper argument handling, not string sanitization.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 4. `run.sh` (Both `output/toolbox-base/run.sh` and `output/toolbox-template/run.sh`)
|
|
||||||
|
|
||||||
**Issue:** Security theater, redundancy, inefficiency, and inflexibility.
|
|
||||||
**Details:**
|
|
||||||
* **Security Theater:** The `sanitized_input` function is present and ineffective, providing a false sense of security.
|
|
||||||
* **Redundant Actions:** Scripts redundantly create directories on the host that are already mounted as volumes in `docker-compose.yml`.
|
|
||||||
* **Dangerous Permissions:** `chmod 700` applied broadly to `.config`, `.local/share`, and `.cache` is overly aggressive and potentially destructive, with errors suppressed (`2>/dev/null || true`).
|
|
||||||
* **Inefficient Rebuilds:** `docker compose up --build` forces an inefficient rebuild of the image on every `up` command, even when no changes have occurred.
|
|
||||||
* **Inflexibility:** Hardcoded container names in `docker exec` commands limit adaptability.
|
|
||||||
**Impact:** False security, potential data loss, slow development cycles, and reduced flexibility.
|
|
||||||
**Recommendation:**
|
|
||||||
* Remove the `sanitized_input` function.
|
|
||||||
* Eliminate redundant directory creation.
|
|
||||||
* Remove the dangerous `chmod` command or apply it with extreme precision.
|
|
||||||
* Remove `--build` from `docker compose up`; `build.sh` should handle image building.
|
|
||||||
* Dynamically derive container names or use `docker compose exec` with service names.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 5. `release.sh` (`output/toolbox-base/release.sh`)
|
|
||||||
|
|
||||||
**Issue:** Critically incomplete release process and dangerous practices.
|
|
||||||
**Details:**
|
|
||||||
* **Incomplete Release:** The script builds and tags images locally but *fails to push* them to a remote registry. This renders the "release" process incomplete and useless for distribution or consumption by other systems.
|
|
||||||
* **Dangerous `--allow-dirty` Flag:** The `--allow-dirty` flag, while guarded, is a severe anti-pattern for a release script. A release must always originate from a clean, committed state to ensure reproducibility and integrity. Its presence encourages risky behavior.
|
|
||||||
* **Inherited Inefficiencies:** The script calls `build.sh`, inheriting all its inefficiencies and flaws.
|
|
||||||
**Impact:** Non-reproducible releases, inability to distribute images, compromised integrity, and a false sense of a completed release.
|
|
||||||
**Recommendation:**
|
|
||||||
* Implement robust `docker push` commands for all relevant tags.
|
|
||||||
* Remove the `--allow-dirty` flag entirely. A release should *always* require a clean git tree.
|
|
||||||
* Address the underlying inefficiencies in `build.sh`.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 6. `security-audit.sh` (Both `output/toolbox-base/security-audit.sh` and `output/toolbox-template/security-audit.sh`)
|
|
||||||
|
|
||||||
**Issue:** Superficial, inefficient, and misleading security audit.
|
|
||||||
**Details:**
|
|
||||||
* **False Sense of Security:** The script provides a very basic and incomplete security audit, giving a false sense of assurance. It misses many critical aspects of container security.
|
|
||||||
* **Inefficiency:** Each check executes a new `docker run --rm "${IMAGE_NAME}" ...`, which is extremely inefficient. A single `docker run` executing an internal script would be significantly faster.
|
|
||||||
* **Limited Scope:** Checks are basic and do not cover the full spectrum of container security, especially for `npm`, `mise`, or `aqua` managed tools. It fails to perform static analysis of the Dockerfile (e.g., with Hadolint, which is installed in the base image).
|
|
||||||
* **Error Hiding:** Excessive use of `2>/dev/null` suppresses potentially valuable error messages.
|
|
||||||
* **Poor UX:** Verbose output, generic recommendations, and a lack of clear overall risk assessment.
|
|
||||||
* **Missing Critical Checks:** Lacks checks for image size, multi-stage build optimization, comprehensive vulnerability scanning (beyond basic `apt` packages), and content of sensitive files.
|
|
||||||
**Impact:** Undetected security vulnerabilities, inefficient security checks, and a false sense of security.
|
|
||||||
**Recommendation:**
|
|
||||||
* Refactor to use a single `docker run` command for all internal checks.
|
|
||||||
* Integrate comprehensive vulnerability scanning tools (e.g., Trivy for all package types, Hadolint for Dockerfile analysis).
|
|
||||||
* Expand checks to cover `npm`, `mise`, and `aqua` dependencies.
|
|
||||||
* Remove excessive error suppression.
|
|
||||||
* Provide a clear, concise summary of findings and actionable recommendations.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 7. `test.sh` (Both `output/toolbox-base/test.sh` and `output/toolbox-template/test.sh`)
|
|
||||||
|
|
||||||
**Issue:** Highly inefficient and superficial testing.
|
|
||||||
**Details:**
|
|
||||||
* **Extreme Inefficiency:** Each tool test executes a new `docker run --rm "${IMAGE_NAME}" ...`, making the test suite incredibly slow.
|
|
||||||
* **Limited Scope:** Tests only check if a tool's `--version` command works, which is a very basic sanity check. It fails to verify actual functionality, correct configuration, or integration between tools.
|
|
||||||
* **Error Hiding:** Suppresses all output from tool commands (`>/dev/null 2>&1`), hiding potential warnings or errors.
|
|
||||||
* **Maintenance Burden:** Hardcoded tool lists require manual updates when the `Dockerfile` changes.
|
|
||||||
* **No Integration Tests:** Lacks tests to verify that tools work together as expected (e.g., `mise` and `aqua` integration with the shell, `starship` prompt display).
|
|
||||||
**Impact:** Slow development cycles, undetected regressions, and a false sense of tested functionality.
|
|
||||||
**Recommendation:**
|
|
||||||
* Refactor to use a single `docker run` command for all internal tests.
|
|
||||||
* Implement more comprehensive tests that verify actual tool functionality and integration.
|
|
||||||
* Remove excessive error suppression.
|
|
||||||
* Dynamically generate tool lists or use a more robust configuration management approach.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 8. `README.md` (Both `output/toolbox-base/README.md` and `output/toolbox-template/README.md`)
|
|
||||||
|
|
||||||
**Issue:** Misleading information, incompleteness, and propagation of bad examples.
|
|
||||||
**Details:**
|
|
||||||
* **Misleading Information:** `toolbox-base/README.md` falsely claims `release.sh` pushes images, which is not implemented.
|
|
||||||
* **Incompleteness:** Fails to mention `test.sh` and `security-audit.sh` in the verification checklist, despite their presence.
|
|
||||||
* **Propagation of Bad Examples:** `toolbox-template/README.md` includes flawed code examples directly from the `Dockerfile`, perpetuating bad practices.
|
|
||||||
* **Lack of Verification Checklist:** `toolbox-template/README.md` lacks a dedicated verification checklist, which is crucial for a template.
|
|
||||||
**Impact:** Confusion for users, incorrect expectations, and propagation of poor practices.
|
|
||||||
**Recommendation:**
|
|
||||||
* Update `README.md` files to accurately reflect script functionality.
|
|
||||||
* Include all relevant scripts in verification checklists.
|
|
||||||
* Refactor code examples in `README.md` to demonstrate best practices.
|
|
||||||
* Add a comprehensive verification checklist to `toolbox-template/README.md`.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 9. `.devcontainer/devcontainer.json` (Both `output/toolbox-base/.devcontainer/devcontainer.json` and `output/toolbox-template/.devcontainer/devcontainer.json`)
|
|
||||||
|
|
||||||
**Issue:** Weak validation and potential maintenance burden.
|
|
||||||
**Details:**
|
|
||||||
* **Weak Validation:** The `postCreateCommand` uses a very basic `starship --version` check, which is insufficient for comprehensive environment validation.
|
|
||||||
* **Maintenance Burden:** The hardcoded `remoteUser` could become a maintenance issue if the user name needs to change across different environments.
|
|
||||||
**Impact:** Insufficient environment validation, potential for broken development environments.
|
|
||||||
**Recommendation:**
|
|
||||||
* Enhance `postCreateCommand` with more robust validation checks, potentially leveraging the improved `test.sh` script.
|
|
||||||
* Consider making `remoteUser` configurable if dynamic user names are anticipated.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 10. Git Status
|
|
||||||
|
|
||||||
**Issue:** Uncommitted changes and untracked files.
|
|
||||||
**Details:** The `git status` command reveals numerous modified and untracked files.
|
|
||||||
**Impact:** Indicates ongoing work, but also a lack of regular commits, which can lead to larger, harder-to-review changes, and potential loss of work.
|
|
||||||
**Recommendation:** Encourage more frequent, smaller commits to facilitate easier review and better version control.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Conclusion
|
|
||||||
|
|
||||||
The ToolboxStack project, in its current state, is fundamentally flawed. It exhibits a systemic disregard for efficiency, best practices, and security across its Docker configurations, build scripts, and documentation. The pervasive redundancy, inefficiency, and security vulnerabilities will lead to bloated images, slow development cycles, and a high risk of undetected issues. A complete overhaul, focusing on Docker best practices, robust scripting, and accurate documentation, is urgently required.
|
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
|
|
||||||
## Qwen Audit
|
|
||||||
|
|
||||||
Please orient yourself in exhaustive detail and depth to this entire directory tree.
|
|
||||||
The purpose of this directory treee is to create a set of "toolbox" containers for myself (as CTO) and my team of AI coding agents to use to implment all of my ideas.
|
|
||||||
|
|
||||||
Your role in this chat is to conduct a series of ongoing
|
|
||||||
|
|
||||||
- exhaustive
|
|
||||||
- in depth
|
|
||||||
- brutal
|
|
||||||
- no stone left unturned
|
|
||||||
|
|
||||||
audits of this directory tree.
|
|
||||||
|
|
||||||
You will be taking on the roles of
|
|
||||||
|
|
||||||
Docker expert
|
|
||||||
tooling expert
|
|
||||||
senior staff level developer/architect/tester/DEVOPS/SRE
|
|
||||||
|
|
||||||
and you will conduct an audit and produce a report.
|
|
||||||
|
|
||||||
Your audit should cover:
|
|
||||||
|
|
||||||
- Docker build optimization,
|
|
||||||
- Dockerfile correctness
|
|
||||||
- Build caching
|
|
||||||
- security best practices,
|
|
||||||
- docker development environment best practices,
|
|
||||||
- best common practices in general for (dockerized) development/tooling stacks
|
|
||||||
- any other criteria you feel is prudent in the subject area
|
|
||||||
- assessment of all existing toolboxes (base, DocStack, QADocker, and any others)
|
|
||||||
|
|
||||||
|
|
||||||
When I say the words "perform QA"
|
|
||||||
You will write out a human-readable report to :
|
|
||||||
|
|
||||||
collab/audits/YYYY/MM/DD/HHMM/QAReport.md (using the local system time).
|
|
||||||
|
|
||||||
The human-readable report should use icons/headers/tables/graphics and be very beautiful and easy to digest.
|
|
||||||
|
|
||||||
You will write out an llm optimized report to
|
|
||||||
collab/audits/YYYY/MM/DD/HHMM/QAReport.LLM (using the local system time).
|
|
||||||
|
|
||||||
Keep in mind that I will feed your LLM optimized report to the other qwen chat for implementation. So it should be fully optimized for an LLM to follow and implement.
|
|
||||||
|
|
||||||
Be advised another QWEN is actively working in this directory tree making toolboxes for me. So confine your write operations to collab/audits please.
|
|
||||||
|
|
||||||
You have another role as well.
|
|
||||||
|
|
||||||
When I say the words "give advice"
|
|
||||||
|
|
||||||
You will write out a human readable report to :
|
|
||||||
|
|
||||||
collab/advisor/YYYY/MM/DD/HHMM/AdvisorReport.md (using the local system time).
|
|
||||||
|
|
||||||
The human readable report should use icons/headers/tables/graphics and be very beautiful and easy to digest.
|
|
||||||
|
|
||||||
You will write out an llm optimized report to
|
|
||||||
collab/advisor/YYYY/MM/DD/HHMM/AdvisorReport.LLM (using the local system time).
|
|
||||||
|
|
||||||
Keep in mind that I will feed your LLM optimized report to the other qwen chat for implementation. So it should be fully optimized for an LLM to follow and implement.
|
|
||||||
|
|
||||||
To make suggestions and give feedback on
|
|
||||||
|
|
||||||
- tools to add
|
|
||||||
- how to split up the containers
|
|
||||||
- what needs to go into base toolbox vs specialized toolboxes
|
|
||||||
|
|
||||||
Some context:
|
|
||||||
|
|
||||||
My projects span:
|
|
||||||
|
|
||||||
- Extensive documentation generation needs (PDFs, websites) of governance documents, reports, proposals, project plans, budgets etc.
|
|
||||||
- Software development (full SDLC) across: node,python,php, ruby, perl, java, rust, c and c++ (including embedded development, cross compiling),
|
|
||||||
nix (embedded systems builds for aeronautical applications where we need complete reproducibility), web application development, desktop GUI development etc
|
|
||||||
|
|
||||||
The ToolboxStack is for "inner loop" operations (edit/compile/test) only.
|
|
||||||
|
|
||||||
I have another stack for build/packaging/release operations and another stack for support functions (like atuin/mailhog etc).
|
|
||||||
|
|
||||||
## Enhanced Audit Process
|
|
||||||
|
|
||||||
The audit process now includes automated assessment of all existing toolboxes using the script at collab/audit-all-toolboxes.sh.
|
|
||||||
|
|
||||||
When performing an audit using the "perform QA" command, this script will be run automatically to analyze all toolboxes in the system, and the results will be incorporated into both the human-readable and LLM-optimized reports.
|
|
||||||
|
|
||||||
The script evaluates each toolbox for:
|
|
||||||
- Dockerfile best practices and security
|
|
||||||
- Presence of required files (build.sh, run.sh, test.sh, etc.)
|
|
||||||
- Documentation completeness (README.md, PROMPT, SEED)
|
|
||||||
- Tool configuration (aqua.yaml, etc.)
|
|
||||||
|
|
||||||
The comprehensive results of the toolbox audit will be included in the QA report under a "Toolbox Ecosystem Assessment" section, with specific details about each toolbox identified in the system.
|
|
||||||
23
ToolboxStack/collab/prompts/FeatureWork/toolbox-qadocker.md
Normal file
23
ToolboxStack/collab/prompts/FeatureWork/toolbox-qadocker.md
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
The first toolbox we need to build is for performing audit/QA work on the images we are trying to build.
|
||||||
|
|
||||||
|
Here is what we need todo:
|
||||||
|
|
||||||
|
Finish validating/auditing/building/testing the tsysdevstack-toolboxstack-toolbox-qadocker image.
|
||||||
|
|
||||||
|
This will be the ONLY image that we build (other than tsysdevstack-toolboxstack-toolbox-base itself) which DOES NOT use the toolbox-base image as its foundation.
|
||||||
|
|
||||||
|
The toolbox-qadocker image is used for bootstrap purposes and is meant to audit toolbox-base and every other custom toolbox we make.
|
||||||
|
|
||||||
|
The toolbox-qadocker image should be minimal, simple. It should be easy to extend, it should be able to be re-built quickly.
|
||||||
|
|
||||||
|
Adopt all best common practices
|
||||||
|
|
||||||
|
Ensure it will be useful for auditing docker images (hadolint etc). Its meant to run quickly and be utilized by AI CLI agents when they are making container images.
|
||||||
|
|
||||||
|
Do the work in:
|
||||||
|
|
||||||
|
output/toolbox-QADocker
|
||||||
|
|
||||||
|
Ensure the container image builds and the tools work
|
||||||
|
|
||||||
|
Use it to QA itself.
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
if [[ $# -ne 1 ]]; then
|
|
||||||
echo "Usage: $0 <toolbox-name>" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
RAW_NAME="$1"
|
|
||||||
if [[ "${RAW_NAME}" == toolbox-* ]]; then
|
|
||||||
TOOLBOX_NAME="${RAW_NAME}"
|
|
||||||
else
|
|
||||||
TOOLBOX_NAME="toolbox-${RAW_NAME}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
||||||
TEMPLATE_DIR="${SCRIPT_DIR}/toolbox-template"
|
|
||||||
TARGET_DIR="${SCRIPT_DIR}/${TOOLBOX_NAME}"
|
|
||||||
|
|
||||||
if [[ ! -d "${TEMPLATE_DIR}" ]]; then
|
|
||||||
echo "Error: template directory not found at ${TEMPLATE_DIR}" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -e "${TARGET_DIR}" ]]; then
|
|
||||||
echo "Error: ${TARGET_DIR} already exists" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
cp -R "${TEMPLATE_DIR}" "${TARGET_DIR}"
|
|
||||||
|
|
||||||
python3 - "$TARGET_DIR" "$TOOLBOX_NAME" <<'PY'
|
|
||||||
import sys
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
base = Path(sys.argv[1])
|
|
||||||
toolbox_name = sys.argv[2]
|
|
||||||
|
|
||||||
for path in base.rglob("*"):
|
|
||||||
if not path.is_file():
|
|
||||||
continue
|
|
||||||
text = path.read_text()
|
|
||||||
updated = text.replace("{{toolbox_name}}", toolbox_name)
|
|
||||||
if updated != text:
|
|
||||||
path.write_text(updated)
|
|
||||||
PY
|
|
||||||
|
|
||||||
echo "Created ${TARGET_DIR} from template."
|
|
||||||
echo "Next steps:"
|
|
||||||
echo " 1) Edit ${TARGET_DIR}/SEED once to describe the toolbox goals."
|
|
||||||
echo " 2) Load ${TARGET_DIR}/PROMPT in Codex; it will instruct you to read SEED and proceed."
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
You are Codex helping with TSYSDevStack ToolboxStack deliverables.
|
|
||||||
|
|
||||||
Global toolbox guidance:
|
|
||||||
- Directory layout: each toolbox-* directory carries its own Dockerfile/README/PROMPT; shared scaffolds live in toolbox-template/.devcontainer and docker-compose.yml.
|
|
||||||
- Use ./NewToolbox.sh <name> to scaffold a new toolbox-* directory from toolbox-template.
|
|
||||||
- Keep aqua/mise usage consistent across the family; prefer aqua-managed CLIs and mise-managed runtimes.
|
|
||||||
- Reference toolbox-template when bootstrapping a new toolbox. Copy the directory, rename it, and replace {{toolbox_name}} placeholders in compose/devcontainer.
|
|
||||||
- Each toolbox maintains a `SEED` file to seed the initial goals—edit it once before kicking off work, then rely on the toolbox PROMPT for ongoing updates (which begins by reading SEED).
|
|
||||||
- Default build workflow: `./build.sh` produces a `:dev` tag; `./release.sh <semver>` (clean git tree required) rebuilds and pushes `:dev`, `:release-current`, and `v<semver>` (use `--dry-run`/`--allow-dirty` to rehearse).
|
|
||||||
- Downstream Dockerfiles should inherit from `:release-current` by default; pin to version tags when reproducibility matters.
|
|
||||||
|
|
||||||
Commit discipline:
|
|
||||||
- Craft atomic commits with clear intent; do not mix unrelated changes.
|
|
||||||
- Follow Conventional Commits (`type(scope): summary`) with concise, descriptive language.
|
|
||||||
- Commit frequently as features evolve, keeping diffs reviewable.
|
|
||||||
- After documentation/tooling changes, run ./build.sh to ensure the image builds, then push once the build succeeds.
|
|
||||||
- Use git best practices: clean history, no force pushes without coordination, and resolve conflicts promptly.
|
|
||||||
|
|
||||||
Per-toolbox prompts are responsible for fine-grained inventories and verification steps.
|
|
||||||
@@ -1,25 +1,14 @@
|
|||||||
{
|
{
|
||||||
"name": "TSYSDevStack Docker QA Toolbox",
|
"name": "TSYSDevStack {{toolbox_name}}",
|
||||||
"dockerComposeFile": [
|
"dockerComposeFile": [
|
||||||
"../docker-compose.yml"
|
"../docker-compose.yml"
|
||||||
],
|
],
|
||||||
"service": "toolbox-qadocker",
|
"service": "{{toolbox_name}}",
|
||||||
"workspaceFolder": "/workspace",
|
"workspaceFolder": "/workspace",
|
||||||
"remoteUser": "toolbox",
|
"remoteUser": "toolbox",
|
||||||
"runServices": [
|
"runServices": [
|
||||||
"toolbox-qadocker"
|
"{{toolbox_name}}"
|
||||||
],
|
],
|
||||||
"overrideCommand": false,
|
"overrideCommand": false,
|
||||||
"postCreateCommand": "zsh -lc 'echo \"Docker QA environment ready. Available tools: trivy, hadolint, docker, dockerfilelint\"'",
|
"postCreateCommand": "zsh -lc 'starship --version >/dev/null'"
|
||||||
"mounts": [
|
|
||||||
"source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind"
|
|
||||||
],
|
|
||||||
"customizations": {
|
|
||||||
"vscode": {
|
|
||||||
"extensions": [
|
|
||||||
"ms-azuretools.vscode-docker",
|
|
||||||
"hadolint.hadolint"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,101 +1,120 @@
|
|||||||
# 🛡️ Docker QA Toolbox Audit Checklist
|
# 🧰 Toolbox Template Audit Checklist
|
||||||
|
|
||||||
This checklist ensures the Docker QA toolbox meets all security, functionality, and maintainability requirements for Docker image auditing.
|
This checklist ensures the toolbox-template provides a solid foundation for creating new toolboxes that extend from toolbox-base.
|
||||||
|
|
||||||
## 🔒 Security Audit
|
## 🏗️ Structure Audit
|
||||||
|
|
||||||
- [ ] All packages installed with specific versions (no `latest` tags)
|
- [ ] Template Dockerfile properly extends from toolbox-base:release-current
|
||||||
- [ ] All external downloads verified with checksums/signatures
|
- [ ] Template Dockerfile follows best practices for extension
|
||||||
- [ ] No root access possible at runtime (sudo removed)
|
- [ ] Template docker-compose.yml properly inherits from base configuration
|
||||||
- [ ] Non-root user properly configured with UID/GID mapping
|
- [ ] Template build.sh script properly wraps docker build with UID/GID mapping
|
||||||
- [ ] No hardcoded secrets or credentials in image
|
- [ ] Template run.sh script properly manages container lifecycle
|
||||||
- [ ] Minimal attack surface (unnecessary packages removed)
|
- [ ] Template devcontainer.json properly references base configuration
|
||||||
- [ ] Regular security scanning implemented (Trivy integration)
|
- [ ] Template SEED file properly defines extension objectives
|
||||||
- [ ] Base image (Ubuntu) regularly updated
|
- [ ] Template PROMPT file properly guides contributors
|
||||||
- [ ] All aqua packages verified through registry
|
- [ ] Template README.md properly documents usage and customization
|
||||||
- [ ] Docker socket access properly secured
|
- [ ] Template aqua.yaml properly extends from base tooling
|
||||||
|
|
||||||
## 🛠️ Functionality Audit
|
## 🔧 Consistency Audit
|
||||||
|
|
||||||
- [ ] All Docker QA tools properly installed and accessible
|
- [ ] Template inherits all base security practices
|
||||||
- [ ] All tools respond to `--version` flag correctly
|
- [ ] Template follows same build process patterns as base
|
||||||
- [ ] Aqua proxy mechanism properly configured
|
- [ ] Template uses same user model as base (non-root with UID/GID mapping)
|
||||||
- [ ] Docker access to host daemon working correctly
|
- [ ] Template workspace mounting consistent with base
|
||||||
- [ ] Security scanning tools (Trivy, Hadolint) functional
|
- [ ] Template runtime behavior consistent with base
|
||||||
- [ ] Dockerfile linting tools working properly
|
- [ ] Template error handling consistent with base
|
||||||
- [ ] Shell configurations properly set up (zsh, bash)
|
- [ ] Template documentation style consistent with base
|
||||||
- [ ] Environment variables properly configured
|
- [ ] Template testing approach consistent with base
|
||||||
- [ ] PATH correctly set for all tools
|
- [ ] Template customization points clearly defined
|
||||||
- [ ] User home directory properly configured
|
- [ ] Template extension patterns well-documented
|
||||||
- [ ] Workspace directory properly set up with correct permissions
|
|
||||||
|
|
||||||
## 🏗️ Build Process Audit
|
## 🛡️ Security Audit
|
||||||
|
|
||||||
- [ ] Dockerfile follows best practices
|
- [ ] Template maintains all base security guarantees
|
||||||
- [ ] Multi-stage build optimizations implemented
|
- [ ] Template doesn't introduce security vulnerabilities
|
||||||
- [ ] Build cache properly utilized
|
- [ ] Template doesn't weaken base security model
|
||||||
- [ ] Build arguments properly validated
|
- [ ] Template properly validates user inputs
|
||||||
- [ ] Error handling in build scripts comprehensive
|
- [ ] Template properly handles file permissions
|
||||||
- [ ] Build verification tests implemented
|
- [ ] Template doesn't expose additional attack surfaces
|
||||||
- [ ] Image tagging strategy consistent
|
- [ ] Template properly manages secrets/configuration
|
||||||
- [ ] Release process properly documented
|
- [ ] Template follows principle of least privilege
|
||||||
|
- [ ] Template properly isolates user processes
|
||||||
|
- [ ] Template maintains non-root execution model
|
||||||
|
|
||||||
## 🧪 Testing Audit
|
## 🧪 Testing Audit
|
||||||
|
|
||||||
- [ ] Automated testing of all installed tools
|
- [ ] Template includes testing framework
|
||||||
- [ ] Integration tests for Docker daemon access
|
- [ ] Template tests verify proper extension from base
|
||||||
- [ ] Regression tests for known issues
|
- [ ] Template tests validate added functionality
|
||||||
- [ ] Security scanning of built images
|
- [ ] Template tests check for regression issues
|
||||||
- [ ] Performance benchmarks
|
- [ ] Template tests cover error conditions
|
||||||
- [ ] Security scanning during build
|
- [ ] Template tests verify security properties
|
||||||
|
- [ ] Template tests run automatically during build
|
||||||
|
- [ ] Template tests provide clear failure diagnostics
|
||||||
|
- [ ] Template tests cover all customization points
|
||||||
|
- [ ] Template tests align with base testing philosophy
|
||||||
|
|
||||||
## 📚 Documentation Audit
|
## 📚 Documentation Audit
|
||||||
|
|
||||||
- [ ] README.md accurately reflects current state
|
- [ ] Template README.md clearly explains purpose and usage
|
||||||
- [ ] All tools properly documented
|
- [ ] Template README.md properly documents customization options
|
||||||
- [ ] Usage examples for Docker QA workflows provided
|
- [ ] Template README.md links to base documentation
|
||||||
- [ ] Troubleshooting guide included
|
- [ ] Template README.md includes quick start guide
|
||||||
- [ ] Contribution guidelines clear
|
- [ ] Template README.md covers troubleshooting
|
||||||
- [ ] License information up to date
|
- [ ] Template README.md explains extension patterns
|
||||||
|
- [ ] Template README.md documents versioning strategy
|
||||||
|
- [ ] Template README.md covers maintenance procedures
|
||||||
|
- [ ] Template README.md explains collaboration guidelines
|
||||||
|
- [ ] Template README.md maintains consistent style with base
|
||||||
|
|
||||||
## 🔄 Maintenance Audit
|
## 🔄 Maintenance Audit
|
||||||
|
|
||||||
- [ ] Dependency update strategy defined
|
- [ ] Template properly tracks base image updates
|
||||||
- [ ] Version pinning strategy consistent
|
- [ ] Template provides clear upgrade paths
|
||||||
- [ ] Backward compatibility maintained
|
- [ ] Template maintains backward compatibility
|
||||||
- [ ] Deprecation policy established
|
- [ ] Template follows same release cadence as base
|
||||||
- [ ] Release notes properly maintained
|
- [ ] Template properly handles dependency updates
|
||||||
- [ ] Issue tracking process defined
|
- [ ] Template includes update automation where appropriate
|
||||||
|
- [ ] Template documents breaking changes
|
||||||
|
- [ ] Template provides migration guides when needed
|
||||||
|
- [ ] Template follows same versioning scheme as base
|
||||||
|
- [ ] Template maintains consistent issue tracking
|
||||||
|
|
||||||
## 🎯 Specialized QA Features Audit
|
## 🎯 Usability Audit
|
||||||
|
|
||||||
- [ ] Trivy vulnerability scanning functional
|
- [ ] Template is easy to copy and customize
|
||||||
- [ ] Hadolint Dockerfile linting operational
|
- [ ] Template provides clear extension points
|
||||||
- [ ] Dockerfilelint working correctly
|
- [ ] Template includes helpful examples
|
||||||
- [ ] Docker history/inspect tools accessible
|
- [ ] Template reduces boilerplate code
|
||||||
- [ ] Image layer analysis capabilities present
|
- [ ] Template provides sensible defaults
|
||||||
- [ ] Best practices validation tools available
|
- [ ] Template includes proper error messages
|
||||||
|
- [ ] Template supports common customization patterns
|
||||||
## 📈 Performance Audit
|
- [ ] Template includes helpful documentation
|
||||||
|
- [ ] Template follows intuitive naming conventions
|
||||||
- [ ] Image size optimized
|
- [ ] Template minimizes configuration complexity
|
||||||
- [ ] Startup time acceptable
|
|
||||||
- [ ] Memory footprint reasonable
|
|
||||||
- [ ] CPU usage within expected bounds
|
|
||||||
- [ ] Docker scanning performance adequate
|
|
||||||
|
|
||||||
## 🌐 Compatibility Audit
|
## 🌐 Compatibility Audit
|
||||||
|
|
||||||
- [ ] Works on all supported platforms
|
- [ ] Template works with all supported platforms
|
||||||
- [ ] Docker daemon access functional across platforms
|
- [ ] Template maintains cross-platform consistency
|
||||||
- [ ] Backward compatibility with Docker versions maintained
|
- [ ] Template integrates well with base tooling
|
||||||
- [ ] Integration with common CI/CD tools verified
|
- [ ] Template supports common development workflows
|
||||||
|
- [ ] Template handles various project structures
|
||||||
|
- [ ] Template works with popular IDEs/editors
|
||||||
|
- [ ] Template supports CI/CD integration
|
||||||
|
- [ ] Template compatible with common deployment methods
|
||||||
|
- [ ] Template supports popular version control systems
|
||||||
|
- [ ] Template integrates with common development tools
|
||||||
|
|
||||||
## 🧹 Cleanup Audit
|
## 🧹 Cleanliness Audit
|
||||||
|
|
||||||
- [ ] Temporary files properly removed
|
- [ ] Template includes no unnecessary files
|
||||||
- [ ] Build artifacts cleaned up
|
- [ ] Template follows consistent file organization
|
||||||
- [ ] Cache directories properly managed
|
- [ ] Template includes proper .gitignore
|
||||||
- [ ] Log files rotated or removed
|
- [ ] Template avoids duplicating base functionality
|
||||||
- [ ] Orphaned processes prevented
|
- [ ] Template includes proper licensing information
|
||||||
- [ ] Resource leaks eliminated
|
- [ ] Template maintains clean directory structure
|
||||||
|
- [ ] Template includes appropriate comments/documentation
|
||||||
|
- [ ] Template avoids hardcoded values where possible
|
||||||
|
- [ ] Template follows consistent naming conventions
|
||||||
|
- [ ] Template includes proper attribution where needed
|
||||||
@@ -1,195 +1,77 @@
|
|||||||
# Multi-stage approach to minimize final image size and attack surface
|
# Use Ubuntu 24.04 as base for the QA Docker toolbox
|
||||||
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
|
|
||||||
FROM ubuntu:24.04
|
FROM ubuntu:24.04
|
||||||
|
|
||||||
|
# Set build arguments (these can be overridden at build time)
|
||||||
ARG USER_ID=1000
|
ARG USER_ID=1000
|
||||||
ARG GROUP_ID=1000
|
ARG GROUP_ID=1000
|
||||||
ARG USERNAME=toolbox
|
ARG USERNAME=toolbox
|
||||||
ARG TEA_VERSION=0.11.1
|
|
||||||
|
|
||||||
|
# Set up environment and install essential packages
|
||||||
ENV DEBIAN_FRONTEND=noninteractive
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
# ROOT: Install minimal runtime dependencies only
|
ca-certificates \
|
||||||
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
curl \
|
||||||
--mount=type=cache,target=/var/lib/apt/lists,sharing=locked \
|
gnupg \
|
||||||
apt-get update \
|
lsb-release \
|
||||||
&& apt-get install -y --no-install-recommends \
|
git \
|
||||||
ca-certificates \
|
unzip \
|
||||||
curl \
|
wget \
|
||||||
git \
|
|
||||||
jq \
|
|
||||||
bc \
|
|
||||||
locales \
|
|
||||||
openssh-client \
|
|
||||||
zsh \
|
|
||||||
unzip \
|
|
||||||
zip \
|
|
||||||
python3 \
|
|
||||||
docker.io \
|
|
||||||
&& apt-get clean \
|
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# ROOT: Restore system-wide configurations
|
# Install Docker CLI
|
||||||
RUN locale-gen en_US.UTF-8
|
RUN install -m 0755 -d /etc/apt/keyrings \
|
||||||
ENV LANG=en_US.UTF-8 \
|
&& curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg \
|
||||||
LANGUAGE=en_US:en \
|
&& chmod a+r /etc/apt/keyrings/docker.gpg \
|
||||||
LC_ALL=en_US.UTF-8
|
&& 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
|
# Install hadolint for Dockerfile linting
|
||||||
RUN if getent passwd "${USER_ID}" >/dev/null; then \
|
RUN wget -O /usr/bin/hadolint https://github.com/hadolint/hadolint/releases/download/v2.12.0/hadolint-Linux-x86_64 \
|
||||||
existing_user="$(getent passwd "${USER_ID}" | cut -d: -f1)"; \
|
&& chmod +x /usr/bin/hadolint
|
||||||
userdel --remove "${existing_user}"; \
|
|
||||||
fi \
|
# Install dive for exploring Docker image layers
|
||||||
&& if ! getent group "${GROUP_ID}" >/dev/null; then \
|
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}"; \
|
groupadd --gid "${GROUP_ID}" "${USERNAME}"; \
|
||||||
fi \
|
fi && \
|
||||||
&& useradd --uid "${USER_ID}" --gid "${GROUP_ID}" --shell /usr/bin/zsh --create-home "${USERNAME}"
|
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
|
# Install aqua for package management
|
||||||
COPY --from=installer --chown=${USER_ID}:${GROUP_ID} /home/${USERNAME} /home/${USERNAME}
|
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
|
# Copy the aqua.yaml configuration for the non-root user and install packages
|
||||||
RUN mkdir -p /workspace && chown "${USER_ID}:${GROUP_ID}" /workspace
|
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
|
# Prepare workspace directory with appropriate ownership
|
||||||
RUN curl -fsSL "https://dl.gitea.io/tea/${TEA_VERSION}/tea-${TEA_VERSION}-linux-amd64" -o /tmp/tea \
|
RUN mkdir -p /workspace \
|
||||||
&& curl -fsSL "https://dl.gitea.io/tea/${TEA_VERSION}/tea-${TEA_VERSION}-linux-amd64.sha256" -o /tmp/tea.sha256 \
|
&& chown "${USER_ID}:${GROUP_ID}" /workspace
|
||||||
&& 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
|
|
||||||
|
|
||||||
RUN curl -fsSL https://starship.rs/install.sh | sh -s -- -y -b /usr/local/bin
|
# Remove sudo to ensure no root escalation is possible at runtime
|
||||||
|
|
||||||
# ROOT: Security hardening - remove sudo if present
|
|
||||||
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
|
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=/root/.local/share/aquaproj-aqua/bin:/home/${USERNAME}/.local/share/aquaproj-aqua/bin:/usr/local/bin:${PATH}
|
||||||
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
|
|
||||||
|
|
||||||
# FINAL USER: Switch to toolbox user for runtime
|
|
||||||
USER ${USERNAME}
|
|
||||||
WORKDIR /workspace
|
WORKDIR /workspace
|
||||||
|
USER ${USERNAME}
|
||||||
|
|
||||||
CMD ["/usr/bin/zsh"]
|
CMD ["/bin/bash"]
|
||||||
@@ -1,34 +1,27 @@
|
|||||||
# Docker QA Toolbox Prompt
|
You are Codex, collaborating with a human on the TSYSDevStack ToolboxStack project.
|
||||||
|
|
||||||
You are an AI assistant working inside the Docker QA Toolbox container. Your purpose is to assist with Docker image auditing, security scanning, and quality assurance.
|
- Seed context:
|
||||||
|
- `SEED` captures the initial scope. Edit it once to define goals, then treat it as read-only unless the high-level objectives change.
|
||||||
|
- Start each session by reading it (`cat SEED`) and summarize progress or adjustments here in PROMPT.
|
||||||
|
|
||||||
## Your Environment
|
Context snapshot ({{toolbox_name}}):
|
||||||
- You're running as the 'toolbox' user with the same UID/GID as the host user
|
- Working directory: artifacts/ToolboxStack/{{toolbox_name}}
|
||||||
- You have access to the Docker daemon via the mounted socket
|
- Image: tsysdevstack-toolboxstack-{{toolbox_name}} (extends from tsysdevstack-toolboxstack-toolbox-base:release-current)
|
||||||
- You're in a bash shell with access to various Docker auditing tools
|
- Container user: toolbox (non-root, UID/GID mapped to host)
|
||||||
|
- Mounted workspace: current repo at /workspace (rw)
|
||||||
|
|
||||||
## Your Capabilities
|
Current state:
|
||||||
1. Scan Docker images for vulnerabilities using Trivy
|
- Extends from the standard toolbox-base image, inheriting all base tooling (shells, CLIs, package managers).
|
||||||
2. Lint Dockerfiles using Hadolint and dockerfilelint
|
- aqua packages are baked into the base image during the build process for consistency, reproducibility and performance.
|
||||||
3. Analyze Docker image layers and composition
|
- AI CLI tools from the base are available, with host directories mounted for configuration persistence.
|
||||||
4. Validate Docker best practices
|
- See ../PROMPT for shared toolbox contribution expectations (documentation sync, build cadence, commit/push discipline, Conventional Commits, atomic history).
|
||||||
5. Perform security audits of container images
|
|
||||||
6. Generate reports on Docker image quality
|
|
||||||
|
|
||||||
## Common Commands
|
Collaboration checklist:
|
||||||
- `trivy image <image-name>` - Scan an image for vulnerabilities
|
1. Translate SEED goals into concrete tooling decisions; mirror outcomes in README.md and this PROMPT (do not rewrite SEED unless the scope resets).
|
||||||
- `hadolint <Dockerfile>` - Lint a Dockerfile against best practices
|
2. Prefer aqua-managed CLIs and mise-managed runtimes for reproducibility.
|
||||||
- `dockerfilelint <Dockerfile>` - Additional Dockerfile linting
|
3. After each tooling change, update README/PROMPT, run ./build.sh, commit (Conventional Commit message, focused diff), and push only once the build succeeds per ../PROMPT.
|
||||||
- `docker history <image-name>` - Show image layer history
|
4. Record verification steps (build/test commands) as they are performed.
|
||||||
- `docker inspect <image-name>` - Show image metadata
|
5. Maintain UID/GID mapping and non-root execution.
|
||||||
- `docker run --rm -it <image-name> /bin/sh` - Inspect image contents interactively
|
|
||||||
|
|
||||||
## Best Practices to Follow
|
Active focus:
|
||||||
1. Always scan images before deploying to production
|
- Initialize {{toolbox_name}} using the toolbox-template scaffolding; evolve the Dockerfile/tooling inventory to satisfy the SEED goals.
|
||||||
2. Use multi-stage builds to minimize attack surface
|
|
||||||
3. Run containers as non-root users
|
|
||||||
4. Pin base image versions rather than using 'latest'
|
|
||||||
5. Regularly update base images and packages
|
|
||||||
6. Verify checksums when downloading external binaries
|
|
||||||
|
|
||||||
Remember: The workspace directory is mounted from your host system, so you can analyze Dockerfiles and images from the host.
|
|
||||||
@@ -1,85 +1,107 @@
|
|||||||
# 🛡️ Docker QA Toolbox
|
# 🧰 TSYSDevStack Toolbox Template
|
||||||
|
|
||||||
A specialized development environment for Docker image auditing, security scanning, and quality assurance.
|
Template for creating new toolboxes that extend from the `toolbox-base` image.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 🚀 Quick Start
|
## 🚀 Quick Start
|
||||||
|
|
||||||
```bash
|
1. **Create a new toolbox**
|
||||||
cd output/toolbox-QADocker
|
```bash
|
||||||
./build.sh # build the image with UID/GID matching your host
|
cp -r /path/to/toolbox-template /path/to/new-toolbox
|
||||||
./run.sh up # launch the toolbox-qadocker service in the background
|
cd /path/to/new-toolbox
|
||||||
docker exec -it tsysdevstack-toolboxstack-toolbox-qadocker zsh
|
```
|
||||||
|
|
||||||
|
2. **Customize the toolbox**
|
||||||
|
- Edit `Dockerfile` to add toolbox-specific tooling
|
||||||
|
- Modify `docker-compose.yml` to adjust service configuration
|
||||||
|
- Update `SEED` to define the toolbox's purpose and goals
|
||||||
|
|
||||||
|
3. **Build the toolbox**
|
||||||
|
```bash
|
||||||
|
./build.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Start the toolbox**
|
||||||
|
```bash
|
||||||
|
./run.sh up
|
||||||
|
```
|
||||||
|
|
||||||
|
5. **Access the toolbox**
|
||||||
|
```bash
|
||||||
|
docker exec -it tsysdevstack-toolboxstack-{{toolbox_name}} zsh
|
||||||
|
```
|
||||||
|
|
||||||
|
6. **Stop the toolbox**
|
||||||
|
```bash
|
||||||
|
./run.sh down
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧱 Architecture
|
||||||
|
|
||||||
|
- **Base Image**: Extends from `tsysdevstack-toolboxstack-toolbox-base:release-current`
|
||||||
|
- **User**: Runs as non-root `toolbox` user (UID/GID mapped to host)
|
||||||
|
- **Workspace**: Mounts current directory to `/workspace` (read/write)
|
||||||
|
- **Runtime**: Inherits all tooling from base plus toolbox-specific additions
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🛠️ Customization
|
||||||
|
|
||||||
|
### Dockerfile
|
||||||
|
Extend the base image with toolbox-specific tooling:
|
||||||
|
```dockerfile
|
||||||
|
# Extend from the toolbox-base image
|
||||||
|
FROM tsysdevstack-toolboxstack-toolbox-base:release-current
|
||||||
|
|
||||||
|
# Add toolbox-specific packages or configurations
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
specific-package \
|
||||||
|
&& apt-get clean \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
```
|
```
|
||||||
|
|
||||||
Use `./run.sh down` to stop the container when you are finished.
|
### docker-compose.yml
|
||||||
|
Adjust service configuration for toolbox-specific needs:
|
||||||
## 🧰 Included Tools
|
```yaml
|
||||||
|
services:
|
||||||
### Security Scanning
|
my-toolbox:
|
||||||
- **Trivy** - Comprehensive vulnerability scanner for containers and code
|
# Inherits all base configuration
|
||||||
- **ClamAV** - Antivirus scanner for file system analysis
|
# Add toolbox-specific volumes, ports, etc.
|
||||||
- **Hadolint** - Dockerfile linter for best practices
|
volumes:
|
||||||
|
- ./custom-config:/home/toolbox/.config/custom-tool
|
||||||
### Docker Analysis
|
|
||||||
- **Dockerfilelint** - Node.js-based Dockerfile linter
|
|
||||||
- **Docker** - Docker CLI with access to host Docker daemon via socket
|
|
||||||
- **Docker Buildx** - Docker CLI plugin for extended build capabilities
|
|
||||||
|
|
||||||
### Development Tools
|
|
||||||
- **Git** - Version control system
|
|
||||||
- **Zsh** - Interactive shell with Oh My Zsh framework
|
|
||||||
- **Mise** - Runtime manager for language versions
|
|
||||||
- **Aqua** - CLI tool manager
|
|
||||||
- **YQ** - YAML/JSON processor
|
|
||||||
- **JQ** - JSON processor
|
|
||||||
|
|
||||||
## 📋 QA Workflows
|
|
||||||
|
|
||||||
### Security Scanning
|
|
||||||
```bash
|
|
||||||
# Scan a Docker image with Trivy
|
|
||||||
trivy image <your-image-name>
|
|
||||||
|
|
||||||
# Scan a Dockerfile with Hadolint
|
|
||||||
hadolint Dockerfile
|
|
||||||
|
|
||||||
# Scan a Dockerfile with dockerfilelint
|
|
||||||
dockerfilelint Dockerfile
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Image Analysis
|
### SEED
|
||||||
```bash
|
Define the toolbox's purpose and goals:
|
||||||
# Analyze image layers and size
|
```markdown
|
||||||
docker history <your-image-name>
|
- Describe what this toolbox should provide (languages, CLIs, workflows)
|
||||||
|
- List required base image modifications or additional mounts
|
||||||
# Extract image contents for analysis
|
- Note verification or testing expectations specific to this toolbox
|
||||||
docker save <your-image-name> -o image.tar
|
|
||||||
tar -xf image.tar
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Best Practices Validation
|
---
|
||||||
The toolbox includes tools to validate Docker best practices:
|
|
||||||
- Hadolint for Dockerfile best practices
|
|
||||||
- Trivy for security vulnerabilities
|
|
||||||
- Docker's own best practices recommendations
|
|
||||||
|
|
||||||
## ⚙️ Configuration
|
## 📂 Project Layout
|
||||||
|
|
||||||
The toolbox is configured to:
|
| Path | Purpose |
|
||||||
- Run as a non-root user with host UID/GID mapping
|
|------|---------|
|
||||||
- Access the host Docker daemon via socket mounting
|
| `Dockerfile` | Extends base image with toolbox-specific tooling |
|
||||||
- Include both Docker build and runtime analysis tools
|
| `docker-compose.yml` | Service configuration for the toolbox |
|
||||||
- Follow security best practices (no sudo, minimal attack surface)
|
| `build.sh` | Wrapper around `docker build` with host UID/GID mapping |
|
||||||
|
| `run.sh` | Helper to bring the service up/down |
|
||||||
|
| `.devcontainer/devcontainer.json` | VS Code remote container definition |
|
||||||
|
| `SEED` | Defines the toolbox's purpose and goals |
|
||||||
|
| `PROMPT` | LLM onboarding prompt for future contributors |
|
||||||
|
|
||||||
## 🔐 Security Features
|
---
|
||||||
|
|
||||||
- Non-root user execution with UID/GID mapping
|
## 🤝 Collaboration Notes
|
||||||
- Sudo is removed from the final image
|
|
||||||
- Multi-stage build minimizing attack surface
|
|
||||||
- Regular security scanning capabilities
|
|
||||||
|
|
||||||
## 🤖 AI Agent
|
- Inherits all collaboration policies from `toolbox-base`
|
||||||
This toolbox is maintained by **ToolboxBot**, an AI agent focused on Docker QA tooling.
|
- Document toolbox-specific additions in `README.md` and `PROMPT`
|
||||||
|
- Update `SEED` only when the high-level objectives change
|
||||||
## 📄 License
|
- Prefer aqua/mise for new tooling to keep installations reproducible
|
||||||
See [LICENSE](../LICENSE) for full terms.
|
- Keep documentation synchronized for future contributors
|
||||||
@@ -1,26 +1,38 @@
|
|||||||
# Docker QA Toolbox SEED
|
# Toolbox Template SEED
|
||||||
|
|
||||||
## Purpose
|
This SEED file defines the high-level objectives for all toolboxes created from this template.
|
||||||
This toolbox is specifically designed for Docker image auditing, security scanning, and quality assurance. It provides a comprehensive set of tools to analyze, validate, and secure Docker images and Dockerfiles.
|
|
||||||
|
|
||||||
## Core Functionality
|
## 🎯 Goals
|
||||||
- Security scanning of Docker images using Trivy
|
|
||||||
- Linting of Dockerfiles using Hadolint and dockerfilelint
|
|
||||||
- Analysis of Docker image composition and layers
|
|
||||||
- Validation of Docker best practices
|
|
||||||
- Compliance checking against security standards
|
|
||||||
|
|
||||||
## Target Use Cases
|
- **Extensibility**: Each toolbox should extend from `toolbox-base` to inherit core tooling
|
||||||
- Pre-deployment security scanning of Docker images
|
- **Consistency**: All toolboxes should follow the same patterns and conventions
|
||||||
- Dockerfile quality validation in CI/CD pipelines
|
- **Reproducibility**: Toolbox builds should be deterministic and cache-efficient
|
||||||
- Docker image composition analysis
|
- **Security**: Toolboxes should run as non-root users with minimal privileges
|
||||||
- Security audit of existing container images
|
- **Portability**: Toolboxes should work identically across different host environments
|
||||||
- Verification of container best practices
|
|
||||||
|
|
||||||
## Key Tools
|
## 🧰 Requirements
|
||||||
- Trivy: Comprehensive vulnerability scanner
|
|
||||||
- Hadolint: Dockerfile linter for best practices
|
- **Base Image**: Extend from `tsysdevstack-toolboxstack-toolbox-base:release-current`
|
||||||
- Dockerfilelint: Additional Dockerfile validation
|
- **User Model**: Run as non-root `toolbox` user (UID/GID mapped to host)
|
||||||
- Docker CLI: Direct access to Docker daemon
|
- **Workspace**: Mount current directory to `/workspace` (read/write)
|
||||||
- Mise: Runtime version management
|
- **Runtime**: Inherit all base tooling plus toolbox-specific additions
|
||||||
- Aqua: CLI tool management
|
- **Configuration**: Preserve user configs/mise toolchains via volume mounts
|
||||||
|
|
||||||
|
## 🛠️ Implementation
|
||||||
|
|
||||||
|
- **Dockerfile**: Extend from base with toolbox-specific tooling
|
||||||
|
- **docker-compose.yml**: Configure service with inherited + custom settings
|
||||||
|
- **build.sh**: Wrapper around `docker build` with UID/GID mapping
|
||||||
|
- **run.sh**: Helper to bring service up/down
|
||||||
|
- **devcontainer.json**: VS Code remote container definition
|
||||||
|
- **SEED**: Define toolbox-specific objectives (this file)
|
||||||
|
- **PROMPT**: LLM onboarding prompt for future contributors
|
||||||
|
|
||||||
|
## ✅ Verification
|
||||||
|
|
||||||
|
- Toolboxes should build without errors
|
||||||
|
- Toolboxes should start and run indefinitely
|
||||||
|
- Toolboxes should be accessible via `docker exec`
|
||||||
|
- Toolboxes should inherit all base tooling
|
||||||
|
- Toolboxes should support toolbox-specific additions
|
||||||
|
- Toolboxes should preserve user configurations across restarts
|
||||||
@@ -3,20 +3,22 @@ registries:
|
|||||||
- type: standard
|
- type: standard
|
||||||
ref: v4.431.0
|
ref: v4.431.0
|
||||||
packages:
|
packages:
|
||||||
# Docker and container analysis tools
|
# Docker auditing and security tools
|
||||||
- name: aquasecurity/trivy@v0.54.1
|
- name: hadolint/hadolint@v2.12.0
|
||||||
- name: hadolint/hadolint@v2.14.0
|
- name: aquasecurity/trivy@v0.56.2
|
||||||
|
- name: anchore/grype@v0.84.1
|
||||||
# GitHub and collaboration tools
|
- name: docker/docker-bench-security@v1.8.0
|
||||||
- name: cli/cli@v2.82.1
|
- name: snyk/snyk@v1.1308.0
|
||||||
|
# General utility tools
|
||||||
# Environment and runtime management
|
- name: jesseduffield/lazygit@v0.44.0
|
||||||
- name: direnv/direnv@v2.37.1
|
- name: direnv/direnv@v2.35.0
|
||||||
- name: dandavison/delta@0.18.2
|
- name: dandavison/delta@0.18.2
|
||||||
- name: ajeetdsouza/zoxide@v0.9.8
|
- name: ajeetdsouza/zoxide@v0.9.6
|
||||||
|
- name: mikefarah/yq@v4.44.3
|
||||||
# Development and build tools
|
- name: ducaale/xh@v0.22.3
|
||||||
- name: mikefarah/yq@v4.48.0
|
- name: rs/curlie@v1.8.6
|
||||||
|
- name: koalaman/shellcheck@v0.10.0
|
||||||
# Configuration management
|
- name: mvdan/sh@v3.7.0
|
||||||
- name: twpayne/chezmoi@v2.66.1
|
- name: golangci/golangci-lint@v1.60.3
|
||||||
|
- name: golang/go@go1.23.0
|
||||||
|
- name: cli/cli@v2.57.0
|
||||||
@@ -25,7 +25,12 @@ if ! docker buildx version &> /dev/null; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
IMAGE_NAME="tsysdevstack-toolboxstack-toolbox-qadocker"
|
# Get the toolbox name from the directory name (or you can pass it as an argument)
|
||||||
|
TOOLBOX_NAME="${TOOLBOX_NAME_OVERRIDE:-$(basename "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")}"
|
||||||
|
sanitized_input "$TOOLBOX_NAME"
|
||||||
|
# Convert to lowercase and replace any uppercase letters to ensure valid Docker image name
|
||||||
|
IMAGE_NAME_RAW="tsysdevstack-toolboxstack-${TOOLBOX_NAME#toolbox-}"
|
||||||
|
IMAGE_NAME=$(echo "$IMAGE_NAME_RAW" | tr '[:upper:]' '[:lower:]')
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
# Sanitize user input
|
# Sanitize user input
|
||||||
@@ -37,7 +42,7 @@ USERNAME="${USERNAME_OVERRIDE:-toolbox}"
|
|||||||
sanitized_input "$USERNAME"
|
sanitized_input "$USERNAME"
|
||||||
TEA_VERSION="${TEA_VERSION_OVERRIDE:-0.11.1}"
|
TEA_VERSION="${TEA_VERSION_OVERRIDE:-0.11.1}"
|
||||||
sanitized_input "$TEA_VERSION"
|
sanitized_input "$TEA_VERSION"
|
||||||
BUILDER_NAME="${BUILDER_NAME:-tsysdevstack-builder}"
|
BUILDER_NAME="${BUILDER_NAME:-tsysdevstack-toolboxstack-builder}"
|
||||||
sanitized_input "$BUILDER_NAME"
|
sanitized_input "$BUILDER_NAME"
|
||||||
CACHE_DIR="${SCRIPT_DIR}/.build-cache"
|
CACHE_DIR="${SCRIPT_DIR}/.build-cache"
|
||||||
TAG="${TAG_OVERRIDE:-dev}"
|
TAG="${TAG_OVERRIDE:-dev}"
|
||||||
@@ -97,64 +102,36 @@ fi
|
|||||||
|
|
||||||
echo "Build completed successfully."
|
echo "Build completed successfully."
|
||||||
|
|
||||||
# Run comprehensive verification tests
|
# Run post-build verification
|
||||||
echo "Running comprehensive verification tests..."
|
echo "Running post-build verification..."
|
||||||
if ! docker run --rm "${IMAGE_NAME}:${TAG}" zsh -c 'echo "Container starts successfully as $(whoami) user"'; then
|
if ! docker run --rm "${IMAGE_NAME}:${TAG}" bash -c 'echo "Container starts successfully"'; then
|
||||||
echo "Error: Failed to start container with basic test." >&2
|
echo "Error: Failed to start container with basic test." >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Verify core tools are available to toolbox user
|
# Verify critical tools for Docker auditing are available
|
||||||
echo "Verifying core tools for toolbox user..."
|
echo "Verifying Docker auditing tools..."
|
||||||
CORE_TOOLS=("zsh" "git" "curl" "jq" "docker" "trivy" "hadolint")
|
CRITICAL_TOOLS=("git" "curl" "wget" "docker" "hadolint" "dive" "bash")
|
||||||
for tool in "${CORE_TOOLS[@]}"; do
|
for tool in "${CRITICAL_TOOLS[@]}"; do
|
||||||
if ! docker run --rm "${IMAGE_NAME}:${TAG}" su - toolbox -c "which $tool" >/dev/null 2>&1; then
|
if ! docker run --rm "${IMAGE_NAME}:${TAG}" which "$tool" >/dev/null 2>&1; then
|
||||||
echo "Error: Core tool '$tool' not found in PATH for toolbox user." >&2
|
echo "Error: Critical Docker auditing tool '$tool' not found in PATH." >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
# Verify Docker QA tools are available to toolbox user
|
# Verify additional aqua tools for QA are available
|
||||||
echo "Verifying Docker QA tools for toolbox user..."
|
echo "Verifying QA aqua tools..."
|
||||||
QA_TOOLS=("dockerfilelint" "yq")
|
AQUA_TOOLS=("lazygit" "direnv" "delta" "zoxide" "yq" "xh" "curlie" "shellcheck" "trivy" "grype" "docker-bench-security")
|
||||||
for tool in "${QA_TOOLS[@]}"; do
|
for tool in "${AQUA_TOOLS[@]}"; do
|
||||||
if ! docker run --rm "${IMAGE_NAME}:${TAG}" su - toolbox -c "which $tool" >/dev/null 2>&1; then
|
if ! docker run --rm "${IMAGE_NAME}:${TAG}" which "$tool" >/dev/null 2>&1; then
|
||||||
echo "Error: QA tool '$tool' not found in PATH for toolbox user." >&2
|
echo "Error: QA aqua tool '$tool' not found in PATH." >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
# Verify Node.js and npm are working properly
|
echo "All verifications passed."
|
||||||
echo "Verifying Node.js runtime..."
|
|
||||||
if ! docker run --rm "${IMAGE_NAME}:${TAG}" su - toolbox -c "node --version && npm --version" >/dev/null 2>&1; then
|
|
||||||
echo "Error: Node.js or npm not working properly for toolbox user." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Verify mise is managing tools properly
|
|
||||||
echo "Verifying mise runtime management..."
|
|
||||||
if ! docker run --rm "${IMAGE_NAME}:${TAG}" su - toolbox -c "mise --version" >/dev/null 2>&1; then
|
|
||||||
echo "Error: Mise not available for toolbox user." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Verify aqua is managing tools properly
|
|
||||||
echo "Verifying aqua package management..."
|
|
||||||
if ! docker run --rm "${IMAGE_NAME}:${TAG}" su - toolbox -c "aqua --version" >/dev/null 2>&1; then
|
|
||||||
echo "Error: Aqua not available for toolbox user." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Final security check: verify container runs as toolbox user
|
|
||||||
echo "Verifying runtime security model..."
|
|
||||||
RUNTIME_USER=$(docker run --rm "${IMAGE_NAME}:${TAG}" whoami)
|
|
||||||
if [ "$RUNTIME_USER" != "toolbox" ]; then
|
|
||||||
echo "Error: Container is not running as toolbox user. Current user: $RUNTIME_USER" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "All verifications passed. Security model is correct."
|
|
||||||
|
|
||||||
|
# Push if requested
|
||||||
if [[ "${PUSH}" == "true" ]]; then
|
if [[ "${PUSH}" == "true" ]]; then
|
||||||
echo "Pushing ${IMAGE_NAME}:${TAG}"
|
echo "Pushing ${IMAGE_NAME}:${TAG}"
|
||||||
if ! docker push "${IMAGE_NAME}:${TAG}"; then
|
if ! docker push "${IMAGE_NAME}:${TAG}"; then
|
||||||
@@ -195,4 +172,4 @@ else
|
|||||||
echo "Trivy not found. Install Trivy to perform security scanning."
|
echo "Trivy not found. Install Trivy to perform security scanning."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Build process completed successfully with all verifications and security checks."
|
echo "Build process completed successfully with all verifications."
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
services:
|
services:
|
||||||
toolbox-qadocker:
|
{{toolbox_name}}:
|
||||||
container_name: tsysdevstack-toolboxstack-toolbox-qadocker
|
container_name: tsysdevstack-toolboxstack-{{toolbox_name}}
|
||||||
image: ${TOOLBOX_IMAGE:-tsysdevstack-toolboxstack-toolbox-qadocker:release-current}
|
image: tsysdevstack-toolboxstack-{{toolbox_name}}
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
args:
|
args:
|
||||||
USER_ID: ${LOCAL_UID:-1000}
|
USER_ID: ${LOCAL_UID:-1000}
|
||||||
GROUP_ID: ${LOCAL_GID:-1000}
|
GROUP_ID: ${LOCAL_GID:-1000}
|
||||||
@@ -16,8 +17,19 @@ services:
|
|||||||
stdin_open: true
|
stdin_open: true
|
||||||
volumes:
|
volumes:
|
||||||
- .:/workspace:rw
|
- .:/workspace:rw
|
||||||
- /var/run/docker.sock:/var/run/docker.sock:rw
|
|
||||||
- ${HOME}/.local/share/mise:/home/toolbox/.local/share/mise:rw
|
- ${HOME}/.local/share/mise:/home/toolbox/.local/share/mise:rw
|
||||||
- ${HOME}/.cache/mise:/home/toolbox/.cache/mise:rw
|
- ${HOME}/.cache/mise:/home/toolbox/.cache/mise:rw
|
||||||
# Aqua configuration
|
# AI CLI tool configuration and cache directories
|
||||||
- ${HOME}/.config/aquaproj-aqua:/home/toolbox/.config/aquaproj-aqua:rw
|
- ${HOME}/.config/openai:/home/toolbox/.config/openai:rw
|
||||||
|
- ${HOME}/.config/gemini:/home/toolbox/.config/gemini:rw
|
||||||
|
- ${HOME}/.config/qwen:/home/toolbox/.config/qwen:rw
|
||||||
|
- ${HOME}/.config/code:/home/toolbox/.config/code:rw
|
||||||
|
- ${HOME}/.config/opencode:/home/toolbox/.config/opencode:rw
|
||||||
|
- ${HOME}/.cache/openai:/home/toolbox/.cache/openai:rw
|
||||||
|
- ${HOME}/.cache/gemini:/home/toolbox/.cache/gemini:rw
|
||||||
|
- ${HOME}/.cache/qwen:/home/toolbox/.cache/qwen:rw
|
||||||
|
- ${HOME}/.cache/code:/home/toolbox/.cache/code:rw
|
||||||
|
- ${HOME}/.cache/opencode:/home/toolbox/.cache/opencode:rw
|
||||||
|
# Additional AI tool directories
|
||||||
|
- ${HOME}/.config/codex:/home/toolbox/.config/codex:rw
|
||||||
|
- ${HOME}/.cache/codex:/home/toolbox/.cache/codex:rw
|
||||||
@@ -2,34 +2,110 @@
|
|||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
# Validate input parameters
|
usage() {
|
||||||
if [ "$#" -ne 1 ]; then
|
cat <<'EOU'
|
||||||
echo "Usage: $0 <version-tag>"
|
Usage: ./release.sh [--dry-run] [--allow-dirty] <semver>
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
./release.sh 0.2.0
|
||||||
|
./release.sh --dry-run 0.2.0
|
||||||
|
|
||||||
|
This script rebuilds the toolbox image, tags it as:
|
||||||
|
- tsysdevstack-toolboxstack-<name>:dev
|
||||||
|
- tsysdevstack-toolboxstack-<name>:release-current
|
||||||
|
- tsysdevstack-toolboxstack-<name>:v<semver>
|
||||||
|
|
||||||
|
When run without --dry-run it pushes all three tags.
|
||||||
|
EOU
|
||||||
|
}
|
||||||
|
|
||||||
|
DRY_RUN=false
|
||||||
|
ALLOW_DIRTY=false
|
||||||
|
VERSION=""
|
||||||
|
|
||||||
|
while (( $# > 0 )); do
|
||||||
|
case "$1" in
|
||||||
|
--dry-run)
|
||||||
|
DRY_RUN=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--allow-dirty)
|
||||||
|
ALLOW_DIRTY=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-h|--help)
|
||||||
|
usage
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
-*)
|
||||||
|
echo "Unknown option: $1" >&2
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
VERSION="$1"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ -z "${VERSION}" ]]; then
|
||||||
|
echo "Error: semantic version is required." >&2
|
||||||
|
usage
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
VERSION="$1"
|
if [[ "${VERSION}" =~ ^v?([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then
|
||||||
IMAGE_NAME="tsysdevstack-toolboxstack-toolbox-qadocker"
|
SEMVER="v${BASH_REMATCH[1]}.${BASH_REMATCH[2]}.${BASH_REMATCH[3]}"
|
||||||
|
else
|
||||||
# Build the image with the version tag
|
echo "Error: version must be semantic (e.g., 0.2.0 or v0.2.0)." >&2
|
||||||
echo "Building ${IMAGE_NAME}:${VERSION}"
|
|
||||||
if ! docker build --tag "${IMAGE_NAME}:${VERSION}" .; then
|
|
||||||
echo "Error: Failed to build ${IMAGE_NAME}:${VERSION}" >&2
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Run tests
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
echo "Running tests..."
|
REPO_ROOT="$(cd "${SCRIPT_DIR}" && git rev-parse --show-toplevel 2>/dev/null || true)"
|
||||||
if ! ./test.sh; then
|
|
||||||
echo "Error: Tests failed for ${IMAGE_NAME}:${VERSION}" >&2
|
if [[ -n "${REPO_ROOT}" && "${ALLOW_DIRTY}" != "true" ]]; then
|
||||||
exit 1
|
if ! git -C "${REPO_ROOT}" diff --quiet --ignore-submodules --exit-code; then
|
||||||
|
echo "Error: git working tree has uncommitted changes. Please commit or stash before releasing." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
elif [[ -z "${REPO_ROOT}" ]]; then
|
||||||
|
echo "Warning: unable to resolve git repository root; skipping clean tree check." >&2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Create release tag
|
# Get the toolbox name from the directory name (or you can pass it as an argument)
|
||||||
echo "Creating release tag..."
|
TOOLBOX_NAME="${TOOLBOX_NAME_OVERRIDE:-$(basename "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")}"
|
||||||
if ! docker tag "${IMAGE_NAME}:${VERSION}" "${IMAGE_NAME}:release-current"; then
|
IMAGE_NAME="tsysdevstack-toolboxstack-${TOOLBOX_NAME#toolbox-}"
|
||||||
echo "Error: Failed to create release tag for ${IMAGE_NAME}" >&2
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Release ${IMAGE_NAME}:${VERSION} completed successfully!"
|
USER_ID="${USER_ID_OVERRIDE:-$(id -u)}"
|
||||||
|
GROUP_ID="${GROUP_ID_OVERRIDE:-$(id -g)}"
|
||||||
|
USERNAME="${USERNAME_OVERRIDE:-toolbox}"
|
||||||
|
TEA_VERSION="${TEA_VERSION_OVERRIDE:-0.11.1}"
|
||||||
|
BUILDER_NAME="${BUILDER_NAME:-tsysdevstack-toolboxstack-builder}"
|
||||||
|
CACHE_DIR="${SCRIPT_DIR}/.build-cache"
|
||||||
|
TAG="${TAG_OVERRIDE:-dev}"
|
||||||
|
RELEASE_TAG="${RELEASE_TAG_OVERRIDE:-release-current}"
|
||||||
|
VERSION_TAG="${VERSION_TAG_OVERRIDE:-}"
|
||||||
|
if [[ -n "$VERSION_TAG" ]]; then
|
||||||
|
VERSION_TAG="$SEMVER"
|
||||||
|
fi
|
||||||
|
PUSH="${PUSH_OVERRIDE:-false}"
|
||||||
|
|
||||||
|
echo "Preparing release for ${SEMVER}"
|
||||||
|
echo " dry-run: ${DRY_RUN}"
|
||||||
|
echo " allow-dirty: ${ALLOW_DIRTY}"
|
||||||
|
|
||||||
|
if [[ "${DRY_RUN}" == "true" ]]; then
|
||||||
|
echo "[dry-run] Would build ${IMAGE_NAME}:${TAG}"
|
||||||
|
TAG_OVERRIDE="${TAG}" PUSH_OVERRIDE=false "${SCRIPT_DIR}/build.sh"
|
||||||
|
echo "[dry-run] Skipped pushing tags."
|
||||||
|
else
|
||||||
|
echo "Building ${IMAGE_NAME}:${TAG}"
|
||||||
|
TAG_OVERRIDE="${TAG}" PUSH_OVERRIDE=true RELEASE_TAG_OVERRIDE="${RELEASE_TAG}" VERSION_TAG_OVERRIDE="${SEMVER}" "${SCRIPT_DIR}/build.sh"
|
||||||
|
echo "Release ${SEMVER} pushed as:"
|
||||||
|
echo " - ${IMAGE_NAME}:dev"
|
||||||
|
echo " - ${IMAGE_NAME}:release-current"
|
||||||
|
echo " - ${IMAGE_NAME}:${SEMVER}"
|
||||||
|
fi
|
||||||
@@ -28,14 +28,13 @@ fi
|
|||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
COMPOSE_FILE="${SCRIPT_DIR}/docker-compose.yml"
|
COMPOSE_FILE="${SCRIPT_DIR}/docker-compose.yml"
|
||||||
|
|
||||||
# Sanitize user input
|
|
||||||
export LOCAL_UID="${USER_ID_OVERRIDE:-$(id -u)}"
|
export LOCAL_UID="${USER_ID_OVERRIDE:-$(id -u)}"
|
||||||
sanitized_input "$LOCAL_UID"
|
sanitized_input "$LOCAL_UID"
|
||||||
export LOCAL_GID="${GROUP_ID_OVERRIDE:-$(id -g)}"
|
export LOCAL_GID="${GROUP_ID_OVERRIDE:-$(id -g)}"
|
||||||
sanitized_input "$LOCAL_GID"
|
sanitized_input "$LOCAL_GID"
|
||||||
export LOCAL_USERNAME="${USERNAME_OVERRIDE:-toolbox}"
|
export LOCAL_USERNAME="${USERNAME_OVERRIDE:-toolbox}"
|
||||||
sanitized_input "$LOCAL_USERNAME"
|
sanitized_input "$LOCAL_USERNAME"
|
||||||
export TOOLBOX_IMAGE="${TOOLBOX_IMAGE_OVERRIDE:-tsysdevstack-toolboxstack-toolbox-qadocker:release-current}"
|
export TOOLBOX_IMAGE="${TOOLBOX_IMAGE_OVERRIDE:-tsysdevstack-toolboxstack-{{toolbox_name}}}"
|
||||||
sanitized_input "$TOOLBOX_IMAGE"
|
sanitized_input "$TOOLBOX_IMAGE"
|
||||||
|
|
||||||
if [[ ! -f "${COMPOSE_FILE}" ]]; then
|
if [[ ! -f "${COMPOSE_FILE}" ]]; then
|
||||||
@@ -50,13 +49,19 @@ shift || true
|
|||||||
if [[ "${ACTION}" == "up" ]]; then
|
if [[ "${ACTION}" == "up" ]]; then
|
||||||
# Create necessary directories for the toolbox tools with proper permissions
|
# Create necessary directories for the toolbox tools with proper permissions
|
||||||
mkdir -p "${HOME}/.local/share/mise" "${HOME}/.cache/mise"
|
mkdir -p "${HOME}/.local/share/mise" "${HOME}/.cache/mise"
|
||||||
mkdir -p "${HOME}/.config/aquaproj-aqua"
|
mkdir -p "${HOME}/.config" "${HOME}/.local/share"
|
||||||
|
mkdir -p "${HOME}/.cache/openai" "${HOME}/.cache/gemini" "${HOME}/.cache/qwen" "${HOME}/.cache/code" "${HOME}/.cache/opencode"
|
||||||
|
mkdir -p "${HOME}/.config/openai" "${HOME}/.config/gemini" "${HOME}/.config/qwen" "${HOME}/.config/code" "${HOME}/.config/opencode"
|
||||||
|
mkdir -p "${HOME}/.config/codex" "${HOME}/.cache/codex"
|
||||||
|
|
||||||
|
# Set proper permissions for created directories
|
||||||
|
chmod 700 "${HOME}/.config" "${HOME}/.local/share" "${HOME}/.cache" 2>/dev/null || true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
case "${ACTION}" in
|
case "${ACTION}" in
|
||||||
up)
|
up)
|
||||||
docker compose -f "${COMPOSE_FILE}" up --build --detach "$@"
|
docker compose -f "${COMPOSE_FILE}" up --build --detach "$@"
|
||||||
echo "Container started. Use 'docker exec -it tsysdevstack-toolboxstack-toolbox-qadocker zsh' to access the shell."
|
echo "Container started. Use 'docker exec -it tsysdevstack-toolboxstack-{{toolbox_name}} zsh' to access the shell."
|
||||||
;;
|
;;
|
||||||
down)
|
down)
|
||||||
docker compose -f "${COMPOSE_FILE}" down "$@"
|
docker compose -f "${COMPOSE_FILE}" down "$@"
|
||||||
|
|||||||
@@ -2,41 +2,154 @@
|
|||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
echo "Running security audit on the current environment..."
|
# Security audit script for the toolbox-template
|
||||||
|
|
||||||
# Check for any security issues with the current setup
|
IMAGE_NAME="${IMAGE_NAME_OVERRIDE:-tsysdevstack-toolboxstack-{{toolbox_name}}}"
|
||||||
echo "Checking for common security issues..."
|
|
||||||
|
|
||||||
# Check if running as root (should not be)
|
echo "🔒 Running security audit on ${IMAGE_NAME}"
|
||||||
if [ "$EUID" -eq 0 ]; then
|
|
||||||
echo "WARNING: Running as root user" >&2
|
|
||||||
exit 1
|
|
||||||
else
|
|
||||||
echo "✓ Running as non-root user"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check for sudo access (should not have)
|
# Check if Trivy is available for security scanning
|
||||||
if command -v sudo &> /dev/null; then
|
|
||||||
echo "WARNING: Sudo is available in the container" >&2
|
|
||||||
exit 1
|
|
||||||
else
|
|
||||||
echo "✓ Sudo correctly removed from container"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Verify important security tools are available
|
|
||||||
echo "Checking for security tools..."
|
|
||||||
if command -v trivy &> /dev/null; then
|
if command -v trivy &> /dev/null; then
|
||||||
echo "✓ Trivy security scanner available"
|
echo "🔍 Running Trivy security scan..."
|
||||||
|
trivy image --exit-code 0 --severity HIGH,CRITICAL "${IMAGE_NAME}"
|
||||||
|
echo "✅ Trivy scan completed"
|
||||||
else
|
else
|
||||||
echo "✗ Trivy security scanner not available" >&2
|
echo "⚠️ Trivy not found. Install Trivy to perform security scanning."
|
||||||
exit 1
|
echo " Visit https://aquasecurity.github.io/trivy/ for installation instructions."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if command -v hadolint &> /dev/null; then
|
# Check for outdated packages
|
||||||
echo "✓ Hadolint Dockerfile linter available"
|
echo "📦 Checking for outdated packages..."
|
||||||
|
OUTDATED_PACKAGES=$(docker run --rm "${IMAGE_NAME}" apt list --upgradable 2>/dev/null | grep -v "Listing..." | wc -l)
|
||||||
|
if [[ "${OUTDATED_PACKAGES}" -gt 0 ]]; then
|
||||||
|
echo "⚠️ ${OUTDATED_PACKAGES} packages can be upgraded"
|
||||||
|
echo " Run 'apt update && apt upgrade' to update packages"
|
||||||
else
|
else
|
||||||
echo "✗ Hadolint Dockerfile linter not available" >&2
|
echo "✅ All system packages are up to date"
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Security audit completed successfully!"
|
# Check for unnecessary packages that increase attack surface
|
||||||
|
echo "🛡️ Checking for unnecessary packages..."
|
||||||
|
UNNECESSARY_PACKAGES=$(docker run --rm "${IMAGE_NAME}" dpkg -l | grep -E "(telnet|ftp|rsh-client|nfs-common|rpcbind)" | wc -l)
|
||||||
|
if [[ "${UNNECESSARY_PACKAGES}" -gt 0 ]]; then
|
||||||
|
echo "⚠️ Found ${UNNECESSARY_PACKAGES} potentially unnecessary packages that increase attack surface"
|
||||||
|
echo " Consider removing packages like telnet, ftp, rsh-client, nfs-common, rpcbind"
|
||||||
|
else
|
||||||
|
echo "✅ No unnecessary packages found that increase attack surface"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check for world-writable files/directories
|
||||||
|
echo "📁 Checking for world-writable files/directories..."
|
||||||
|
WORLD_WRITABLE=$(docker run --rm "${IMAGE_NAME}" find / -xdev -type f -perm -0002 -not -path "/proc/*" -not -path "/sys/*" 2>/dev/null | wc -l)
|
||||||
|
if [[ "${WORLD_WRITABLE}" -gt 0 ]]; then
|
||||||
|
echo "⚠️ Found ${WORLD_WRITABLE} world-writable files/directories"
|
||||||
|
echo " These should be reviewed and permissions adjusted if necessary"
|
||||||
|
else
|
||||||
|
echo "✅ No world-writable files/directories found"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check for setuid/setgid binaries
|
||||||
|
echo "🔑 Checking for setuid/setgid binaries..."
|
||||||
|
SETUID_BINARIES=$(docker run --rm "${IMAGE_NAME}" find / -xdev \( -perm -4000 -o -perm -2000 \) -type f -not -path "/proc/*" -not -path "/sys/*" 2>/dev/null | wc -l)
|
||||||
|
if [[ "${SETUID_BINARIES}" -gt 0 ]]; then
|
||||||
|
echo "⚠️ Found ${SETUID_BINARIES} setuid/setgid binaries"
|
||||||
|
echo " These should be reviewed for security implications"
|
||||||
|
else
|
||||||
|
echo "✅ No setuid/setgid binaries found"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check for running services
|
||||||
|
echo "サービ Checking for running services..."
|
||||||
|
RUNNING_SERVICES=$(docker run --rm "${IMAGE_NAME}" ps aux 2>/dev/null | grep -v "PID" | wc -l)
|
||||||
|
if [[ "${RUNNING_SERVICES}" -gt 1 ]]; then
|
||||||
|
echo "⚠️ Found ${RUNNING_SERVICES} running processes"
|
||||||
|
echo " These should be reviewed for necessity"
|
||||||
|
else
|
||||||
|
echo "✅ No unnecessary running services found"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check for listening ports
|
||||||
|
echo "📡 Checking for listening ports..."
|
||||||
|
LISTENING_PORTS=$(docker run --rm "${IMAGE_NAME}" netstat -tuln 2>/dev/null | grep LISTEN | wc -l)
|
||||||
|
if [[ "${LISTENING_PORTS}" -gt 0 ]]; then
|
||||||
|
echo "⚠️ Found ${LISTENING_PORTS} listening ports"
|
||||||
|
echo " These should be reviewed for security implications"
|
||||||
|
else
|
||||||
|
echo "✅ No unnecessary listening ports found"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check for sudo availability
|
||||||
|
echo "🛑 Checking for sudo availability..."
|
||||||
|
if docker run --rm "${IMAGE_NAME}" which sudo >/dev/null 2>&1; then
|
||||||
|
echo "❌ Sudo is available in the image - this is a security risk"
|
||||||
|
echo " Sudo should be removed to prevent privilege escalation"
|
||||||
|
else
|
||||||
|
echo "✅ Sudo is not available in the image"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check for root login capability
|
||||||
|
echo "🔐 Checking for root login capability..."
|
||||||
|
ROOT_LOGIN_ENABLED=$(docker run --rm "${IMAGE_NAME}" cat /etc/passwd | grep root | grep -v "nologin" | wc -l)
|
||||||
|
if [[ "${ROOT_LOGIN_ENABLED}" -gt 0 ]]; then
|
||||||
|
echo "⚠️ Root login might be enabled"
|
||||||
|
echo " Ensure root login is disabled for security"
|
||||||
|
else
|
||||||
|
echo "✅ Root login is properly disabled"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check user configuration
|
||||||
|
echo "👤 Checking user configuration..."
|
||||||
|
USER_ID=$(docker run --rm "${IMAGE_NAME}" id -u toolbox 2>/dev/null || echo "not_found")
|
||||||
|
if [[ "${USER_ID}" == "1000" ]]; then
|
||||||
|
echo "✅ Non-root user 'toolbox' with UID 1000 is properly configured"
|
||||||
|
else
|
||||||
|
echo "⚠️ Non-root user configuration might be incorrect"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check for hardcoded passwords
|
||||||
|
echo "🔑 Checking for hardcoded passwords..."
|
||||||
|
HARDCODED_PASSWORDS=$(docker run --rm "${IMAGE_NAME}" grep -r "password\|passwd" /etc/ 2>/dev/null | grep -v "shadow" | wc -l)
|
||||||
|
if [[ "${HARDCODED_PASSWORDS}" -gt 0 ]]; then
|
||||||
|
echo "⚠️ Found ${HARDCODED_PASSWORDS} potential hardcoded password references"
|
||||||
|
echo " These should be reviewed for security implications"
|
||||||
|
else
|
||||||
|
echo "✅ No hardcoded password references found"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check for exposed secrets
|
||||||
|
echo " секр Checking for exposed secrets..."
|
||||||
|
EXPOSED_SECRETS=$(docker run --rm "${IMAGE_NAME}" find / -xdev -type f -name "*.key" -o -name "*.pem" -o -name "*.cert" 2>/dev/null | wc -l)
|
||||||
|
if [[ "${EXPOSED_SECRETS}" -gt 0 ]]; then
|
||||||
|
echo "⚠️ Found ${EXPOSED_SECRETS} potential secret files"
|
||||||
|
echo " These should be reviewed for security implications"
|
||||||
|
else
|
||||||
|
echo "✅ No exposed secret files found"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check that this template properly extends from the base image
|
||||||
|
echo "🔗 Checking inheritance from base image..."
|
||||||
|
BASE_INHERITANCE=$(docker history "${IMAGE_NAME}" 2>/dev/null | grep "FROM tsysdevstack-toolboxstack-toolbox-base:release-current" | wc -l)
|
||||||
|
if [[ "${BASE_INHERITANCE}" -gt 0 ]]; then
|
||||||
|
echo "✅ Template properly extends from toolbox-base:release-current"
|
||||||
|
else
|
||||||
|
echo "⚠️ Template might not properly extend from toolbox-base:release-current"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Summary
|
||||||
|
echo ""
|
||||||
|
echo "🔒 Security Audit Summary:"
|
||||||
|
echo " - Image: ${IMAGE_NAME}"
|
||||||
|
echo " - Scan completed with recommendations above"
|
||||||
|
echo ""
|
||||||
|
echo "💡 Recommendations:"
|
||||||
|
echo " 1. Install Trivy for comprehensive security scanning"
|
||||||
|
echo " 2. Regularly update packages to address vulnerabilities"
|
||||||
|
echo " 3. Remove unnecessary packages to reduce attack surface"
|
||||||
|
echo " 4. Review world-writable files/directories"
|
||||||
|
echo " 5. Review setuid/setgid binaries"
|
||||||
|
echo " 6. Remove sudo to prevent privilege escalation"
|
||||||
|
echo " 7. Ensure root login is disabled"
|
||||||
|
echo " 8. Verify non-root user configuration"
|
||||||
|
echo " 9. Review hardcoded password references"
|
||||||
|
echo " 10. Check for exposed secrets"
|
||||||
|
echo " 11. Ensure proper inheritance from base image"
|
||||||
@@ -2,40 +2,111 @@
|
|||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
echo "Testing toolbox-QADocker functionality..."
|
# Test script to verify all tools are working properly in the toolbox-template
|
||||||
|
|
||||||
# Test core tools availability
|
IMAGE_NAME="${IMAGE_NAME_OVERRIDE:-tsysdevstack-toolboxstack-{{toolbox_name}}}"
|
||||||
echo "Testing core tools..."
|
|
||||||
if ! command -v zsh &> /dev/null; then
|
echo "🧪 Testing all tools in ${IMAGE_NAME}"
|
||||||
echo "Error: zsh is not available" >&2
|
|
||||||
|
# Function to test a command
|
||||||
|
test_cmd() {
|
||||||
|
local cmd="$1"
|
||||||
|
local description="$2"
|
||||||
|
|
||||||
|
echo -n "Testing ${cmd} (${description})... "
|
||||||
|
|
||||||
|
if docker run --rm "${IMAGE_NAME}" "${cmd}" --version >/dev/null 2>&1; then
|
||||||
|
echo "✅ PASS"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
echo "❌ FAIL"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to test a command with specific args
|
||||||
|
test_cmd_args() {
|
||||||
|
local cmd="$1"
|
||||||
|
local args="$2"
|
||||||
|
local description="$3"
|
||||||
|
|
||||||
|
echo -n "Testing ${cmd} ${args} (${description})... "
|
||||||
|
|
||||||
|
if docker run --rm "${IMAGE_NAME}" "${cmd}" ${args} >/dev/null 2>&1; then
|
||||||
|
echo "✅ PASS"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
echo "❌ FAIL"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Counter for tracking results
|
||||||
|
PASSED=0
|
||||||
|
FAILED=0
|
||||||
|
|
||||||
|
# Test core tools inherited from base
|
||||||
|
echo "🔍 Testing core tools inherited from base..."
|
||||||
|
|
||||||
|
test_cmd "zsh" "Z shell" && ((PASSED++)) || ((FAILED++))
|
||||||
|
test_cmd "git" "Git version control" && ((PASSED++)) || ((FAILED++))
|
||||||
|
test_cmd "curl" "cURL utility" && ((PASSED++)) || ((FAILED++))
|
||||||
|
test_cmd "jq" "JSON processor" && ((PASSED++)) || ((FAILED++))
|
||||||
|
test_cmd "fish" "Fish shell" && ((PASSED++)) || ((FAILED++))
|
||||||
|
test_cmd "fzf" "Fuzzy finder" && ((PASSED++)) || ((FAILED++))
|
||||||
|
test_cmd "bat" "Cat clone with wings" && ((PASSED++)) || ((FAILED++))
|
||||||
|
test_cmd "fd" "Simple, fast alternative to find" && ((PASSED++)) || ((FAILED++))
|
||||||
|
test_cmd "rg" "Ripgrep - line-oriented search tool" && ((PASSED++)) || ((FAILED++))
|
||||||
|
test_cmd "htop" "Interactive process viewer" && ((PASSED++)) || ((FAILED++))
|
||||||
|
test_cmd "btop" "Modern and colorful terminal monitor" && ((PASSED++)) || ((FAILED++))
|
||||||
|
|
||||||
|
# Test aqua installed tools inherited from base
|
||||||
|
echo "🔧 Testing aqua installed tools inherited from base..."
|
||||||
|
|
||||||
|
test_cmd "gh" "GitHub CLI" && ((PASSED++)) || ((FAILED++))
|
||||||
|
test_cmd "lazygit" "Simple terminal UI for git commands" && ((PASSED++)) || ((FAILED++))
|
||||||
|
test_cmd "direnv" "Unclutter your .profile" && ((PASSED++)) || ((FAILED++))
|
||||||
|
test_cmd "delta" "Syntax-highlighting pager for git, diff, and grep output" && ((PASSED++)) || ((FAILED++))
|
||||||
|
test_cmd "zoxide" "Smarter cd command" && ((PASSED++)) || ((FAILED++))
|
||||||
|
test_cmd "just" "Just a command runner" && ((PASSED++)) || ((FAILED++))
|
||||||
|
test_cmd "yq" "Portable command-line YAML processor" && ((PASSED++)) || ((FAILED++))
|
||||||
|
test_cmd "xh" "Friendly and fast tool for sending HTTP requests" && ((PASSED++)) || ((FAILED++))
|
||||||
|
test_cmd "curlie" "The power of curl, the ease of use of httpie" && ((PASSED++)) || ((FAILED++))
|
||||||
|
test_cmd "chezmoi" "Manage your dotfiles across multiple machines" && ((PASSED++)) || ((FAILED++))
|
||||||
|
test_cmd "shfmt" "Shell formatter" && ((PASSED++)) || ((FAILED++))
|
||||||
|
test_cmd "shellcheck" "Shell script analysis tool" && ((PASSED++)) || ((FAILED++))
|
||||||
|
test_cmd "hadolint" "Dockerfile linter" && ((PASSED++)) || ((FAILED++))
|
||||||
|
test_cmd "uv" "Python package installer and resolver" && ((PASSED++)) || ((FAILED++))
|
||||||
|
test_cmd "watchexec" "Execute commands in response to file modifications" && ((PASSED++)) || ((FAILED++))
|
||||||
|
test_cmd "tea" "Gitea CLI" && ((PASSED++)) || ((FAILED++))
|
||||||
|
|
||||||
|
# Test AI CLI tools inherited from base
|
||||||
|
echo "🤖 Testing AI CLI tools inherited from base..."
|
||||||
|
|
||||||
|
test_cmd_args "code" "--version" "just-every/code AI CLI" && ((PASSED++)) || ((FAILED++))
|
||||||
|
test_cmd_args "qwen" "--version" "QwenLM/qwen-code AI CLI" && ((PASSED++)) || ((FAILED++))
|
||||||
|
test_cmd_args "gemini" "--version" "google-gemini/gemini-cli AI CLI" && ((PASSED++)) || ((FAILED++))
|
||||||
|
test_cmd_args "codex" "--version" "openai/codex AI CLI" && ((PASSED++)) || ((FAILED++))
|
||||||
|
test_cmd_args "opencode" "--version" "sst/opencode AI CLI" && ((PASSED++)) || ((FAILED++))
|
||||||
|
|
||||||
|
# Test additional tools inherited from base
|
||||||
|
echo "🧰 Testing additional tools inherited from base..."
|
||||||
|
|
||||||
|
test_cmd "starship" "Cross-shell prompt" && ((PASSED++)) || ((FAILED++))
|
||||||
|
test_cmd "mise" "Polyglot runtime manager" && ((PASSED++)) || ((FAILED++))
|
||||||
|
test_cmd_args "aqua" "--version" "Declarative CLI Version Manager" && ((PASSED++)) || ((FAILED++))
|
||||||
|
|
||||||
|
# Summary
|
||||||
|
echo ""
|
||||||
|
echo "📊 Test Results:"
|
||||||
|
echo " Passed: ${PASSED}"
|
||||||
|
echo " Failed: ${FAILED}"
|
||||||
|
echo " Total: $((PASSED + FAILED))"
|
||||||
|
|
||||||
|
if [[ "${FAILED}" -eq 0 ]]; then
|
||||||
|
echo "🎉 All tests passed!"
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo "💥 ${FAILED} tests failed!"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! command -v git &> /dev/null; then
|
|
||||||
echo "Error: git is not available" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! command -v docker &> /dev/null; then
|
|
||||||
echo "Error: docker is not available" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Test QA tools availability
|
|
||||||
echo "Testing QA tools..."
|
|
||||||
if ! command -v trivy &> /dev/null; then
|
|
||||||
echo "Error: trivy is not available" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! command -v hadolint &> /dev/null; then
|
|
||||||
echo "Error: hadolint is not available" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! command -v dockerfilelint &> /dev/null; then
|
|
||||||
echo "Error: dockerfilelint is not available" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "All tests passed! toolbox-QADocker is functional."
|
|
||||||
81
ToolboxStack/output/toolbox-qadocker/Dockerfile
Normal file
81
ToolboxStack/output/toolbox-qadocker/Dockerfile
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
# 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
|
||||||
|
|
||||||
|
# Set up environment and install essential packages
|
||||||
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
ca-certificates \
|
||||||
|
curl \
|
||||||
|
gnupg \
|
||||||
|
lsb-release \
|
||||||
|
git \
|
||||||
|
unzip \
|
||||||
|
wget \
|
||||||
|
zsh \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# 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/*
|
||||||
|
|
||||||
|
# Install hadolint for Dockerfile linting
|
||||||
|
RUN wget -O /usr/local/bin/hadolint https://github.com/hadolint/hadolint/releases/download/v2.12.0/hadolint-Linux-x86_64 \
|
||||||
|
&& chmod +x /usr/local/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
|
||||||
|
|
||||||
|
# Install git for cloning security repositories
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends git \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Create non-root user
|
||||||
|
RUN groupadd --gid "${GROUP_ID}" "${USERNAME}" \
|
||||||
|
&& useradd --uid "${USER_ID}" --gid "${GROUP_ID}" --shell /bin/bash --create-home "${USERNAME}"
|
||||||
|
|
||||||
|
# Set up basic shell configuration
|
||||||
|
RUN echo 'export PATH="$PATH:/usr/local/bin"' >> /home/${USERNAME}/.bashrc
|
||||||
|
|
||||||
|
# Prepare workspace directory with appropriate ownership
|
||||||
|
RUN mkdir -p /workspace \
|
||||||
|
&& chown "${USER_ID}:${GROUP_ID}" /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
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
# 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'
|
||||||
|
|
||||||
|
ENV PATH=/root/.local/share/aquaproj-aqua/bin:/home/${USERNAME}/.local/share/aquaproj-aqua/bin:/usr/local/bin:${PATH}
|
||||||
|
|
||||||
|
WORKDIR /workspace
|
||||||
|
USER ${USERNAME}
|
||||||
|
|
||||||
|
CMD ["/bin/bash"]
|
||||||
79
ToolboxStack/output/toolbox-qadocker/README.md
Normal file
79
ToolboxStack/output/toolbox-qadocker/README.md
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
# 🧰 TSYSDevStack QA Docker Toolbox
|
||||||
|
|
||||||
|
A minimal Docker image designed for auditing, verifying, and testing Docker images and container configurations.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Quick Start
|
||||||
|
|
||||||
|
1. **Build the toolbox**
|
||||||
|
```bash
|
||||||
|
./build.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Start the toolbox**
|
||||||
|
```bash
|
||||||
|
./run.sh up
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Access the toolbox**
|
||||||
|
```bash
|
||||||
|
docker exec -it tsysdevstack-toolboxstack-qadocker bash
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Stop the toolbox**
|
||||||
|
```bash
|
||||||
|
./run.sh down
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧱 Architecture
|
||||||
|
|
||||||
|
- **Base Image**: Ubuntu 24.04 (minimal base without extending from toolbox-base)
|
||||||
|
- **User**: Runs as non-root `toolbox` user (UID/GID mapped to host)
|
||||||
|
- **Workspace**: Mounts current directory to `/workspace` (read/write)
|
||||||
|
- **Tools**: Contains essential Docker auditing and security tools
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🛠️ Included Tools
|
||||||
|
|
||||||
|
### Docker Auditing & Security
|
||||||
|
- **Docker CLI**: For Docker operations and container management
|
||||||
|
- **Hadolint**: Dockerfile linter for best practices and common errors
|
||||||
|
- **Dive**: Tool to explore Docker image layers and discover inefficiencies
|
||||||
|
- **Trivy**: Comprehensive security scanner for vulnerabilities
|
||||||
|
- **Grype**: Vulnerability scanner for container images
|
||||||
|
- **Docker Bench Security**: Tool for running CIS Docker benchmark tests
|
||||||
|
|
||||||
|
### Version Control & General Tools
|
||||||
|
- **Git**: For version control operations
|
||||||
|
- **Lazygit**: Terminal UI for Git
|
||||||
|
- **Curl/Wget**: For downloading resources
|
||||||
|
- **Yq**: Command-line YAML processor
|
||||||
|
- **Xh**: Friendly and fast tool for HTTP requests
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📂 Project Layout
|
||||||
|
|
||||||
|
| Path | Purpose |
|
||||||
|
|------|---------|
|
||||||
|
| `Dockerfile` | Defines the minimal QA Docker image with auditing tools |
|
||||||
|
| `docker-compose.yml` | Service configuration for the QA toolbox |
|
||||||
|
| `build.sh` | Wrapper around `docker build` with host UID/GID mapping |
|
||||||
|
| `run.sh` | Helper to bring the service up/down |
|
||||||
|
| `aqua.yaml` | Configuration for aqua-managed CLI tools |
|
||||||
|
| `SEED` | Defines the toolbox's purpose and goals |
|
||||||
|
| `PROMPT` | LLM onboarding prompt for future contributors |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🤝 Collaboration Notes
|
||||||
|
|
||||||
|
- This is the ONLY image that does NOT extend from `toolbox-base` (used for bootstrap purposes)
|
||||||
|
- Designed for use by AI CLI agents when creating and verifying container images
|
||||||
|
- Contains tools for auditing Docker images (hadolint, dive, etc.)
|
||||||
|
- Meant to be rebuilt quickly and be easy to extend
|
||||||
|
- Follows best security practices for minimal attack surface
|
||||||
24
ToolboxStack/output/toolbox-qadocker/aqua.yaml
Normal file
24
ToolboxStack/output/toolbox-qadocker/aqua.yaml
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
version: 1.0.0
|
||||||
|
registries:
|
||||||
|
- type: standard
|
||||||
|
ref: v4.431.0
|
||||||
|
packages:
|
||||||
|
# Docker auditing and security tools
|
||||||
|
- name: hadolint/hadolint@v2.12.0
|
||||||
|
- name: aquasecurity/trivy@v0.56.2
|
||||||
|
- name: anchore/grype@v0.84.1
|
||||||
|
- name: docker/docker-bench-security@v1.8.0
|
||||||
|
- name: snyk/snyk@v1.1308.0
|
||||||
|
# General utility tools
|
||||||
|
- name: jesseduffield/lazygit@v0.44.0
|
||||||
|
- name: direnv/direnv@v2.35.0
|
||||||
|
- name: dandavison/delta@0.18.2
|
||||||
|
- name: ajeetdsouza/zoxide@v0.9.6
|
||||||
|
- name: mikefarah/yq@v4.44.3
|
||||||
|
- name: ducaale/xh@v0.22.3
|
||||||
|
- name: rs/curlie@v1.8.6
|
||||||
|
- name: koalaman/shellcheck@v0.10.0
|
||||||
|
- name: mvdan/sh@v3.7.0
|
||||||
|
- name: golangci/golangci-lint@v1.60.3
|
||||||
|
- name: golang/go@go1.23.0
|
||||||
|
- name: cli/cli@v2.57.0
|
||||||
@@ -28,7 +28,9 @@ fi
|
|||||||
# Get the toolbox name from the directory name (or you can pass it as an argument)
|
# Get the toolbox name from the directory name (or you can pass it as an argument)
|
||||||
TOOLBOX_NAME="${TOOLBOX_NAME_OVERRIDE:-$(basename "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")}"
|
TOOLBOX_NAME="${TOOLBOX_NAME_OVERRIDE:-$(basename "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")}"
|
||||||
sanitized_input "$TOOLBOX_NAME"
|
sanitized_input "$TOOLBOX_NAME"
|
||||||
IMAGE_NAME="tsysdevstack-toolboxstack-${TOOLBOX_NAME#toolbox-}"
|
# Convert to lowercase and replace any uppercase letters to ensure valid Docker image name
|
||||||
|
IMAGE_NAME_RAW="tsysdevstack-toolboxstack-${TOOLBOX_NAME#toolbox-}"
|
||||||
|
IMAGE_NAME=$(echo "$IMAGE_NAME_RAW" | tr '[:upper:]' '[:lower:]')
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
# Sanitize user input
|
# Sanitize user input
|
||||||
@@ -107,42 +109,22 @@ if ! docker run --rm "${IMAGE_NAME}:${TAG}" zsh -c 'echo "Container starts succe
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Verify critical tools are available
|
# Verify critical tools for Docker auditing are available
|
||||||
echo "Verifying critical tools..."
|
echo "Verifying Docker auditing tools..."
|
||||||
CRITICAL_TOOLS=("zsh" "git" "curl" "jq" "fish" "fzf" "bat" "fd" "rg" "htop" "btop")
|
CRITICAL_TOOLS=("git" "curl" "wget" "docker" "hadolint" "dive")
|
||||||
for tool in "${CRITICAL_TOOLS[@]}"; do
|
for tool in "${CRITICAL_TOOLS[@]}"; do
|
||||||
if ! docker run --rm "${IMAGE_NAME}:${TAG}" which "$tool" >/dev/null 2>&1; then
|
if ! docker run --rm "${IMAGE_NAME}:${TAG}" which "$tool" >/dev/null 2>&1; then
|
||||||
echo "Error: Critical tool '$tool' not found in PATH." >&2
|
echo "Error: Critical Docker auditing tool '$tool' not found in PATH." >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
# Verify aqua tools are available
|
# Verify additional aqua tools for QA are available
|
||||||
echo "Verifying aqua tools..."
|
echo "Verifying QA aqua tools..."
|
||||||
AQUA_TOOLS=("gh" "lazygit" "direnv" "delta" "zoxide" "just" "yq" "xh" "curlie" "chezmoi" "shfmt" "shellcheck" "hadolint" "uv" "uvx" "watchexec" "kroki")
|
AQUA_TOOLS=("lazygit" "direnv" "delta" "zoxide" "yq" "xh" "curlie" "shellcheck" "trivy" "grype" "docker-bench-security")
|
||||||
for tool in "${AQUA_TOOLS[@]}"; do
|
for tool in "${AQUA_TOOLS[@]}"; do
|
||||||
if ! docker run --rm "${IMAGE_NAME}:${TAG}" which "$tool" >/dev/null 2>&1; then
|
if ! docker run --rm "${IMAGE_NAME}:${TAG}" which "$tool" >/dev/null 2>&1; then
|
||||||
echo "Error: Aqua tool '$tool' not found in PATH." >&2
|
echo "Error: QA aqua tool '$tool' not found in PATH." >&2
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# Verify AI CLI tools are available
|
|
||||||
echo "Verifying AI CLI tools..."
|
|
||||||
AI_TOOLS=("code" "qwen" "gemini" "codex" "opencode")
|
|
||||||
for tool in "${AI_TOOLS[@]}"; do
|
|
||||||
if ! docker run --rm "${IMAGE_NAME}:${TAG}" which "$tool" >/dev/null 2>&1; then
|
|
||||||
echo "Error: AI CLI tool '$tool' not found in PATH." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# Verify testing tools are available
|
|
||||||
echo "Verifying testing tools..."
|
|
||||||
TESTING_TOOLS=("bats" "shellcheck" "shfmt" "hadolint")
|
|
||||||
for tool in "${TESTING_TOOLS[@]}"; do
|
|
||||||
if ! docker run --rm "${IMAGE_NAME}:${TAG}" which "$tool" >/dev/null 2>&1; then
|
|
||||||
echo "Error: Testing tool '$tool' not found in PATH." >&2
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "TSYSDevStack {{toolbox_name}}",
|
|
||||||
"dockerComposeFile": [
|
|
||||||
"../docker-compose.yml"
|
|
||||||
],
|
|
||||||
"service": "{{toolbox_name}}",
|
|
||||||
"workspaceFolder": "/workspace",
|
|
||||||
"remoteUser": "toolbox",
|
|
||||||
"runServices": [
|
|
||||||
"{{toolbox_name}}"
|
|
||||||
],
|
|
||||||
"overrideCommand": false,
|
|
||||||
"postCreateCommand": "zsh -lc 'starship --version >/dev/null'"
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
# Extend from the toolbox-base image
|
|
||||||
# NOTE: Always use the full image name to ensure compatibility in standalone builds
|
|
||||||
FROM tsysdevstack-toolboxstack-toolbox-base:release-current
|
|
||||||
|
|
||||||
# Set build arguments (these can be overridden at build time)
|
|
||||||
ARG USER_ID=1000
|
|
||||||
ARG GROUP_ID=1000
|
|
||||||
ARG USERNAME=toolbox
|
|
||||||
|
|
||||||
# Ensure the non-root user exists with the correct UID/GID
|
|
||||||
# Check if user/group already exists and handle appropriately
|
|
||||||
RUN 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 \
|
|
||||||
groupadd --gid "${GROUP_ID}" "${USERNAME}"; \
|
|
||||||
fi \
|
|
||||||
useradd --uid "${USER_ID}" --gid "${GROUP_ID}" --shell /usr/bin/zsh --create-home "${USERNAME}"; \
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Install toolbox-specific packages here
|
|
||||||
# Example:
|
|
||||||
# RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
||||||
# specific-package \
|
|
||||||
# && apt-get clean \
|
|
||||||
# && rm -rf /var/lib/apt/lists/*
|
|
||||||
|
|
||||||
# Install toolbox-specific aqua packages here
|
|
||||||
# Example:
|
|
||||||
# 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' \
|
|
||||||
# && AQUA_GLOBAL_CONFIG=/tmp/aqua.yaml aqua install \
|
|
||||||
# && su - "${USERNAME}" -c 'AQUA_GLOBAL_CONFIG=~/.config/aquaproj-aqua/aqua.yaml aqua install'
|
|
||||||
|
|
||||||
# Install toolbox-specific npm packages here
|
|
||||||
# Example:
|
|
||||||
# RUN su - "${USERNAME}" -c 'mise exec -- npm install -g @scope/package@version'
|
|
||||||
|
|
||||||
# Prepare workspace directory with appropriate ownership
|
|
||||||
RUN mkdir -p /workspace \
|
|
||||||
&& chown "${USER_ID}:${GROUP_ID}" /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
|
|
||||||
|
|
||||||
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}
|
|
||||||
|
|
||||||
WORKDIR /workspace
|
|
||||||
USER ${USERNAME}
|
|
||||||
|
|
||||||
CMD ["/usr/bin/zsh"]
|
|
||||||
@@ -1,107 +0,0 @@
|
|||||||
# 🧰 TSYSDevStack Toolbox Template
|
|
||||||
|
|
||||||
Template for creating new toolboxes that extend from the `toolbox-base` image.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🚀 Quick Start
|
|
||||||
|
|
||||||
1. **Create a new toolbox**
|
|
||||||
```bash
|
|
||||||
cp -r /path/to/toolbox-template /path/to/new-toolbox
|
|
||||||
cd /path/to/new-toolbox
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Customize the toolbox**
|
|
||||||
- Edit `Dockerfile` to add toolbox-specific tooling
|
|
||||||
- Modify `docker-compose.yml` to adjust service configuration
|
|
||||||
- Update `SEED` to define the toolbox's purpose and goals
|
|
||||||
|
|
||||||
3. **Build the toolbox**
|
|
||||||
```bash
|
|
||||||
./build.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
4. **Start the toolbox**
|
|
||||||
```bash
|
|
||||||
./run.sh up
|
|
||||||
```
|
|
||||||
|
|
||||||
5. **Access the toolbox**
|
|
||||||
```bash
|
|
||||||
docker exec -it tsysdevstack-toolboxstack-{{toolbox_name}} zsh
|
|
||||||
```
|
|
||||||
|
|
||||||
6. **Stop the toolbox**
|
|
||||||
```bash
|
|
||||||
./run.sh down
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🧱 Architecture
|
|
||||||
|
|
||||||
- **Base Image**: Extends from `tsysdevstack-toolboxstack-toolbox-base:release-current`
|
|
||||||
- **User**: Runs as non-root `toolbox` user (UID/GID mapped to host)
|
|
||||||
- **Workspace**: Mounts current directory to `/workspace` (read/write)
|
|
||||||
- **Runtime**: Inherits all tooling from base plus toolbox-specific additions
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🛠️ Customization
|
|
||||||
|
|
||||||
### Dockerfile
|
|
||||||
Extend the base image with toolbox-specific tooling:
|
|
||||||
```dockerfile
|
|
||||||
# Extend from the toolbox-base image
|
|
||||||
FROM tsysdevstack-toolboxstack-toolbox-base:release-current
|
|
||||||
|
|
||||||
# Add toolbox-specific packages or configurations
|
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
||||||
specific-package \
|
|
||||||
&& apt-get clean \
|
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
|
||||||
```
|
|
||||||
|
|
||||||
### docker-compose.yml
|
|
||||||
Adjust service configuration for toolbox-specific needs:
|
|
||||||
```yaml
|
|
||||||
services:
|
|
||||||
my-toolbox:
|
|
||||||
# Inherits all base configuration
|
|
||||||
# Add toolbox-specific volumes, ports, etc.
|
|
||||||
volumes:
|
|
||||||
- ./custom-config:/home/toolbox/.config/custom-tool
|
|
||||||
```
|
|
||||||
|
|
||||||
### SEED
|
|
||||||
Define the toolbox's purpose and goals:
|
|
||||||
```markdown
|
|
||||||
- Describe what this toolbox should provide (languages, CLIs, workflows)
|
|
||||||
- List required base image modifications or additional mounts
|
|
||||||
- Note verification or testing expectations specific to this toolbox
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📂 Project Layout
|
|
||||||
|
|
||||||
| Path | Purpose |
|
|
||||||
|------|---------|
|
|
||||||
| `Dockerfile` | Extends base image with toolbox-specific tooling |
|
|
||||||
| `docker-compose.yml` | Service configuration for the toolbox |
|
|
||||||
| `build.sh` | Wrapper around `docker build` with host UID/GID mapping |
|
|
||||||
| `run.sh` | Helper to bring the service up/down |
|
|
||||||
| `.devcontainer/devcontainer.json` | VS Code remote container definition |
|
|
||||||
| `SEED` | Defines the toolbox's purpose and goals |
|
|
||||||
| `PROMPT` | LLM onboarding prompt for future contributors |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🤝 Collaboration Notes
|
|
||||||
|
|
||||||
- Inherits all collaboration policies from `toolbox-base`
|
|
||||||
- Document toolbox-specific additions in `README.md` and `PROMPT`
|
|
||||||
- Update `SEED` only when the high-level objectives change
|
|
||||||
- Prefer aqua/mise for new tooling to keep installations reproducible
|
|
||||||
- Keep documentation synchronized for future contributors
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
version: 1.0.0
|
|
||||||
registries:
|
|
||||||
- type: standard
|
|
||||||
ref: v4.431.0
|
|
||||||
packages:
|
|
||||||
# Add additional packages specific to your toolbox here
|
|
||||||
# Example:
|
|
||||||
# - name: cli/cli@v2.82.1
|
|
||||||
# - name: jesseduffield/lazygit@v0.55.1
|
|
||||||
# - name: direnv/direnv@v2.37.1
|
|
||||||
# - name: dandavison/delta@0.18.2
|
|
||||||
# - name: ajeetdsouza/zoxide@v0.9.8
|
|
||||||
# - name: casey/just@1.43.0
|
|
||||||
# - name: mikefarah/yq@v4.48.1
|
|
||||||
# - name: ducaale/xh@v0.25.0
|
|
||||||
# - name: rs/curlie@v1.8.2
|
|
||||||
# - name: twpayne/chezmoi@v2.66.1
|
|
||||||
# - name: mvdan/sh@v3.12.0
|
|
||||||
# - name: koalaman/shellcheck@v0.11.0
|
|
||||||
# - name: hadolint/hadolint@v2.14.0
|
|
||||||
# - name: astral-sh/uv@0.9.6
|
|
||||||
# - name: watchexec/watchexec@v2.3.2
|
|
||||||
Reference in New Issue
Block a user