- Rust 96.5%
- Shell 3.5%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .forgejo/workflows | ||
| contrib/direnv | ||
| src | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| LICENSE | ||
| README.md | ||
BOX
Box provides transparent development environments by replacing your dev tools with symlinks that run the tool inside an isolated container.
Think inside the box.
See the blog post for some additional background.
Installation
cargo install --git https://codeberg.org/galen/box-cli
Quickstart
As a quickstart, we can follow an example configuration for a Golang development environment. All configuration options must be prefixed with BOX_. See full list of configurations here.
export BOX_IMAGE="golang:1.25-alpine3.23"
export BOX_VOLUMES="GOCACHE=$HOME/.cache/go-build"
export BOX_ENVS="GOCACHE=$HOME/.cache/go-build"
Once the environment variables are exported, an alias can be added to invoke the commands set for the workspace. For example:
box alias add go
With the alias in place, every invocation of go from the workspace would run inside the container built via the image specified in the configuration with BOX_IMAGE.
Box will automatically mount and configure the current working directory at the same path within the container, so that commands in the container have a consistent view with the host system.
Configuration
Box exposes a number of configuration options to bootstrap the OCI containers. All env vars are parsed according to shell rules.
BOX_AUTOCONFIGURE_CWD
Automatically mount & configure the current working directory in the container. Defaults to true.
Example: BOX_AUTOCONFIGURE_CWD=false
BOX_CMD
Specifies the default command to execute when the container is started.
Example: BOX_CMD="python run.py".
This option should rarely be set; by default, the command given to the development tool gets executed as the container command.
For example, for a development environment boxed for Golang, go build . will spawn the go container with build . command.
BOX_ENTRYPOINT
Specifies the default executable for the container.
Example: BOX_ENTRYPOINT="/bin/bash"
BOX_ENVS
Space-separated list of environment variables to be exported in the container.
Example: BOX_ENVS="DEBUG_LEVEL=info DB_HOST=localhost"
BOX_EXTRA_OPTS
Extra arguments that get passed through transparently to the container runtime.
Example: BOX_EXTRA_OPTS=--read-only
BOX_IMAGE
Container image for the development environment.
Example: BOX_IMAGE="alpine:3.23"
BOX_INIT
Boolean configuration to replace the BOX_ENTRYPOINT or BOX_CMD with a container init process with PID 1 to manage signal handeling and child process reaping. Defaults to true.
Example: BOX_INIT=false
BOX_INTERACTIVE
Boolean configuration to start the container in interactive mode. Defaults to true.
Example: BOX_INTERACTIVE=false
BOX_NETWORKS
Space-separated list of container networks.
Example: BOX_NETWORKS="app_network db_network"
BOX_NO_COMMAND
Remove the command name from the list of arguments passed as the container CMD. Defaults to false.
Example: BOX_NO_COMMAND=true
This option is useful if the image sets the entrypoint to a specific tool rather than a shell, as is common for CLI applications packaged in containers.
BOX_NO_MOUNT_DIRS
Space-separated list of directories that should not be mounted as volumes in the container. Volumes set via BOX_VOLUMES which reference a host path in this list will be automatically filtered out. Defaults to user's home directory.
Example: BOX_NO_MOUNT_DIRS="$HOME /some/private/dir"
This option is useful to prevent certain directories from being mounted in the container if they are the current working directory.
BOX_PORTS
Space-separated list of port mappings between host and container.
Example: BOX_PORTS="8000:8000 80:80"
BOX_PRIVILEGED
Boolean configuration to grant extended privileges to the container. Defaults to false.
Example: BOX_PRIVILEGED=true
BOX_RUNTIME
Required configuratin to select OCI runtime for the workspace container. Supports podman and docker.
Example: BOX_RUNTIME=podman
BOX_TTY
Boolean configuration to attach pseudo-tty to the container. Defaults to true if stdin, stdout, and stderr are all TTYs, otherwise false.
Example: BOX_TTY=true
BOX_USER
Specifies the container user.
Example: BOX_USER=1000
BOX_VOLUMES
Space-separated list of bind mounts for the container.
Example: BOX_VOLUMES="$PWD:$PWD $HOME/cloud_config:$HOME/cloud_config"
BOX_WORKDIR
Specifies the working directory inside the container. Defaults to the current working directory unless BOX_AUTOCONFIGURE_CWD is disabled.
Example: BOX_WORKDIR=/app
Command-specific configurations
Box also allows to override the defined configuration options for specific commands.
For example, in case of an already configured development environment, we might want to change some env vars when we want to execute a helper script bin/my-script. This can be achieved by the match rule overrides for the box configurations.
BOX_<key>_MATCH
Specifies the key and value for a command, whose invocation should use different configuration options than otherwise specified.
e.g. BOX_my_script_MATCH="bin/my-script"
bin/my-script command may now invoke the same main container with different configuration options.
e.g. BOX_my_script_ENVS="DEBUG_LEVEL=trace"
All box supported configurations are applicable for BOX_my_script_ matcher.
Box alias
Box provides a utility subcommand alias to add symlinks to the development tools as:
box alias add <alias_name>
The path where box stores aliases can be found by box path (defaults to $XDG_DATA_HOME/box). This directory must be added to your $PATH.
A list of aliases can be seen with:
box alias list
Aliases can be removed via:
box alias remove <alias_name>
Context-specific aliases
The location where box stores aliases can be changed by setting $BOX_PATH. This can be used to create aliases only available within a specific context.
For example, all aliases for a workspace called my_todos could be created by setting the box path:
export BOX_PATH=$(box path)/my_todos
All alias subcommands will work only in the context of specified workspace.
Box and direnv
Box pairs well with direnv for seamless export of configuration variables and provides some helper directives that work with direnv.
Here is an example .envrc configuration for go environment with box helper directives:
image="$(build_image ./Dockerfile)"
export BOX_IMAGE=$image
go_path="${GOPATH:-$HOME/.go}"
go_cache_path="${GOCACHE:-$HOME/.cache/go-build}"
my_envs="$(envs_from_dotenv)"
export BOX_ENVS="$my_envs GOPATH=$go_path GOCACHE=$go_cache_path"
export BOX_VOLUMES="$go_path:$go_path $go_cache_path:$go_cache_path $PWD:$PWD"
export BOX_PORTS="8080:8080 5432:5432"
export BOX_WORKDIR="$PWD"
Check out dev-envs for more examples.