boxman
Read the Boxman book for the concepts, setup steps, and command reference.
Set up and manage an Ubuntu 24.04 development box. boxman is a Python command
with system, user, and vault operations.
Install a host
From this checkout, run the system step as root, then the user step from each
login account. The first command works with the Ubuntu system Python before
uv is installed:
sudo python3 -m boxman.cli system
python3 -m boxman.cli user
With uv available, run it without installing the package:
uvx --from . boxman vault status
After publishing the repository, uvx --from git+https://github.com/vivainio/boxman boxman ... can run the same console
command. For a persistent command, use uv tool install . from this checkout.
boxman system uses zipget to install the apt packages declared in
linux-tools.toml, sets up Git LFS, and configures rootless Podman for normal
login users. It accepts explicit usernames, or --packages-only for a
container build. It downloads zipget if no version supporting
recipe --system-only is on root's PATH. A fresh install needs a released
zipget with that option.
boxman user installs the tools in the recipe, Node.js 22, Claude Code,
Copilot CLI, and uv. Run the user step for each account.
Run boxman verify afterward to check the installed commands and rootless
Podman.
The same package set can be used in a dev container:
podman build -f container/Dockerfile -t boxman-dev .
The container build skips host login-user and systemd configuration. FUSE mounting may require additional container privileges, so the vault commands are intended for the native host.
Private directory
The recipe installs gocryptfs and FUSE 3. Each user initializes their own
vault once and unlocks it after a reboot or unmount:
uvx --from . boxman vault init
uvx --from . boxman vault unlock
uvx --from . boxman vault status
uvx --from . boxman claude # starts Claude with its config in the mounted vault
uvx --from . boxman vault lock # after stopping processes that use the mount
Encrypted files live in ~/.private.cipher; the plaintext mount is
~/private. Initialization and unlocking prompt for the password. Keep the
password and gocryptfs recovery key outside the host. Back up the encrypted
directory, including gocryptfs.conf, while keeping the plaintext mount out
of backups.
boxman claude refuses to run unless the vault is mounted. Use it before the
first Claude login. It sets CLAUDE_CONFIG_DIR to ~/private/claude and does
not move existing credentials from ~/.claude. Configure other tools'
credential locations separately if they should use the vault. Persistent
agents need the vault mounted while they use credentials. Locking fails while
a process holds files in the mount open.
The vault protects its backing files and snapshots while locked. It does not hide credentials from the user's running processes or a host administrator while unlocked. Keep home directory permissions private to each Unix owner.
EC2 host
Install the optional AWS dependency, then create
${XDG_CONFIG_HOME:-~/.config}/boxman/ec2.toml:
uv tool install '.[ec2]'
mkdir -p "${XDG_CONFIG_HOME:-$HOME/.config}/boxman"
[ec2]
profile = "your-aws-profile"
region = "your-region"
stack_name = "your-stack-name"
[ec2.tags]
Owner = "your-owner"
Environment = "your-environment"
The config contains no credentials; AWS uses the named profile. Supply the tags
required by your account. The TOML file selects the AWS profile, region, stack,
and tags. Command-line options override the file;
--tag KEY=VALUE adds or overrides a tag. --config PATH selects another TOML
file. Put global options before the action:
boxman ec2 init --vpc-id vpc-... --subnet-id subnet-... \
--instance-type t3.xlarge --volume-size-gb 100 \
--instance-name mybox \
--ami-id /aws/service/canonical/ubuntu/server/24.04/stable/current/amd64/hvm/ebs-gp3/ami-id
boxman ec2 deploy
boxman ec2 status
boxman ec2 start
boxman ec2 stop
boxman ec2 connect -u myuser
boxman ec2 ssh -u myuser
boxman ec2 ssh-config -u myuser --alias mybox
boxman ec2 run -u myuser 'uname -a'
init writes ${XDG_CONFIG_HOME:-~/.config}/boxman/stacks/<stack_name>.yaml
with the instance settings as parameter defaults and refuses to overwrite an
existing file. Edit that YAML to customize the stack. deploy reads the YAML
for the configured stack name and sends its defaults as CloudFormation
parameters. Tags from [ec2.tags] and repeatable
--tag KEY=VALUE options become CloudFormation stack tags. A single config
file selects one stack; use --config PATH for another box.
Deployment creates or updates a CloudFormation stack containing an Ubuntu EC2
instance, an SSM role, and an EC2 Instance Connect Endpoint. SSH uses that
endpoint and installs a generated public key through SSM. ssh-config writes a
marked host entry to ~/.ssh/config. The stack name selects the instance for
all subsequent commands. Starting, stopping, and deploying incur AWS charges.
Release
Build the Zensical book locally with zensical build --clean. The docs workflow
publishes it to GitHub Pages when documentation changes on main.
A published GitHub release triggers the PyPI workflow. Use a vX.Y.Z tag;
the workflow sets the package version from the release tag, builds the wheel
and source distribution, and publishes with PyPI trusted publishing. Configure
a PyPI trusted publisher for repository vivainio/boxman, workflow
publish.yml, environment pypi before the first release.
Release files for boxman 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| boxman-0.1.0.tar.gz | 19.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| boxman-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 38.1 kB
Release files / boxman-0.1.0.tar.gz
| Download URL | boxman-0.1.0.tar.gz |
|---|---|
| Size | 19.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
97c9e3076e7a3e8e41e88652bafee631d2fc9f4840b34e51231a1969aa10467f
|
|
BLAKE2b-256 checksum How to use checksums |
bacfd7e02ef11fa2d35bf66debfce864a21bd9536c7ea9ac86c46967ccaa15f8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 19, 2026.
Transparency logRelease files / boxman-0.1.0-py3-none-any.whl
| Download URL | boxman-0.1.0-py3-none-any.whl |
|---|---|
| Size | 18.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
03fc3929d0c78ed92796a3c245c423ec2f2fbde9c1240e588013b873d84ee69f
|
|
BLAKE2b-256 checksum How to use checksums |
0e5e4824ccebf122d504c6df7fd2a479ef8926be57395058412a27efedbcd219
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 19, 2026.
Transparency log