Not a dotfiles script. Not a hosted IDE.
A small app that turns “spin me up a clean environment for this” into a button, on hardware you already pay for — and turns it back into nothing when you’re done.
- editor
- code-server in every workspace, on its own subdomain — a full IDE in a browser tab
- terminal
- persistent: closing the tab doesn’t kill the build, and the scrollback comes back
- projects
- devcontainer-style specs: base image, features, extensions, ports, postCreate / postStart
- versions
- editing a project bumps its version and pre-builds the image, so the next launch is warm
- your keys
- ~/.ssh mounted read-only: any git host your key reaches clones and pushes, passphrase included
- secrets
- global or per project, encrypted at rest, injected as environment variables at boot
- storage
- SQLite in one volume — back it up and you’ve backed up the whole installation
- routing
- worker-<id>.localhost for the IDE, worker-<id>-<port>.localhost for every port that listens
step 1
Run the container
One docker run with the Docker socket mounted — or the compose file below. Then open http://localhost. There is no account step, because there are no accounts.
step 2
Describe a project
Start from a template (Next.js, Vite, Astro, FastAPI, Express, Docker-in-Docker) or point it at your own repository and base image. Features, ports, hooks and secrets all live in the spec.
step 3
Launch a workspace
A sibling container boots from that spec, clones your repositories, runs your hooks, and hands you an editor and a terminal on their own subdomain.
if you prefer a file
Or the compose version.
Same thing, easier to keep next to whatever else you already run. Set a real DATA_ENCRYPTION_KEY once (openssl rand -hex 32) — it is what your stored secrets are encrypted with.
services:
spunto-lite:
image: ghcr.io/spuntodotnet/spunto-lite:latest
restart: unless-stopped
ports: ["80:80"]
environment:
DATA_ENCRYPTION_KEY: ${DATA_ENCRYPTION_KEY}
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- $HOME/.ssh:/host-ssh:ro
- spunto-lite-ssh-agent:/run/spunto-ssh-agent
- spunto-lite-data:/app/data
volumes:
spunto-lite-data:
spunto-lite-ssh-agent:Somewhere safe to let an agent run.
A coding agent needs a shell that can install things, a server it can start and a repository it can break. Giving it that on your laptop is how you end up with a mystery daemon and a corrupted database. Giving it a Lite workspace is just a container — its own network, its own ports, its own clone — that you throw away when it’s done.
Write what you want on a project, pick the harness and the model, and a worker from the project’s pool gets the session. You watch the reply as it is written, answer or interrupt it, read the diff from the machine itself, open a shell on it, then Accept or Drop.
How tasks work →- harnesses
- Claude Code, Codex and Mistral Vibe — their official SDKs, baked into the project’s image
- keys
- ANTHROPIC_API_KEY, OPENAI_API_KEY or MISTRAL_API_KEY, as an ordinary secret
- no git required
- no branch is cut for the task: the agent makes one if it needs one, and names it
- MCP servers
- Notion, Linear… connected once in OAuth; the worker never holds the vendor’s token
Three things it won’t do.
None of these are on a roadmap. They are the line between a tool you run on your laptop and a platform a team depends on, and drawing it clearly is the only way Lite gets to stay this small.
- !No login screen. It holds your Docker socket, so keep it on localhost or a network you trust — never on the open internet.
- !One machine, one person. No organisations, no roles, no sharing a workspace with a teammate.
- !Your machine only. No fleet of servers, no cloud machines to rent — that’s Spunto Cloud.
lite or cloud — the whole difference
The spec you write in Lite — image, features, hooks, ports — is the format Spunto Cloud uses: export a project from one, import it in the other.
See Spunto Cloud →Try it in the time it takes to read this page.
It’s MIT and the image is public, so trying it costs nothing but disk.