Install
$ agentstack add skill-imtiazrayhan-agentscamp-library-devcontainer-designer ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
The phrase "works on my machine" is a confession that the project has no defined machine. Two contributors on Node 18.17 and 20.4, one with a system libpq and one without, a Postgres someone installed via Homebrew in 2023 — that spread is exactly the environment drift a dev container exists to kill. But a container only does that if it pins what the repo actually targets and brings the whole stack up together; an unpinned node:latest reintroduces the drift you containerized to remove, and a :latest Postgres can rev a major version under you on the next rebuild. This skill reads the repo to find the real stack, then writes a devcontainer.json (with a Dockerfile and/or compose when services are involved) where every version is pinned, services come up as one unit, dependencies are cached so rebuilds are cheap, and secrets are injected at runtime — never baked into the image.
When to use this skill
- New contributors burn their first day on setup, or the onboarding README has more than a handful of "install X, then Y" steps that drift out of date.
- The same code behaves differently across machines (passes locally, fails in CI, or vice versa) and you suspect runtime/version/system-lib differences rather than a real bug.
- You're standardizing tooling across a team and want one definition of "the dev environment" that an editor can rebuild on demand.
- The project needs a DB, cache, queue, or other service running alongside the app and people manage those by hand today.
When NOT to use this skill
- The drift is a missing lockfile, not a missing container — if
package.json/pyproject.tomlhas unpinned ranges and no committed lock, fix that first; a container around floating deps still drifts. - You need a production deployment image. A dev container optimizes for fast inner-loop edit/run with the source mounted; a production image optimizes for a small, immutable artifact with the source baked in. They are different files with different tradeoffs — don't ship this one.
Instructions
- Detect the real stack before writing anything. Glob and read the manifests that declare the runtime and pin it:
.nvmrc/.node-version/enginesinpackage.json,.python-version/pyproject.tomlrequires-python,.ruby-version,go.modgodirective,.tool-versions(asdf/mise),rust-toolchain.toml. Identify the package manager from the lockfile that exists (package-lock.json→ npm,pnpm-lock.yaml→ pnpm,yarn.lock→ yarn,poetry.lock→ poetry,uv.lock→ uv) — the container must use the same one, or it builds a different tree. The repo's declared version is the source of truth; never round to "latest stable." - Find the services the app actually talks to. Grep config and env templates (
.env.example,config/,docker-compose*.yml,application.yml) for connection strings and ports —DATABASE_URL,REDIS_URL,postgres://,amqp://, ES/OpenSearch hosts. Read the dependency manifest for client libraries (pg,redis,psycopg,pika,kafkajs) as corroboration. Every external service the app expects at runtime must come up in the dev environment, or the container is half a setup and contributors are back to installing Postgres by hand. - Pin the base image to the repo's exact runtime version. Use a digest-stable, version-specific tag —
mcr.microsoft.com/devcontainers/python:3.12ornode:20.17-bookworm, never:latest,:lts, or a bare major like:20. Match the minor the repo targets (a.nvmrcof20.17.0meansnode:20.17, notnode:20). If you author a Dockerfile, install system libraries the build needs that the base lacks (libpq-devforpsycopg,build-essential,libvipsforsharp,default-libmysqlclient-dev) — these are the silent "missing on my machine" failures. Set the pinned image indevcontainer.jsonimage, orbuild.dockerfileif you need the extra libs. - Bring the whole stack up with compose when services exist. When step 2 found a DB/cache/queue, write a
docker-compose.ymlwith the app service plus each dependency pinned to a specific version (postgres:16.4,redis:7.4) — a major Postgres bump on rebuild can refuse to read the old data dir. Pointdevcontainer.jsonat it viadockerComposeFile+service+workspaceFolder, listrunServicesso the DB starts with the workspace, and use a named volume for the DB data dir so a container rebuild doesn't wipe local seed data. Set serviceDATABASE_URLto the compose service hostname (postgres, notlocalhost) so the app connects across the compose network. - Mount the workspace and cache dependencies so rebuilds stay cheap. A 10-minute container build trains people to never rebuild — and a never-rebuilt container is the drift you were eliminating. Keep the source bind-mounted (default
workspaceFolder) so edits are instant. Put the package manager's store (notnode_modules/.venv) in a named volume mount so deps survive rebuilds: a volume on~/.npm,~/.cache/pnpm,~/.cache/pip,~/.cargo. For compiled-language or heavy-system-lib stacks, structure the Dockerfile so dependency-install layers come before the source copy, so a code change doesn't bust the dep cache. - Preinstall tooling and run a
postCreateCommandthat leaves the env ready. Add the editor extensions and settings the project assumes undercustomizations.vscode.extensions(linter, formatter, language server, the DB client) — so everyone gets the same lint-on-save, not a personal config. Use apostCreateCommandto run the dependency install with the detected package manager (pnpm install --frozen-lockfile) plus any project setup (DB migrate + seed, generate types, copy.env.exampleto.envif absent). The goal: open the project, and after postCreate it runs — no manual step. Preferdevcontainer features(ghcr.io/devcontainers/features/*) for common add-ons (docker-in-docker, gh CLI) over hand-rolledapt-getlines. - Inject secrets at runtime — never bake them into the image. Reference required secrets in
containerEnv/remoteEnvsourced from the host (${localEnv:OPENAI_API_KEY}) or via a secret mount, and keep a committed.env.exampledocumenting the keys with empty/placeholder values. Anything sensitive stays in the developer's local.env(gitignored) or their host env. Do notENV SECRET=...,COPY .env, orARGa credential in the Dockerfile, and don't commit a populated.env— an image layer is shipped verbatim to everyone who pulls it.
> [!WARNING] > An unpinned base or runtime (node:latest, python:3, postgres:16 without a minor) is the single change that reintroduces the exact drift the container is meant to eliminate. The image silently revs out from under the team on the next pull or rebuild, and now "works in the container" depends on when you built it. Pin every base image and every service to a specific version, and update those pins as a reviewed, deliberate commit.
> [!CAUTION] > A secret baked into an image — via ENV, ARG, COPY .env, or a committed populated .env — leaks to everyone who pulls the image and persists in the layer history even if a later layer deletes it. Injecting credentials into a built image is publishing them. Keep all secrets in the developer's local env/secret store and reference them at runtime; commit only an empty .env.example.
Output
A devcontainer.json plus the Dockerfile and/or docker-compose.yml the project needs, written via Write, with: every base image and service tag pinned to the version the repo targets (and the detected source of that version called out — e.g. node:20.17 (from .nvmrc), postgres:16.4); the dependent services wired through compose with named data volumes and correct service-hostname connection strings; a dependency-store cache mount and a layer-ordered Dockerfile so rebuilds are fast; the preinstalled extensions and a postCreateCommand that installs and sets up so the env is ready on first open; and a clear note of which secrets are injected from the host env / secret mount versus the committed empty .env.example — none baked into the image. The skill reads the repo and writes config files only; it does not build images, start containers, or run install commands.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: imtiazrayhan
- Source: imtiazrayhan/agentscamp-library
- License: MIT
- Homepage: https://agentscamp.com
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.