You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 0f1ced2
Browse filesBrowse the repository at this point in the historyBrowse files
docs(claude-code): switch to Docker Compose with pull_policy (#52)
* docs(claude-code): switch consumer pattern to Docker Compose with pull_policy (#51)
- Replace `image` in devcontainer.json with minimal docker-compose.yml
using `pull_policy: always` so rebuilds always pull fresh images
- Keep mounts, containerEnv, capAdd, init in devcontainer.json as
cross-orchestrator properties (preserves ${devcontainerId} and
${localEnv:...} variable substitution)
- Update local fallback, extending, sandbox auth, and file structure
sections to reflect compose approach
- Add metadata.author to sandbox-fetch-docs skill
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore(skills): add metadata to sandbox-fetch-docs and copy to project
- Add url and version to skill metadata in claude-code/.claude/skills/
- Copy skill to .claude/skills/ for use in this project's devcontainer
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
description: Use when needing to verify implementation against official library docs, check API contracts, or look up how a dependency works — especially after bugs caused by wrong assumptions about a library's API. Triggers on "check the docs", "verify against docs", "official documentation", "how does X API work", "canonical implementation".
4
+
metadata:
5
+
author: Serge Gatezh
6
+
url: https://github.com/gatezh
7
+
version: "1.0.0"
8
+
---
9
+
10
+
# Fetch Documentation in Sandbox
11
+
12
+
## Overview
13
+
14
+
This sandbox only has network access to GitHub and npm registry. All other domains (vendor doc sites, CDNs, search engines) are firewalled. Use these approaches in priority order — do NOT attempt blocked approaches.
15
+
16
+
## Approach Priority
17
+
18
+
```dot
19
+
digraph fetch_docs {
20
+
rankdir=TB;
21
+
"Need library docs?" [shape=doublecircle];
22
+
"Installed in node_modules?" [shape=diamond];
23
+
"Read local source + types" [shape=box, style=filled, fillcolor="#d4edda"];
24
+
"Public repo on GitHub?" [shape=diamond];
25
+
"Fetch via raw.githubusercontent.com" [shape=box, style=filled, fillcolor="#d4edda"];
26
+
"Browse via GitHub Contents API" [shape=box, style=filled, fillcolor="#d4edda"];
# Read source implementation (how it actually works)
58
+
Grep: pattern in node_modules/.bun/PACKAGE@VERSION/node_modules/PACKAGE/dist/index.mjs
59
+
```
60
+
61
+
**When to use:** Always start here. Types show the API contract, source shows the implementation. This is more reliable than docs which may be outdated or describe a different version.
62
+
63
+
## 2. Raw GitHub content (no auth needed)
64
+
65
+
Fetch files directly from public repos via `raw.githubusercontent.com`:
Copy file name to clipboardExpand all lines: claude-code/.claude/skills/sandbox-fetch-docs.md
+4Lines changed: 4 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,10 @@
1
1
---
2
2
name: sandbox-fetch-docs
3
3
description: Use when needing to verify implementation against official library docs, check API contracts, or look up how a dependency works — especially after bugs caused by wrong assumptions about a library's API. Triggers on "check the docs", "verify against docs", "official documentation", "how does X API work", "canonical implementation".
Copy file name to clipboardExpand all lines: claude-code/README.md
+62-26Lines changed: 62 additions & 26 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -47,16 +47,29 @@ The image rebuilds daily at 5am MT (11:00 UTC) using native runners for both amd
47
47
48
48
### Default variant
49
49
50
-
Add to your project's `.devcontainer/devcontainer.json`:
50
+
Add these files to your project's `.devcontainer/` directory. Docker Compose with `pull_policy: always` ensures "Rebuild Without Cache" always pulls the latest image — the image name stays in one place. All other config stays in `devcontainer.json` using cross-orchestrator properties (`mounts`, `containerEnv`, `capAdd`, `init`) so you keep devcontainer variable substitution (`${devcontainerId}`, `${localEnv:...}`).
// Named volumes persist node_modules, Claude config, and fish history across rebuilds.
61
74
// Dirs are pre-created in the image with node:node ownership, so fresh volumes
62
75
// inherit correct permissions via Docker volume population.
@@ -84,16 +97,29 @@ Add to your project's `.devcontainer/devcontainer.json`:
84
97
85
98
> **No node_modules volumes** — the sandbox variant does not have passwordless sudo (only `sudo /usr/local/bin/init-firewall.sh` is allowed), so the `sudo chown` used in the default variant to fix volume ownership won't work. Let node_modules live in the bind mount instead.
@@ -215,10 +241,13 @@ The sandbox `devcontainer.json` already injects this via `${localEnv:CLAUDE_CODE
215
241
216
242
**Alternative — per-project `.env.local` file:**
217
243
218
-
If you prefer file-based configuration over host env vars, add `runArgs` to the sandbox `devcontainer.json`:
244
+
If you prefer file-based configuration over host env vars, add `env_file` to the sandbox `docker-compose.yml` and remove `CLAUDE_CODE_OAUTH_TOKEN` from `containerEnv` in `devcontainer.json`:
Create `.env.local` from the template (git-ignored):
@@ -237,16 +266,18 @@ The `.env.example` template to check into your project:
237
266
CLAUDE_CODE_OAUTH_TOKEN=your-token-here
238
267
```
239
268
240
-
Add `.env.local` to `.gitignore`. Note: Docker will fail to start if `.env.local` doesn't exist when using `--env-file`.
269
+
Add `.env.local` to `.gitignore`. Note: Docker Compose fails to start if `.env.local` doesn't exist when using `env_file` (set `required: false` in compose to make it optional).
├── .env.example ← template for auth token (checked in)
252
283
└── .env.local ← actual auth token (gitignored)
@@ -271,7 +302,7 @@ The image pre-creates these directories with `node:node` ownership so Docker's v
271
302
└── database/node_modules/
272
303
```
273
304
274
-
If your project has additional services, create volume mounts in `devcontainer.json` — Docker creates directories at container start. The `sudo chown` in `updateContentCommand` fixes ownership.
305
+
If your project has additional services, add volume mounts in `devcontainer.json` `mounts` — Docker creates directories at container start. The `sudo chown` in `updateContentCommand` fixes ownership.
Everything else (`mounts`, `containerEnv`, `updateContentCommand`, etc.) stays the same — the local image is identical to the pre-built one.
368
+
Everything else in `devcontainer.json` (mounts, containerEnv, lifecycle commands, etc.) stays the same — the local image is identical to the pre-built one.
335
369
336
370
### Extending the image for project-specific needs
337
371
338
-
If you need to layer project-specific tools on top, create a thin Dockerfile in your project:
372
+
If you need to layer project-specific tools on top, create a thin Dockerfile and update your compose file to build it:
339
373
340
374
```dockerfile
341
375
# .devcontainer/Dockerfile
@@ -344,12 +378,14 @@ FROM ghcr.io/gatezh/devcontainer-images/claude-code:latest
344
378
RUN npm install -g your-tool
345
379
```
346
380
347
-
```jsonc
348
-
// .devcontainer/devcontainer.json
349
-
{
350
-
"build": { "dockerfile":"Dockerfile" },
351
-
// ... rest of config (same as Quick Start, minus the "image" key)
352
-
}
381
+
```yaml
382
+
# .devcontainer/docker-compose.yml — replace `image` with `build`
383
+
services:
384
+
devcontainer:
385
+
build:
386
+
context: .
387
+
dockerfile: Dockerfile
388
+
# ... rest stays the same (workspace volume, etc.)
353
389
```
354
390
355
391
This pulls the pre-built image as a base layer (cached after first pull) and adds your customizations on top.
0 commit comments