A containerized development environment system that provides isolated, ephemeral workspaces with persistent file storage.
cd ~/path/to/your/project
project # Enter the sandbox
# ... do your work ...
exit # Leave sandbox (container deleted, files persist)The project command creates a fresh Docker container with a complete development toolchain, mounts your current directory, and automatically cleans up when you exit - while keeping all your files and project-specific caches.
-
Alias (
~/.bashrc:203)alias project='docker-compose -f ~/Code/compose.yaml run --rm workbench'
-
Docker Compose (
~/Code/compose.yaml)- Defines the "workbench" service
- Mounts current directory as
/app - Configures environment variables for project isolation
-
Dockerfile (
~/Code/Dockerfile.project)- Ubuntu 24.04 base image
- Multi-language development stack
- Pre-configured ubuntu user (UID 1000)
Host: ${PWD} → Container: /app (your HOME)
Host: /tmp/.X11-unix → Container: /tmp/.X11-unix (GUI support)
HOME=/app- Your project directory becomes homeHISTFILE=/app/.bash_history- Bash history per projectCARGO_HOME=/app/.cargo- Rust dependencies isolated per projectNPM_CONFIG_CACHE=/app/.npm- npm cache isolated per projectDISPLAY=$DISPLAY- GUI application support
- Runs as UID:GID
1000:1000(matches host user) - No permission issues between host and container
- Files created in container are owned by you on the host
- Python 3 - with pip and venv
- Node.js - with npm
- Java 17 - OpenJDK
- .NET 8.0 - SDK
- Rust - via rustup (stable toolchain)
- build-essential (gcc, g++, make)
- cmake
- pkg-config
- libssl-dev
- git
- curl
- sudo (passwordless for ubuntu user)
- Full NVIDIA GPU access via runtime
- All GPUs available (
capabilities: [gpu])
✅ All files in /app (your project directory)
✅ .bash_history (bash command history)
✅ .cargo/ (Rust dependencies)
✅ .npm/ (npm cache)
✅ Any code, configs, or data you create
❌ The container instance
❌ Files outside /app (e.g., /tmp, /home/ubuntu)
❌ System changes (installed packages, config outside /app)
❌ Global modifications (unless saved to /app)
# On host
cd ~/Code/Coding/some-project
project
# Inside container (prompt: ubuntu@kubuntu:~$)
echo "hello" > test.txt
cargo init --name myapp
npm init -y
python3 -m venv .venv
exit
# Back on host - all files still there
ls
# Output: test.txt Cargo.toml src/ package.json .venv/Try out a new library or framework without polluting your system:
mkdir /tmp/experiment
cd /tmp/experiment
project
cargo new hello-rust
cd hello-rust
cargo run
exit
# Clean up when done: rm -rf /tmp/experimentEach project gets its own dependency tree:
cd ~/Code/project-a
project
npm install react@18.0.0 # Only in project-a
# In another terminal
cd ~/Code/project-b
project
npm install react@17.0.0 # Only in project-bWork with multiple languages in one environment:
cd ~/Code/fullstack-app
project
# Backend
cargo build --release
# Frontend
npm run build
# Scripts
python3 deploy.py
exitSame environment every time, regardless of host state:
# Teammate A's machine
cd ~/project && project && cargo build
# Teammate B's machine (same Docker image)
cd ~/project && project && cargo build
# Identical build environment| Feature | Benefit |
|---|---|
| Isolation | Each project has its own dependencies |
| Reproducibility | Consistent environment across machines |
| Cleanliness | No cruft - containers are ephemeral |
| Portability | Share compose.yaml with teammates |
| GPU Access | ML/compute work with full GPU support |
| Multi-language | All languages available instantly |
| No Cleanup | Container auto-deleted on exit |
project
sudo apt-get update
sudo apt-get install -y tmux htop
# Use tools...
exit
# Note: Packages gone on next run. Add to Dockerfile.project for persistence.Edit ~/Code/Dockerfile.project to add permanent tools:
RUN apt-get update && apt-get install -y \
your-package-here \
&& rm -rf /var/lib/apt/lists/*Then rebuild:
cd ~/Code
docker-compose build workbenchGUI apps work automatically (X11 socket is mounted):
project
# GUI apps will display on your hostsudo systemctl start docker
sudo usermod -aG docker $USER
# Log out and back inCheck that you're UID 1000:
id -u # Should output: 1000Rebuild the image:
cd ~/Code
docker-compose build --no-cache workbenchcd ~/Code/your-project
rm -rf .cargo .npm node_modules target/
project # Fresh dependency install~/Code/
├── compose.yaml # Docker Compose configuration
├── Dockerfile.project # Container image definition
└── PROJECT-SANDBOX-README.md # This file
~/.bashrc
└── alias project='...' # Line 203
Your Project/
├── .bash_history # Your command history
├── .cargo/ # Rust dependencies (if used)
├── .npm/ # npm cache (if used)
├── .venv/ # Python venv (if created)
└── [your files] # All your project files
- History search: Your bash history persists per-project in
.bash_history - Clean slate: Delete
.cargo/,.npm/, etc. to reset dependencies - Fast iteration: Container startup is instant after first image build
- Network access: Uses host networking - no port mapping needed
- System resources: Container has full access to CPU, memory, GPU
Short answer: Your project data is gone (unless backed up).
Understanding the layers:
| Component | Location | What Happens on Delete |
|---|---|---|
| Project files | ~/Code/your-project/ |
❌ DELETED - no recovery |
| Container instance | Docker runtime | ✅ Already gone (--rm flag) |
| Docker image | Docker cache | ✅ Still exists (~3.2GB) |
If you deleted a project directory:
- ✅ Git remote exists:
git cloneto recover - ✅ Have backups: Restore from backup
- ❌ No remote/backup: Data is permanently lost
The Docker image (project-workbench:latest) persists separately from your projects:
# View Docker images
docker images | grep project-workbench
# Remove the image (if you want to free ~3.2GB)
docker rmi project-workbench:latest
# Rebuild when needed
cd ~/Code && docker-compose build workbenchNote: Deleting the image doesn't affect existing projects - it just means you'll need to rebuild next time you use project.
-
Use git - Initialize repos and push to remote (GitHub, GitLab, etc.)
cd ~/Code/your-project git init git remote add origin git@github.com:user/repo.git git push -u origin main
-
For experiments - Use
/tmpif you don't care about persistencecd /tmp/throwaway-test project # ... experiment ... exit # Delete whenever: rm -rf /tmp/throwaway-test
-
Clean up Docker - Periodically remove unused images
docker system prune -a # Remove all unused images
- Container runs as your user (UID 1000), not root
- Has sudo access inside container (passwordless)
- Network mode is
host- no network isolation - Full GPU access - trusted code only
Lee Hanken Email: github-12-2017-ds8@leehanken.uk GitHub: github.com/macsplit