## Summary
The kit examples page covered tool installation and credential injection
but never showed how to customize the shell environment — sourcing a
tool's init script so its command lands on `PATH` in every shell. This
adds a "Customize the shell environment" section, documents
install-command gotchas that apply to any download-based kit, and fixes
a Vale rule that tripped on product names ending in `!`.
Two commits:
1. **docs: add shell environment customization to kit examples**
- Worked example uses **nvm** — it installs cleanly in a default sandbox
(reachable egress, no extra packages), so the snippet works as
copy-pasted. It appends to `/etc/sandbox-persistent.sh` — the sandbox's
persistent environment file, sourced for both interactive and
non-interactive shells — matching the FAQ convention for custom env
vars, and cross-links it.
- Install-command caveats added to the "Install a tool" section:
deny-by-default egress can silently block downloads; `curl … | bash`
masks those failures (exits `0`, sandbox reports success while nothing
installed); install steps run under `sh`, not bash; some tools need base
packages such as `zip`/`unzip`.
- The first draft's sdkman snippet was dropped as the primary example
because it fails silently in a default sandbox (blocked `get.sdkman.io`
egress + missing `zip`/`unzip`). Those failure modes are now documented
as general install-command guidance, with sdkman as the illustration.
2. **vale: exempt product names ending in '!' from Docker.Exclamation**
- `Docker.Exclamation` flags any word followed by `!` in bare prose,
tripping on product names like SDKMAN!. Link text and code were already
exempt via `IgnoredScopes`, but bare prose was not. Added an
`exceptions` list (matched against the word before the `!`) so genuine
exclamations are still caught.
## Learnings
- `/etc/sandbox-persistent.sh` is the canonical persistence point for
shell env in sandboxes — sourced before *every* bash invocation
(interactive and non-interactive), so it reaches agents started with
both `sbx run` and `sbx exec`. A `~/.bashrc` edit only covers
interactive shells.
- `curl … | bash` in an install command masks download failures: the
pipe's exit status is bash's, and bash exits `0` on empty input, so a
domain blocked by the deny-by-default egress policy still produces a "✓
Created" sandbox with nothing installed. Download-then-run (`-o file &&
bash file`) surfaces the failure.
- Kit install commands run under `sh` (dash), not bash — bash builtins
like `source` fail with `sh: source: not found` unless piped to `bash`
or wrapped in `bash -c`.
- nvm won't activate while `NPM_CONFIG_PREFIX` is set (the base image
sets it for its system Node); `unset NPM_CONFIG_PREFIX` before sourcing
`nvm.sh`.
- Vale's `exceptions` for an `existence` rule with `nonword: true` are
matched against the *word* preceding the non-word token, not the full
match — so a product name ending in `!` is listed without the `!`
(`SDKMAN`, not `SDKMAN!`). Go's RE2 engine also has no lookahead, so
token regexes can't use `(?=…)`.
Generated by Claude Code
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
"Autoconfiguration" is part of the standard term "stateless address
autoconfiguration (SLAAC)" used in the macvlan/ipvlan IPv6 sections.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The Docker.Exclamation rule flags any word followed by an exclamation
point in bare prose, which trips on product names that legitimately end
in '!' such as SDKMAN!. Link text and code are already exempt via
IgnoredScopes, but bare-prose mentions were not.
Add an exceptions list, matched against the word preceding the '!', so
genuine exclamations are still caught while listed product names pass.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Show how to source a tool's init script as part of a kit so its command
lands on PATH in every shell, using nvm as a worked example. nvm
installs cleanly in a default sandbox (reachable egress, no extra
packages), so the snippet works as copy-pasted.
Append to /etc/sandbox-persistent.sh — the sandbox's established
persistent environment file, sourced for both interactive and
non-interactive shells — to match the convention documented in the FAQ
for custom environment variables, and cross-link it.
Also document install-command gotchas that apply to any download-based
kit: deny-by-default egress can silently block downloads, curl | bash
masks those failures (exits 0), install steps run under sh not bash, and
some tools need base packages such as zip/unzip.
Add nvm to the Vale vocabulary.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
## Summary
Adds an admin-facing guide for Docker Sandboxes organization sign-in
enforcement: admins deploy an enforcement configuration via endpoint
management (macOS configuration profile, Windows registry, Linux
root-owned JSON file) specifying allowed Docker Hub org slugs, and `sbx
login` verifies membership and revokes credentials on failure.
New page
`content/manuals/ai/sandboxes/governance/sign-in-enforcement.md` covers
how it works (login-time-only, fail-closed, auto-login behavior), the
configuration schema, per-platform deployment, and error messages. Also
cross-links from the governance overview and generalizes the security
page's organization-control section so it makes a single point about
admin-level controls rather than enumerating each feature.
## Learnings
- The `sbx` sign-in enforcement config is entirely endpoint/file-based
(`com.docker.sbx` managed prefs, `HKLM\SOFTWARE\Policies\Docker\SBX`,
`/etc/docker-sbx/config.json`) with no Admin Console UI — distinct from
sandbox org *policy* (network/filesystem), which is Admin Console + API
driven. Worth keeping these two admin mechanisms separate in the docs.
Generated by Claude Code
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Two related style-conformance fixes across `content/guides/`, motivated
by a recent audit of guide-page style against STYLE.md, COMPONENTS.md,
and AGENTS.md.
## What changed
### 1. Add missing `keywords:` frontmatter to 104 guide pages
`keywords` is documented as required (AGENTS.md, COMPONENTS.md) but was
missing from 10 single-file guides, 8 `_index.md` landing pages, and 86
chapter pages. Each page now has a meaningful, page-specific
comma-separated keyword list derived from its title, lead content, and
sibling pages where applicable.
Examples of the convention applied:
-
`content/guides/testcontainers-java-spring-boot-kafka/create-project.md`
— `testcontainers, java, spring boot, kafka, mysql, project setup`
- `content/guides/docker-compose/why.md` — `docker compose,
multi-container, yaml, services, orchestration, application`
Post-change verification confirms zero guide pages under
`content/guides/` are missing the field.
### 2. Remove bold-for-emphasis from 14 guide pages
STYLE.md restricts bold to UI elements only — never for emphasis,
product names, command names, or the `**Term**: description`
subsection-label pattern. Cleaned up the top-15 offender files
identified by raw bold-span count (code blocks excluded). One file
(`jupyter.md`, 32 spans) was untouched because all spans were legitimate
UI references.
Shape of the work across 14 files:
- ~60 `**Term**: description` list items de-bolded
- ~10 identifiers/values/commands converted to backticks (e.g.
`**my-mysql**` → `` `my-mysql` ``)
- ~10 product/emphasis bolds removed
- 6 bolded link texts un-bolded
- 3 blockquote-style notes converted to `> [!NOTE]` callouts
Legitimate UI bolds (button names, menu items, field labels, tab names)
were preserved throughout. `databases.md` kept 47 of 49 spans for this
reason — only port-mapping value and container name were converted to
backticks.
## Out of scope
The audit surfaced other items not addressed here:
- Series `params` block missing on all 48 `_index.md` landing pages —
this is a "decide what's authoritative" question that warrants
discussion before code changes.
- Vale prose violations (`just`, `easily`, `we`, etc.) — concentrated in
~5 files; can land separately.
- Heading numbering convention (`## Step N:` vs `## N.` vs plain) —
undocumented; should be pinned down in STYLE.md or COMPONENTS.md before
mechanical sweeps.
## Verification
- `markdownlint` (via `scripts/lint.sh`) clean on all changed files.
- Vale not installed locally; relying on CI to validate prose.
- `git diff --stat` confirms scope: 118 unique files, all under
`content/guides/`. No vendored, layout, or generated-file changes.
Sandboxes write settings files for some built-in agents (such as
/home/agent/.claude/settings.json for the claude agent) via a PostStart
hook in vm_configurator.go, which fires after kit static files and
initFiles. Document the overwrite behavior in kits.md and add a worked
commands.startup example in kit-examples.md.
The above/below substitutions fired on idioms ("above and beyond"),
numeric comparisons ("above the 90th percentile"), and version
references ("macOS Ventura and above"), where "previous"/"following"
makes no sense. Drop them — the canonical "see the example above"
case is mild enough that human review can catch it.
Extend TokenIgnores so shortcodes followed by path segments
(``{{% param "x" %}}/dists/``) and shortcodes nested inside markdown
link text are both treated as opaque. Fixes spurious URL/term hits
across the engine/install pages.
Add vocab entries for legitimate technical terms previously flagged by
Vale.Spelling (bootloader, crypto, Kubuntu/Lubuntu/Xubuntu, lockfile,
multimodal, multithreading, NLP, oldoldstable, parallelizable, pnpm,
superset, tokenization, WebGL). Also wrap the `println` heading in
formatting.md in backticks — it's a Go template function, not prose.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The login/logout swap was firing on noun usages like "sbx login",
"login shell", and "device flow login" — none of which mean "sign in".
Restrict the pattern to verb phrases ("log in", "log on", "sign on",
"log out") so noun forms are left alone.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The vale ruleset was producing ~1,600 violations, a meaningful fraction
of which were noise from a hard-to-maintain vocabulary file, sprawling
shortcode-ignore regex, and rule patterns with known false positive
modes. This commit cleans up all three.
Vocabulary fixes (accept.txt):
- Fix the case-insensitive catch-all `(?i)[A-Z]{2,}'?s` which was
matching every plural word and suppressing other rule checks on them
- Fix wrong-cased canonical entries that caused cascading Vale.Terms
false positives: Duckduckgo→DuckDuckGo, fluentd→Fluentd, [Rr]eadme
removed (README is correct), VPNKit, AppArmor, OpenSSL, etc.
- Remove `Mac` (Apple brand) — conflicted with `MAC` (address) under
Vale's case-insensitive vocab matching; both are in the base dictionary
- Resolve duplicate case entries (uncaptured/Uncaptured, etc.) by using
narrow character-class regex like `[Uu]ncaptured` to opt out of Terms
enforcement
- Add common tech terms missing from the vocab (Vitest, Deno, Pinecone,
Wolfi, Streamlit, ESLint, Kustomize, HAProxy, Qdrant, etc.)
- Add common acronyms and abbreviations as canonical uppercase (URL,
JSON, TCP, UID, SHA, CMD, VM, GPG, KVM)
Rule fixes:
- TokenIgnores/BlockIgnores collapsed from 7 patterns to 2 (one for
inline shortcodes, one for multi-line block shortcodes)
- Docker.Capitalization regex tightened to skip `docker` preceded or
followed by `-`/`.` (image names, URLs) and word chars after
(`dockerd`, `Dockerfile`)
- Docker.RecommendedWords `vs: versus` now excludes "VS Code" and "vs."
(heading abbreviation)
- Docker.We becomes case-sensitive so `US` (country) isn't flagged as
the pronoun `us`
- Docker.VersionText requires X.Y minimum to avoid matching port numbers
like "1025 or higher"
- Docker.Units drops KB→kB swap (KB is conventional in user-facing docs)
Section overrides:
- Brace-expansion glob `[{a,b,c}]` consolidates repeated path lists
- Release notes and previous-versions content fully disabled (each rule
listed explicitly because Vale's BasedOnStyles= empty in a section
doesn't actually disable rules, despite the docs)
- Reference content disables Vale.Spelling/Vale.Terms/Docker.Capitalization
Net result: 1,429 → ~1,070 violations, with spot-checks confirming the
remaining violations are real (CLI commands without backticks, first-
person plurals, `allows`→`lets`, etc.) and not artifacts of the rules.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
<!--Delete sections as needed -->
## Description
- Adds VEX status reference and `not_affected` justification codes based
on OpenVEX and usage in the advisory repo.
- Adds "Why DHI does not use `fixed`"
- Removes "Why is VEX important?" and "How DHI integrates VEX" sections.
This content is covered more concretely in `scanner-integrations.md`.
Will follow up to figure out how to cover the content better between
these two topics, but removing redundant content for now.
https://deploy-preview-24838--docsdocker.netlify.app/dhi/core-concepts/vex/
## Related issues or tickets
ENGDOCS-3238
## Reviews
<!-- Notes for reviewers here -->
<!-- List applicable reviews (optionally @tag reviewers) -->
- [ ] Technical review
- [ ] Editorial review
---------
Signed-off-by: Craig Osterhout <craig.osterhout@docker.com>
## Description
Migrate 17 Testcontainers guides from testcontainers.com into the Docker
docs site, covering Java (14 guides), .NET (2 guides), and Node.js (1
guide). This follows up on PR #24450 which added the initial Go and
Python guides.
Each guide is converted from AsciiDoc to Hugo Markdown, split into
multi-chapter stepper navigation, updated to the latest Testcontainers
API, and verified with passing tests running in containers.
Java guides use testcontainers-java 2.0.4 with the new 2.x Maven
coordinates and package names (e.g., `testcontainers-postgresql`,
`org.testcontainers.postgresql.PostgreSQLContainer`). The Quarkus guide
uses Quarkus 3.22.3 with TC 1.x managed by the Quarkus BOM, since no
released Quarkus version ships TC 2.x yet.
## How to test
All code snippets have been verified by running each guide's source
repository tests inside Docker containers with the Docker socket
mounted.
To re-run the verification, use the `/testcontainers-guides-migrator`
skill included in this PR
(`.claude/skills/testcontainers-guides-migrator/SKILL.md`). The skill's
Step 6 documents the exact container commands and macOS Docker Desktop
workarounds (host override, docker-java API version, etc.) needed to run
each language's tests:
```
/testcontainers-guides-migrator I want you to verify all the guides in this branch.
Do a full review, verifying that all code snippets compile, the code is executable,
and ALL the tests pass. Run them as docker containers, never locally.
```
## Related issues or tickets
Supersedes #24450 (expanded from 2 guides to all 19)
## Reviews
- [ ] Technical review
- [ ] Editorial review
- [ ] Product review
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
## Description
Migrate the first two Testcontainers getting-started guides from
[testcontainers.com/guides](https://testcontainers.com/guides/) into the
Docker docs site:
- **Getting started with Testcontainers for Go** — multi-page guide with
4 chapters (create project, write tests, test suites, run tests). Code
updated to testcontainers-go v0.41.0 API (`postgres.Run()`,
`CleanupContainer`, `BasicWaitStrategies()`).
- **Getting started with Testcontainers for Python** — multi-page guide
with 3 chapters (create project, write tests, run tests). Code updated
to testcontainers-python 4.14.2 (fixed `get_exposed_port()` returning
`int`).
Each guide appears as its own entry in the `/guides/` listing with
proper language and tag filters (`testing-with-docker`). Chapters render
with stepper navigation in the sidebar.
Also adds:
- A `testing-with-docker` tag to `data/tags.yaml`
- A Claude skill
(`.claude/skills/testcontainers-guides-migrator/SKILL.md`) that
documents the repeatable migration process for the remaining 19 guides
- Links from `content/manuals/testcontainers.md` to the new guides
- Vale vocabulary entries for `pgx`, `Micronaut`, `psycopg`, `pytest`
All guide code was compiled and tests verified passing in containers
with Docker socket mounted.
## Related issues or tickets
No related issues found.
## Reviews
- [ ] Technical review
- [ ] Editorial review
- [ ] Product review
<!--Delete sections as needed -->
## Description
<!-- Tell us what you did and why -->
## Related issues or tickets
<!-- Related issues, pull requests, or Jira tickets -->
## Reviews
<!-- Notes for reviewers here -->
<!-- List applicable reviews (optionally @tag reviewers) -->
- [ ] Technical review
- [ ] Editorial review
- [ ] Product review
<!--Delete sections as needed -->
## Description
[Unsloth](https://github.com/unslothai/unsloth), a project designed to
make fine-tuning models much faster and more accessible.
<!-- Tell us what you did and why -->
## Related issues or tickets
<!-- Related issues, pull requests, or Jira tickets -->
## Reviews
<!-- Notes for reviewers here -->
<!-- List applicable reviews (optionally @tag reviewers) -->
- [ ] Technical review
- [ ] Editorial review
- [ ] Product review
This change was automatically generated by the documentation agent team
in response to issue #23757.
🤖 Generated with cagent
Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
Starting with Docker Engine v29, 32-bit Raspberry Pi OS (armhf) packages
will no longer be provided for new major versions.
<!--Delete sections as needed -->
## Description
<!-- Tell us what you did and why -->
## Related issues or tickets
<!-- Related issues, pull requests, or Jira tickets -->
## Reviews
<!-- Notes for reviewers here -->
<!-- List applicable reviews (optionally @tag reviewers) -->
- [ ] Technical review
- [ ] Editorial review
- [ ] Product review
---------
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
Co-authored-by: Allie Sadler <102604716+aevesdocker@users.noreply.github.com>
## Description
Created a new guide that walks users through adding pgAdmin to their
application stack to visualize a PostgreSQL database. Also includes
details on how to auto-connect to the database using Compose config
files.
## Related issues or tickets
None
## Reviews
- [ ] Technical review
- [x] Editorial review
- [ ] Product review
Would appreciate an editorial review, specifically on the usage of
italics/bold around step #4. I believe I followed the editing guidelines
correctly, but a second pair of eyes wouldn't hurt.
Thanks!
---------
Co-authored-by: Craig Osterhout <103533812+craig-osterhout@users.noreply.github.com>
<!--Delete sections as needed -->
## Description
<!-- Tell us what you did and why -->
## Related issues or tickets
<!-- Related issues, pull requests, or Jira tickets -->
## Reviews
<!-- Notes for reviewers here -->
<!-- List applicable reviews (optionally @tag reviewers) -->
- [ ] Technical review
- [ ] Editorial review
- [ ] Product review
---------
Co-authored-by: Craig Osterhout <103533812+craig-osterhout@users.noreply.github.com>
Co-authored-by: Sarah Sanders <sarah.sanders@docker.com>
<!--Delete sections as needed -->
## Description
Added migration tip to inform existing Docker Hub users that they can
keep using existing workflows and tools when migrating from other images
on Docker Hub.
https://deploy-preview-23327--docsdocker.netlify.app/dhi/get-started/
## Related issues or tickets
<!-- Related issues, pull requests, or Jira tickets -->
## Reviews
<!-- Notes for reviewers here -->
<!-- List applicable reviews (optionally @tag reviewers) -->
- [ ] Editorial review
---------
Signed-off-by: Craig <craig.osterhout@docker.com>