Warning
devbox is beta workstation infrastructure. It modifies host users, files, packages, Docker configuration, shell setup, Git setup, and optional systemd unit files.
It is currently intended for our own small-team Ubuntu workstation workflow. Review the code first and test on a disposable VM or VPS before using it on an important machine.
devbox is a small, opinionated SWE workstation setup for an Ubuntu host and a disposable Docker container, with one dev work identity shared across both.
It is not a general platform. It is a practical workstation pattern:
- the host owns durable state, secrets, users, filesystems, SSH agent access, and Docker;
- the container is a rebuildable execution/tooling layer;
- the
devuser exists on both host and container, with UID/GID1111by default; - work files live on the host and are bind-mounted into the container;
- shell config, Git config, aliases, history, and daily tooling are kept close enough that
dev@boxanddev@devfeel like one working environment.
The goal is a small, good workstation: boring, explicit, rebuildable, and pleasant to use.
Current release: v0.1.0-beta.
Supported beta/MVP workflow:
admin user clones repo and bootstraps host
-> host/sync.py creates/converges the dev user and runtime files
-> dev user starts the container directly with Docker Compose
-> dev works in either dev@box or dev@dev
The supported runtime path is direct Docker Compose from an interactive dev login.
The sync script can install and enable a systemd unit, but fully systemd-managed container startup with stable interactive SSH-agent semantics is deferred.
- dedicated host work user:
dev - matching container user:
dev - shared UID/GID:
1111by default - shared work directories:
/home/dev/git/home/dev/pj
- Zsh, Oh My Zsh, Powerlevel10k, aliases, and history setup
- Git and GitHub CLI configuration
- SSH authentication/signing through host-owned key material and agent forwarding
- Docker Compose runtime under
/home/dev/.config/dev-env - active host-side repo/config copy at
/home/dev/.devbox - persistent Docker named volumes for GitHub CLI and Codex state
- disposable container rebuild/recovery workflow
Private keys are not baked into the image and should not be copied into the container. The container uses the host SSH agent and selected mounted public/config files.
container/ Dockerfile, Compose file, container docs
dotfiles/dev/ files installed into /home/dev
host/sync.py host convergence engine
host/sync.ipynb literate development notebook/source
scripts/ small helper scripts
templates/ public-safe examples for local config
Makefile daily command surface after bootstrap
host/sync.py is the important control-plane file. The scripts and Makefile are thin wrappers around the tested workflow.
Tip
See host/sync.ipynb at Solveit for the literate programming source.
This is the supported beta/MVP bootstrap path.
On a fresh-ish Ubuntu host, clone the repo as the existing admin/user account:
git clone https://github.com/1iis/devbox.git
cd devbox
chmod +x scripts/setup.sh scripts/dev-in.sh
./scripts/setup.shThe setup script asks for:
- Git display name;
- Git email;
- optional existing SSH signing private key;
- optional existing SSH auth private key.
If key paths are omitted or do not exist, host/sync.py can generate fresh keys for the dev user.
After setup completes:
sudo -iu dev
cd ~/.devbox
./scripts/dev-in.shThat starts the Compose runtime if needed and enters the container shell.
From the host dev user:
cd ~/.devbox
./scripts/dev-in.shThat is the normal “start and enter devbox” path.
The equivalent Makefile commands are:
cd ~/.devbox
make dcup # start container
make shell # enter dev@dev
make ps # show service state
make logs # follow logs
make dcdn # stop containerThe container is disposable. Your work is not: project files, shell config, Git config, SSH metadata, history, and selected tool state live on the host or in named Docker volumes.
The wrapper is intentionally small. The manual equivalent is useful when debugging scripts/setup.sh or developing devbox itself.
git clone https://github.com/1iis/devbox.git
cd devbox
python3 -m py_compile host/sync.py
python3 host/sync.py status \
--name "Your Name" \
--email you@example.com
sudo python3 host/sync.py enable \
--name "Your Name" \
--email you@example.com
sudo -iu dev
cd ~/.devbox
make dcup
make shellTo import existing keys during bootstrap:
python3 host/sync.py status \
--name "Your Name" \
--email you@example.com \
--ssh-sign-key "$HOME/.ssh/sign" \
--ssh-private-key "$HOME/.ssh/dev"Then run the same command with sudo ... enable.
The key paths are bootstrap inputs. They are not part of the daily shell environment.
GitHub CLI state is stored in the gh-config Docker named volume:
gh auth loginCodex state is stored in the codex-config Docker named volume:
codexBoth survive container rebuilds and recreation.
SSH auth and signing use host-owned key material. The container receives:
- the forwarded SSH agent socket;
- SSH config;
- known hosts;
- the public signing key.
Private keys should remain on the host.
devbox creates a local shell environment file if it is missing:
/home/dev/.oh-my-zsh/custom/env.zsh
This file is create-once local state. host/sync.py creates it from templates/env.zsh.example if needed and does not overwrite existing content.
Use it for local shell environment variables or tool tokens if needed.
Do not use it as bootstrap configuration. Bootstrap inputs such as name, email, and SSH key paths should be passed to scripts/setup.sh or host/sync.py.
Do not commit real secrets.
The supported beta/MVP runtime path is direct Docker Compose from an interactive dev login:
cd ~/.devbox
make dcup
make shellThe installed Compose runtime files live at:
/home/dev/.config/dev-env
The active host-side repo/config copy lives at:
/home/dev/.devbox
That directory is deliberately not bind-mounted into the container. Normal work should happen under bind-mounted work directories such as:
/home/dev/git
/home/dev/pj
Fast local checks:
make checkThis currently checks:
- Python compilation for
host/sync.py; host/sync.py --help;- shell syntax for scripts;
- Docker Compose config parsing.
For fresh-host confidence, test on a disposable Ubuntu VM or VPS and run the full bootstrap path.
devboxis currently opinionated around Ubuntu hosts.- The normal work user is always
dev. - UID/GID default to
1111. - Direct Docker Compose from an interactive
devlogin is the supported runtime path. - The systemd unit can be installed/enabled, but full systemd-managed runtime with reliable interactive SSH-agent semantics is deferred.
host/sync.ipynbis tracked as literate source/development context;host/sync.pyis the runtime artifact.devboxis not a multi-user framework. Each installation gets its owndevidentity.- No container image is published yet.
These may happen later, but are not part of the current MVP path:
- packaged
devboxCLI; - PyPI/
uvxinstallation; - published container images;
- generalized multi-user support;
- cloud-init-first workflow;
- full systemd-managed runtime;
- broad platform support beyond the current Ubuntu workflow.
- boring over clever
- explicit over magical
- host owns durable state
- container is disposable
- private keys stay out of the container
- local config is create-once where appropriate
- managed files are exact and reproducible
- daily workflow should be short and memorable
MIT. See LICENSE.