This project provides a containerized and isolated development environment for any folder on your system, using Docker and a bash script as an orchestrator.
The cuybox.sh script handles building the necessary Docker image, as well as creating, managing, and connecting to persistent containers, ensuring that each working directory has its own unique and reusable sandbox.
- Isolated Environments: Each sandbox is linked to an absolute directory path, mounting its content into
/sandboxinside the container. - Intelligent Persistence: Containers are not deleted upon exit. The script automatically reconnects to a container if it's already running or starts it if it's stopped.
- Unique & Predictable Naming: Each container's name is generated from a tag (the folder's name or a custom one), a 4-character hash of the path, and an index to resolve collisions (
{tag}-{hash}-{index}). - Path Tracking: A config file (
$XDG_CONFIG_HOME/cuybox/state.json, defaulting to~/.config/cuybox/state.json) keeps a record of paths and their sandboxes to prevent collisions and manage indices. - Pre-configured Environment: The Docker image comes with
nvmand the latest version ofNode.js v22ready to use. - Graceful Lifecycle: Containers run under
tiniwith an idle process so they stop quickly and cleanly even after long sessions. - Custom Attach Program: Sandboxes attach with
byobuby default, with--programavailable for alternatives such asbash. - Flexibility: Allows passing custom options directly to the
docker runcommand (e.g., to delete a container on exit with--rm). - Ephemeral Port Forwarding: Run
--forward-port PORT,HOST_PORT:CONTAINER_PORT(default bind0.0.0.0), orBIND:HOST_PORT:CONTAINER_PORT—and repeat the flag as needed—to spin up standalonesocatbridges to a running sandbox untilCtrl+C. - Discoverable Container IP: The script prints the container IP on launch, so you can use it directly without running
--set-hostnamewhen you just need the address. - State Management: List entries in
state.json, inspect one entry, or forget one entry from the state file without removing the Docker container.
Before using the script, ensure you have the following tools installed on your system:
- Docker: The engine for creating and running containers.
- jq: For command-line JSON processing.
- coreutils: Provides
realpath,basename,cut, etc. - crc32: For generating short hashes (may be in
libarchive-toolson some Linux distributions). - socat (optional): Required only when using
--forward-portto proxy ports from the host to the container.
The cuybox.sh script must be executable (chmod +x cuybox.sh).
-
Start a sandbox in the current directory:
./cuybox.sh
-
Start a sandbox for a specific directory:
./cuybox.sh /path/to/your/project
-
Use a custom tag for the container name:
./cuybox.sh /path/to/your/project my-special-tag
-
Force host user setup: The container configures a matching user when it is created. Re-run the setup on demand with the optional flag:
./cuybox.sh /path/to/your/project --setup-user
-
Attach with a custom program: By default,
cuybox.shattaches withbyobu. Use--programto run another installed program directly, such asbash../cuybox.sh --program bash /path/to/your/project
-
Pass additional parameters to Docker: To create a container that gets deleted upon exit (non-persistent behavior), use the
--rmflag../cuybox.sh /path/to/your/project --rm
To pass environment variables:
./cuybox.sh . -e MY_VARIABLE=my_value -
Forward a port from an already-running sandbox (requires
socat): First, start the sandbox normally so the container is running. In another terminal, run the forwarding command and leave it running; stop it at any time withCtrl+C. A lonePORTmaps0.0.0.0:PORT -> container:PORT,HOST_PORT:CONTAINER_PORTlets you choose different ports, andBIND:HOST_PORT:CONTAINER_PORTlets you constrain the host interface. You can repeat the flag to forward multiple ports, and the script will refuse to run if the container is stopped../cuybox.sh --forward-port 8080 /path/to/your/project ./cuybox.sh --forward-port 8080:3000 /path/to/your/project ./cuybox.sh --forward-port 127.0.0.1:9000:9000 /path/to/your/project
-
Exit the sandbox: Simply type
exitor pressCtrl+D. -
Manage recorded sandbox state: List entries recorded in
state.json. The listedIDis normally the generated container name (tag-hash-index), and the current working directory is marked when it matches an entry../cuybox.sh --list
Show one entry by its listed ID:
./cuybox.sh --show my-project-abcd-0
Forget one entry from
state.jsonby its listed ID. This does not remove the Docker container itself../cuybox.sh --forget my-project-abcd-0
- Dockerfile: Defines an Ubuntu-based environment with
nvm, Node.js v22, andtinias PID 1. The container idles withtail -f /dev/null, so stop and start operations remain fast. - cuybox.sh: This is the orchestrator that:
- Parses arguments to separate script inputs from Docker options.
- Calculates the absolute path of the directory and generates a 4-character
crc32hash. - Queries the config file in
$XDG_CONFIG_HOME/cuybox/state.json(or~/.config/cuybox/state.json) to determine the container's index, avoiding collisions. - Generates a unique and persistent name for the container.
- Checks if the
develcuy/cuybox:latestDocker image exists and, if not, builds it. - Creates the container on first run, runs the host-user setup once (or when
--setup-useris passed), and then executes the attach program (byobuby default) inside the running container. - Provides state-only commands (
--list,--show, and--forget) that operate onstate.jsonwithout starting Docker setup.
To add more tools or change the Node.js version, simply edit the Dockerfile and remove the local develcuy/cuybox:latest image (docker rmi develcuy/cuybox:latest). The next time you run cuybox.sh, the image will be rebuilt with your changes.