setup-devcontainer
Generate a shared devcontainer (Ubuntu base image, Node, GitHub CLI, one persistent config volume) in the current repo — one container every AI CLI installs…
Skill by ken-guru
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/ken-guru-setup-devcontainer
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: devops, agent-building
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
- Runs as
- Shell scripts
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/setup-devcontainer
What's inside
- Skill name
setup-devcontainer- Description
- Generate a shared devcontainer (Ubuntu base image, Node, GitHub CLI, one persistent config volume) in the current repo — one container every AI CLI installs into, added independently via its four companion setup-<tool>-devcontainer skills — optionally layering on SSH deploy-key/signing-key automation for agent-driven git push and signed commits, and/or an opt-in default-deny network egress firewall (iptables+ipset, allowlist derived from a Network Manifest). Use when the user wants to add a devcontainer to a repo, add SSH key automation to an existing devcontainer, restrict a devcontainer's outbound network, or connect a Local Checkout to a real GitHub repo. Not for adding an AI CLI itself — run the matching setup-<tool>-devcontainer skill for that, after this one.
- License
- MIT
- Instructions
- 419 lines in SKILL.md · view on GitHub
Before installing
- Ships executable scripts
- Instructions read files in your home folder (~/.ssh, ~/.aws…)
Files (50)
- CONTEXT.md
- SKILL.md
- adding-a-backing-service.md · docs/
- adding-firewall-later.md · docs/
- adding-ssh-later.md · docs/
- 0001-per-container-ssh-keys.md · docs/adr/
- 0002-collapse-tool-container-isolation.md · docs/adr/
- 0003-manual-first-deploy-key-registration.md · docs/adr/
- 0004-digest-pin-base-image-reject-docker-hardened-images.md · docs/adr/
- 0005-network-egress-firewall-and-network-manifest.md · docs/adr/
- 0006-capability-drop-reject-readonly-rootfs-and-seccomp.md · docs/adr/
- 0007-agent-trust-hub-audit-response.md · docs/adr/
- connecting-local-checkout.md · docs/
- check-skill-sync-targets.sh · scripts/
- render-lib.sh · scripts/lib/
- patch-if-absent.sh · scripts/
- patch-json-array-if-absent.sh · scripts/
- render-devcontainer.sh · scripts/
- test-devcontainer.sh · scripts/
- test-firewall-lib.sh · scripts/
- test-integration.sh · scripts/
- test-network-manifest-domains.sh · scripts/
- test-patch-if-absent.sh · scripts/
- test-patch-json-array-if-absent.sh · scripts/
- verify-devcontainer.sh · scripts/
- Dockerfile · templates/
- README.baseline.md · templates/
- README.firewall-block.md · templates/
- README.ssh-block.md · templates/
- allowed-domains.local.txt · templates/
- bash-env.sh · templates/
- devcontainer.json · templates/
- devcontainer.with-ssh.json · templates/
- env.baseline.example · templates/
- env.ssh-block.example · templates/
- firewall-capability-entries.json · templates/
- firewall-lib.sh · templates/
- init-firewall.sh · templates/
- initialize-base.sh · templates/
- install-cli-block.sh · templates/
- network-manifest-domains.sh · templates/
- network-manifest.json · templates/
- post-attach.sh · templates/
- post-create-base.sh · templates/
- post-create-ssh-block.sh · templates/
- post-create-warnings-block.sh · templates/
- post-start-base.sh · templates/
- post-start-firewall-block.sh · templates/
- project-mounts.local.json · templates/
- refresh-allowlist.sh · templates/
SKILL.md (first lines)
# Setup Devcontainer
Generates `.devcontainer/` from the templates in [templates/](templates/):
one **Shared Container** — a single `devcontainer.json` and `Dockerfile` —
that every selected AI CLI installs into via its own independent skill, run
separately after this one. See [CONTEXT.md](CONTEXT.md) for this skill's
vocabulary (Shared Container, Local Checkout, Shared Checkout, Scaffold,
CLI Skill, Own-Block Contract, Project-Owned Block, Capability Seam, Network
Manifest, Project Mounts).
This skill owns the container definition (`devcontainer.json`, `Dockerfile`)
and the shared parts of `post-create.sh`/`post-start.sh`/`README.md`
entirely — no CLI skill ever edits them directly, except for one narrow,
explicit exception (the Capability Seam, `runArgs`, used by
`setup-codex-devcontainer`).
## 1. Resolve the workspace root, then detect the target repo
Before anything else, make sure you're standing in the directory VS Code will actually open for
this devcontainer. Every check and file write from here on — including the stale-container check
in step 2 — trusts `$(pwd)`; getting this wrong lets a stale container or a misplaced
`.devcontainer/` slip through silently instead of being caught.
```bash
git rev-parse --is-inside-work-tree 2>/dev/null
```
- **Fails**: not a git repo yet (the Local Checkout case below, before `git init`). Skip this
check entirely and continue to detecting the repo.
- **Succeeds**: compare the current checkout's root against the repo's main working tree:
```bash
git rev-parse --show-toplevel
git rev-parse --git-common-dir
```
`--git-common-dir` is the shared `.git` directory; its parent is the *main* checkout's root,
which is what differs in a linked worktree (each worktree has its own top level but shares this
common dir).
- **Parent of `--git-common-dir` matches `--show-toplevel`**: already at the repo root, or in a
plain subdirectory of it. `cd` to `--show-toplevel` and continue — every `$(pwd)` reference
later in this skill is now correct, no further changes needed.
- **They differ**: this is a **linked git worktree** — a separate checkout directory sharing
this repo's history, common in isolated per-task agent sessions. Don't guess which one VS Code
will open (worktree-per-devcontainer is a legitimate setup too). Stop and ask: "This looks
like a git worktree, not necessarily the folder you'll open in VS Code for the devcontainer.
Which folder will that be? If it's not this one, re-run this skill from there instead — the
checks below (stale containers, existing config) only ever look at the current directory."
```bash
git remote get-url origin
```
Parse `owner/repo` from it (works for both `git@github.com:owner/repo.git` and
`https://github.com/owner/repo` forms) — this is `{{REPO_SLUG}}`. `{{REPO_NAME}}` is the `repo`
part alone, used in the volume names.
If there's no `origin` remote yet, ask one question: "Does a GitHub repository already exist for
this project? If yes, name it (`owner/repo`) — the container's `GH_TOKEN` will need access to it.
If no, or you're not ready to connect yet, this becomes a local-only **Local Checkout** —
connectable to GitHub later (see 'Connecting a Local Checkout to a real GitHub repo')."
- **Named an existing repo**: resolve `{{REPO_SLUG}}`/`{{REPO_NAME}}` from it, same as the
existing-`origin` case above.
- **Local Checkout**: `{{REPO_SLUG}}` stays empty. `{{REPO_NAME}}` falls back to the local working
directory's basename (`basename "$(pwd)"`), sanitized to Docker's naming rules (lowercase,
invalid characters replaced with `-`) — state the resolved name back to the user as part of
your summary; don't decide it silently. Also ask, as a separate yes/no question: "Initialize
this workspace with `git init`?" Record the answer as `{{LOCAL_CHECKOUT_GIT_INIT}}`
(`"true"`/`"false"`). If yes, resolve `{{GIT_DEFAULT_BRANCH}}` from the host's
`git config --global init.defaultBranch` — substitute it as an empty string if the host has
none configured; always substitute this placeholder with *something*, even `""`.
Done when you have `{{REPO_SLUG}}` (possibly empty) and `{{REPO_NAME}}` — plus, if Local Checkout,
`{{LOCAL_CHECKOUT_GIT_INIT}}` and, if that's yes, `{{GIT_DEFAULT_BRANCH}}`.
## 2. Discover existing setup
```bash
test -f .devcontainer/devcontainer.json && echo "devcontainer already exists"
```
- **Already exists**: this repo already has a Shared Container from a prior run. Nothing to
regenerate — CLI installs are handled entirely by the setup-`<tool>`-devcontainer skills, and
adding SSH to an existing devcontainer is [Adding SSH to a tool
later](docs/adding-ssh-later.md). Stop here unless the user is specifically asking to
reconfigure the base devcontainer itself.
Exception: if `devcontainer.json` sets `workspaceFolder` without a matching `workspaceMount`,
it predates the fix below and will fail to mount the repo at all. Patch it in place (add
`"workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind,consistency=cached"`
next to `workspaceFolder`) and check for a stale container from the earlier failed attempt (see
below) — a restart alone won't pick up the fix, since the mount is baked in at container
creation.
Exception: if `devcontainer.json` has no `containerEnv.BASH_ENV` entry, it predates the fix that
makes `GH_TOKEN` (and the rest of `.devcontainer/.env`) visible to an AI CLI's own tool calls —
without it, `GH_TOKEN` only ever reaches the three lifecycle scripts (postCreate/postStart/
postAttach), never a `gh` command an agent runs itself, even right after a token was added and
the container rebuilt. Patch it in place: add `.devcontainer/bash-env.sh` (copy of
[templates/bash-env.sh](templates/bash-env.sh), chmod +x), add
`"containerEnv": {"BASH_ENV": "/workspace/.devcontainer/bash-env.sh"}` to `devcontainer.json`,
and add the `devcontainer-env-load` block from
[templates/post-create-base.sh](templates/post-create-base.sh) to `.devcontainer/post-create.sh`
if it isn't already there. Needs **Dev Containers: Rebuild Container** to take effect.
Warning, not an exception (nothing here auto-patches this one): if `devcontainer.json` has no
`build.target` field, it predates the Baseline Containment hardening (`--cap-drop=ALL` plus a
small `--cap-add` allowlist, unconditionally; the opt-in network firewall; the digest-pinned,
multi-stage `Dockerfile`) — the whole container still runs with Docker's full default capability
set and an unpinned, single-stage image, regardless of anything the setup-`<tool>`-devcontainer
skills or the "later" docs above do to it. There's no automated backfill for this (a deliberate
choice, not an oversight — see the skill's own git history for the reasoning). Tell the user
plainly: to actually get the hardening, delete `.devcontainer/` and regenerate from scratch,
rerunning any `setup-<tool>-devcontainer` skills and redoing the SSH/firewall answers afterward.
- **Doesn't exist**: fresh setup, continue to step 3.
Also check for a leftover container from an unrelated prior setup of this same workspace folder —From ken-guru/skills, MIT.
More from ken-guru/skills
- 0.592score
drafting-slides
ken-guru
Drafts a slide deck as one editable Marp Markdown file, with a heading and speaker notes on every slide, citations for every factual claim, and a plan for…
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
creating-charts
ken-guru
Creates static, accessible data charts (bar, line, scatter, area, and more) from a data file with Vega-Lite, checks their text is readable at final size, and…
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
creating-diagrams
ken-guru
Creates legible diagrams from D2 source (flows, architectures, sequences, decision paths) and checks they stay readable at their final size.
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
generating-images
ken-guru
Generates illustrations and photos with an AI image provider (Gemini or OpenAI) after the person approves the cost, and marks every result as AI-generated.
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
planning-presentation
ken-guru
Plans a presentation with the person: interviews them until the audience, goal, and premises are clear, records the Brief, and builds an approved storyline…
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
rendering-slides
ken-guru
Renders a Marp slide deck to HTML, a tagged PDF, and a speaker-notes script with a polished theme, installing the pinned tools it needs and checking the result.
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
reviewing-presentation
ken-guru
Reviews a slide deck for factual accuracy and sourcing, language, legibility, accessibility, timing, and how the rendered slides look, and reports what to fix…
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
researching-sources
ken-guru
Finds, vets, and organises credible sources for a question into a Source Set, judging each source's credibility and turning conflicting claims into explicit…
SkillAFreshness: A★ 1Claude Code +9 - 0.583score
setup-codex-devcontainer
ken-guru
Install Codex into an existing shared devcontainer generated by the setup-devcontainer skill — its own install step, sandbox capability grant, optional YOLO…
SkillAFreshness: A★ 1Claude Code +9 - 0.583score
setup-copilot-devcontainer
ken-guru
Install GitHub Copilot CLI into an existing shared devcontainer generated by the setup-devcontainer skill — its own install step, optional YOLO guidance, and…
SkillAFreshness: A★ 1Claude Code +9 - 0.547score
unslop
ken-guru
Load when the user asks to edit prose for a more natural voice while preserving meaning, tone, technical precision, and structured output.
SkillBFreshness: B★ 1Claude Code +9 - 0.543score
setup-antigravity-devcontainer
ken-guru
Install Antigravity into an existing shared devcontainer generated by the setup-devcontainer skill — its own install step, optional YOLO alias, optional link…
SkillBFreshness: B★ 1Claude Code +9
Signals
- Stars
- 1
- Forks
- 1
- Open issues
- 6
- Last commit (this folder)
- Oct 21, 2026 (8 days ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- Repository
- github.com/ken-guru/skills
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from ken-guru
- 0.592score
creating-charts
ken-guru
Creates static, accessible data charts (bar, line, scatter, area, and more) from a data file with Vega-Lite, checks their text is readable at final size, and…
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
creating-diagrams
ken-guru
Creates legible diagrams from D2 source (flows, architectures, sequences, decision paths) and checks they stay readable at their final size.
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
generating-images
ken-guru
Generates illustrations and photos with an AI image provider (Gemini or OpenAI) after the person approves the cost, and marks every result as AI-generated.
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
planning-presentation
ken-guru
Plans a presentation with the person: interviews them until the audience, goal, and premises are clear, records the Brief, and builds an approved storyline…
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
rendering-slides
ken-guru
Renders a Marp slide deck to HTML, a tagged PDF, and a speaker-notes script with a polished theme, installing the pinned tools it needs and checking the result.
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
drafting-slides
ken-guru
Drafts a slide deck as one editable Marp Markdown file, with a heading and speaker notes on every slide, citations for every factual claim, and a plan for…
SkillAFreshness: A★ 1Claude Code +9
Cite this page
setup-devcontainer skill. Agent Mart. https://agentmart.dev/skills/ken-guru-setup-devcontainer (last updated 2026-10-24)