Build a one-command local dev setup: an idempotent bootstrap script, dotfile hygiene, containerized services with Docker Compose, secrets handling with .env.example, and onboarding docs that get a new person productive in an hour. Use when setting up a repo's dev environment, fixing 'works on my machine', onboarding new developers, or auditing a project's local setup.
./install.sh local-dev-environmentname: "local_dev_environment" description: "Build a one-command local dev setup: an idempotent bootstrap script, dotfile hygiene, containerized services with Docker Compose, secrets handling with .env.example, and onboarding docs that get a new person productive in an hour. Use when setting up a repo's dev environment, fixing 'works on my machine', onboarding new developers, or auditing a project's local setup."
Turn a repo's setup from folklore into machinery: one command takes a fresh machine from zero to running app with tests green, and docs carry a new person to their first real commit in under an hour. The skill covers four pieces that have to work together: the bootstrap script, dotfile/toolchain hygiene, containerized services, and secrets. The output is verifiable: every step ends with a check you can run, and the whole thing must pass bin/env_audit.py before you call it done.
Step 1 — Inventory. Before writing anything, list what a developer actually needs on day one: language runtimes and versions, backing services (database, cache, queue), secrets and credentials, editor config, and the commands for run, test, lint, and seed. If you cannot list it, you cannot bootstrap it. See references/inventory-worksheet.md.
Step 2 — One-command bootstrap. Write script/bootstrap.sh (template in assets/bootstrap.sh). It must be idempotent: safe to run twice, installing only what is missing, and it must fail loudly on the first problem instead of limping on. Structure, in order:
.tool-versions or the devcontainer definition. Never rely on the machine's ambient runtime.references/dotfile-hygiene.md..env.example to .env if missing, and run the secrets generator for anything that needs a real value.Keep the script short: anything over ~120 lines becomes script/lib/ helpers or a devcontainer definition.
Step 3 — Containerized services. Provide compose.yaml for every backing service (template in assets/compose-dev-stack.yaml):
postgres:16-alpine), never latest.depends_on: {condition: service_healthy} so the app starts after its database is ready, not just after the container exists.compose.yaml minimal and put hot-reload mounts, debug ports, and dev Dockerfiles in compose.override.yml, which Compose loads automatically..env, which is gitignored. Never put a real password in a compose file.docker compose up -d to get every service.Step 4 — Secrets hygiene. .env holds real values and is never committed; .env.example is committed and documents every variable the project expects, with placeholder values that say how to obtain or generate the real one (JWT_SECRET=generate-with-openssl-rand-base64-48). Ship script/generate-secrets.sh (template in assets/) using openssl rand so developers mint their own values instead of asking in chat. Add a pre-commit hook that refuses any commit containing .env. See references/secrets-hygiene.md.
Step 5 — Onboarding docs. Write docs/ONBOARDING.md as a path, not a reference manual (template in references/onboarding-checklist.md). The target: a new person runs one command, gets the app running, reads three short docs, and merges a trivial first PR (even a README fix) by end of day one. Every step is a checkbox with a verification, not a paragraph. Include a "stuck" rule: after 20 minutes stuck, ask someone. Schedule the doc to be tested: once a quarter, have someone who never used it follow it exactly on a clean machine and fix every surprise.
Step 6 — Verify. Run bin/env_audit.py <repo-root> (passes if every check below holds). Then dry-run the bootstrap on a clean checkout or a throwaway container and confirm the app starts and tests pass.
A finished local dev environment contains:
script/bootstrap.sh: idempotent, fails fast, ends with green tests.compose.yaml (+ optional compose.override.yml): pinned tags, healthchecks, named volumes, fake dev-only credentials..env.example: every variable documented with placeholder values; .env gitignored; script/generate-secrets.sh committed..pre-commit-config.yaml: formatters/linters plus a hook that blocks .env.docs/ONBOARDING.md: day-one path ending in a merged first PR.bin/env_audit.py output: all checks PASS.Verification evidence: the audit output plus a log of the clean-machine bootstrap run. "It worked on my laptop" is not evidence; a fresh run is.
set -euo pipefail in every shell script; check prerequisites first and name the missing piece in the error message..env lives only on developer machines.publisher key 2e43c913833850e6d80f939677e3de76e806d47785c0f1caaca90f9d18c98e1e
No ratings yet — be the first to rate it.