podspawnpodspawn

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 | bash

This downloads the binary and puts it in your PATH. On macOS with OrbStack, Docker is already available through the OrbStack socket.

podspawn version

Create 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 dev
karthik@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/repo

Open 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 list
NAME   STATUS    IMAGE          AGE
dev    running   ubuntu:24.04   12m

Stop the machine

podspawn stop dev
✓ Stopped machine dev

The 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 scratch
karthik@scratch:~$ echo "do stuff here"
do stuff here
karthik@scratch:~$ exit

You 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 install

Then create a machine from it:

podspawn create api --podfile podfile.yaml

The 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 | bash

Configure sshd

sudo podspawn server-setup
backed up /etc/ssh/sshd_config to /etc/ssh/sshd_config.podspawn.bak
appended AuthorizedKeysCommand to /etc/ssh/sshd_config
reloaded ssh
server-setup complete

This 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 sarahcodes
added 2 key(s) for sarah

Keys 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.pub

Users SSH in

From any machine with the registered key:

ssh sarah@devbox.company.com

Sarah lands in a Docker container. SFTP, SCP, port forwarding, and agent forwarding all work because sshd handles the protocol.

sarah@devbox:~$ whoami
sarah

Multiple 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 | bash

Create ~/.podspawn/config.yaml:

servers:
  default: devbox.company.com

Now ssh sarah@work.pod routes to the server, and work becomes the project name.

Remove users

sudo podspawn remove-user sarah --force
removed user sarah (1 session(s) destroyed)

Keys deleted, containers killed, done. No tokens to expire, no sessions to invalidate.

Next steps

How is this guide?

On this page