Tutorial
Get a containerized dev environment in under two minutes
This tutorial covers two ways to use podspawn: local mode (runs containers on your own machine with Docker) and server mode (multi-user setup on a shared Linux server via SSH). Start with local mode. Server mode is for teams.
Local mode manages Docker containers directly. No SSH, no sshd config, no keys. You run commands, you get containers.
What you need:
- macOS or Linux with Docker (or OrbStack) installed and running
- That's it
Install podspawn
curl -sSfL https://podspawn.dev/up | bashThis downloads the binary and puts it in your PATH. On macOS with OrbStack, Docker is already available through the OrbStack socket.
podspawn versionCreate a machine
podspawn create dev✓ Creating dev (ubuntu:24.04)This pulls the base image (if needed) and starts a container named dev. The container runs in the background with your user mapped inside it.
Attach a shell
podspawn shell devkarthik@dev:~$You drop straight into a shell. No startup output, no INFO lines. Terminal resize, colors, Ctrl-C all work. This is a Docker exec under the hood, not SSH. The container runs as your OS user (not root), and the hostname is set to the machine name.
Do some work
Install packages, clone repos, run tests. The container persists until you stop it.
sudo apt-get update && sudo apt-get install -y ripgrep git
git clone https://github.com/your-org/your-repo /workspace/repo
cd /workspace/repoOpen a second terminal and run podspawn shell dev again. You land in the same container.
Detach and check status
Type exit or press Ctrl-D to leave the shell. The container keeps running.
podspawn listNAME STATUS IMAGE AGE
dev running ubuntu:24.04 12mStop the machine
podspawn stop dev✓ Stopped machine devThe container is removed. Any state inside it is gone. That's the point: environments are disposable and reproducible.
Ephemeral mode with run
If you want a throwaway container that dies when you exit:
podspawn run scratchkarthik@scratch:~$ echo "do stuff here"
do stuff here
karthik@scratch:~$ exitYou drop straight into a shell. When you exit, the container is destroyed silently. No output after exit.
run creates a container, attaches a shell, and destroys it on exit. One command, no cleanup.
Use a Podfile
For a project with specific dependencies, create a podfile.yaml:
base: ubuntu:24.04
packages:
- nodejs@22
- git
- curl
env:
NODE_ENV: development
services:
- name: postgres
image: postgres:16
ports: [5432]
env:
POSTGRES_PASSWORD: devpass
POSTGRES_DB: testdb
on_create: |
cd /workspace && npm installThen create a machine from it:
podspawn create api --podfile podfile.yamlThe container comes up with Node.js installed and a PostgreSQL sidecar running on the same Docker network. When you stop the machine, the sidecar is cleaned up too.
What you have now
A local workflow where podspawn create replaces hand-maintained Docker Compose files, podspawn shell replaces docker exec -it, and podspawn run gives you disposable scratch containers. No SSH, no configuration files, no server setup.
Server mode is for teams. One Linux server, multiple developers. Users SSH in and get isolated containers. The server admin installs podspawn once; developers connect with any SSH client.
What you need:
- A Linux server (Ubuntu, Debian, RHEL, Alpine) with Docker installed
- SSH access to the server as a user with sudo
- Developers with SSH keys (GitHub import supported)
Install on the server
ssh you@devbox.company.com
curl -sSfL https://podspawn.dev/up | bashConfigure sshd
sudo podspawn server-setupbacked up /etc/ssh/sshd_config to /etc/ssh/sshd_config.podspawn.bak
appended AuthorizedKeysCommand to /etc/ssh/sshd_config
reloaded ssh
server-setup completeThis adds two lines to your sshd config so that sshd calls podspawn to authenticate container users. Your existing SSH access is untouched. The operation is idempotent and rolls back on failure.
Add users
sudo podspawn add-user sarah --github sarahcodesadded 2 key(s) for sarahKeys are saved locally at /etc/podspawn/keys/sarah. No network calls happen at auth time. GitHub is only contacted during add-user.
You can also add keys directly:
sudo podspawn add-user sarah --key "ssh-ed25519 AAAA... sarah@laptop"
sudo podspawn add-user sarah --key-file /tmp/sarah-id.pubUsers SSH in
From any machine with the registered key:
ssh sarah@devbox.company.comSarah lands in a Docker container. SFTP, SCP, port forwarding, and agent forwarding all work because sshd handles the protocol.
sarah@devbox:~$ whoami
sarahMultiple SSH sessions share the same container. When all sessions disconnect, a grace period starts. After it expires, the container is destroyed.
Optional .pod namespace
Developers can install the podspawn client on their laptops for friendly hostnames:
curl -sSfL https://podspawn.dev/up | bashCreate ~/.podspawn/config.yaml:
servers:
default: devbox.company.comNow ssh sarah@work.pod routes to the server, and work becomes the project name.
Remove users
sudo podspawn remove-user sarah --forceremoved user sarah (1 session(s) destroyed)Keys deleted, containers killed, done. No tokens to expire, no sessions to invalidate.
Next steps
- Podfile Spec for declaring project environments
- IDE Integration for VS Code, JetBrains, and Cursor
- AI Agents for disposable agent environments
- Security Hardening for gVisor, seccomp, and network isolation
How is this guide?