A single source of truth for provisioning Craig's development environment across several targets. One toolchain, several mechanisms for installing it.
| Mechanism | Status | Notes |
|---|---|---|
bootstrap.sh |
Working | Imperative bash provisioner for Ubuntu 26.04 on WSL2. The reference definition of a correctly set up machine. |
Nix flake and home-manager |
Planned | Intended long-term replacement for bootstrap.sh on machines where Nix can be installed. |
Dockerfile and .devcontainer/ |
Planned | Container image carrying the same toolchain. |
| Ansible role | Planned | For targets managed by configuration management. |
| Vagrant box | Undecided | WSL2 is itself the VM, so a box would have to be driven from Windows against Hyper-V. Possibly redundant. |
Where more than one mechanism exists they must converge on the same toolchain.
bootstrap.sh stays useful on locked down corporate builds where Nix cannot be
installed, so plan for the two to coexist rather than replacing one with the other.
Clone into the WSL filesystem and run the provisioner:
git clone https://github.com/libre-devops/developer-environment.git ~/src/developer-environment
cd ~/src/developer-environment
./bootstrap.shThe script is idempotent. Re-running it on a provisioned machine is a no-op that exits zero, so it is safe to run again after a partial failure.
Run only the sections you want:
./bootstrap.sh --list # show the sections without running anything
./bootstrap.sh apt repos # run only those two
./bootstrap.sh verify # acceptance check, changes nothingSections run in this order: proxy, apt, repos, bins, lang, venv,
brew, psmodules, shell, git, ssh, verify.
Most sections need sudo. On a machine without passwordless sudo, run the
script from an interactive terminal so it can prompt.
verify exits non-zero if anything is missing, so a full run on an incomplete
machine exits non-zero too. That is deliberate, so the acceptance test can
actually gate.
All configuration is by environment variable, so the same script works on a personal machine and behind a corporate proxy.
| Variable | Default | Purpose |
|---|---|---|
PROXY |
empty | Corporate proxy, for example http://127.0.0.1:3128. Written to apt config and /etc/environment. Leave empty on a personal machine. |
CORP_CA |
empty | Path to a corporate root CA to add to the system trust store. |
REPO_SUITE |
noble |
Suite to request from third-party apt repos. Vendors lag a new LTS, so 26.04 borrows noble. Set to auto once they publish resolute. |
INSTALL_BREW |
true |
Install Homebrew and its formulae. |
VENV_PYTHON |
3.12 |
Python version for the shared developer virtualenv. |
Example, on the corporate Windows build:
PROXY="http://127.0.0.1:3128" CORP_CA="/mnt/c/certs/corp-root.crt" ./bootstrap.shThe canonical list lives in CLAUDE.md. In outline:
- Base tooling from the Ubuntu archive: build-essential, git, gnupg2, podman, neovim, jq, texlive, pandoc and the usual network and diagnostic utilities.
- Vendor apt repositories for
azure-cli,powershell,gh,dotnet-sdk,pdk,cloudflaredandtrivy. - Standalone release binaries for
yq(mikefarah),tenv,glab,keybase,starship,uv,conftest,terraform-docs,justandshellcheck. - Toolchain managers:
goenv,nvm,sdkman. - PowerShell modules at user scope: Az, Microsoft.Graph, Pester and LibreDevOpsHelpers. Az and Microsoft.Graph are meta-modules pulling in dozens of sub-modules each, so a cold install of either takes several minutes.
- A shared Python virtualenv at
~/.venvs/developer, activated by thedevshell function. - Homebrew, deliberately, even though it duplicates most of the above.
pwsh and az are not optional. A target without them is not provisioned.
./bootstrap.sh verifyThis checks that every expected binary resolves, that the developer virtualenv exists, that the GPG secret key is present, and reports binaries that are installed in more than one place.
Smoke tests for the credentials the environment depends on:
ssh -T git@github.com
echo test | gpg --clearsign > /dev/null
git -C ~/src/developer-environment commit --allow-empty -m 'signing test'No secrets belong in this repository. Real values live in
~/.config/shell/secrets.env at mode 0600, sourced from .bashrc and never
committed. bootstrap.sh creates that file as a template of commented-out
variable names on first run. .gitignore covers secrets.env, .env, *.key,
*.asc and *.pem.
The primary target is Ubuntu 26.04 LTS on WSL2 on a personal Windows 11 machine. Anything written here should also survive a work MacBook running corporate security agents, and a corporate Windows build with WSL running Oracle Linux 9 behind a CNTLM proxy. Do not assume unproxied egress or a trusted default CA bundle.
Work inside the WSL filesystem. Repositories belong under ~/src/. Working
under /mnt/c makes git pathologically slow over the 9p bridge and introduces
CRLF line endings that break shebangs.
MIT.