Spawner
Preview environments on your self-hosted Spawner server: a copy of your app for each git branch
Installation
Ajoutez ceci à la configuration MCP de votre client (Claude Desktop : claude_desktop_config.json ; Cursor : .cursor/mcp.json ; VS Code et les autres utilisent la même forme « mcpServers »).
spawner-cliclaude mcp add spawner -e 'SPAWNER_URL=<SPAWNER_URL>' -e 'SPAWNER_TOKEN=<your spawner_token>' -- npx -y spawner-cli@2.2.1 mcp
{
"mcpServers": {
"spawner": {
"command": "npx",
"args": [
"-y",
"spawner-cli@2.2.1",
"mcp"
],
"env": {
"SPAWNER_URL": "<SPAWNER_URL>",
"SPAWNER_TOKEN": "<your spawner_token>"
}
}
}
}
Variables d'environnement
SPAWNER_URLAddress of your Spawner server's dashboard, such as https://spawner.preview.example.com. Without it, the server of spawner loginSPAWNER_TOKENsecret Personal API token (spn_...), from spawner token create or the dashboard. Without it, the token of spawner login
Documentation
Tirée du README du projet sur GitHub, actualisée chaque semaine. Les liens ouvrent GitHub.
Sommaire
Spawner
Spawner is an open source, self-hosted preview environment manager: a copy of your app for each git branch, on your own server, with its own URLs, database and logs, for teams and their coding agents.
Website · Documentation · Compare · Changelog · Releases · npm
Spawner builds preview environments (also called review apps or ephemeral environments) from your project's Docker Compose file, without Kubernetes. Developers, reviewers and coding agents start one from a branch, or from a worktree with its uncommitted changes, then open it, run commands in it, read its logs, share it and delete it. Environments nobody uses go to sleep, so many fit on one server. Free under Apache-2.0.
Status: out of beta since 2.1.0. Only the latest release gets fixes, and the dashboard updates a server in one click.
$ cd ~/code/blog-feat-login # an agent's worktree, branch feat/login
$ spawner up --wait
feat-login (blog) is ready
web https://feat-login--blog.preview.example.com
api https://api--feat-login--blog.preview.example.com
$ spawner exec -i feat-login db -- mysql -uapp -papp app < fixtures.sql
$ spawner logs feat-login api --errors
$ spawner share feat-login # a link for someone without an account
$ spawner down feat-login
Quick start
On a server dedicated to previews (Ubuntu 22.04 or 24.04, Debian 12, amd64 or arm64; at least 4 GiB of memory, 8 GiB or more advised), with a DNS record *.preview.example.com pointing to it:
curl -fsSL https://github.com/Flosk6/Spawner/releases/latest/download/install.sh | sudo bash
The installer asks for the domain, an e-mail and your DNS provider (for one wildcard certificate), installs Docker if needed, starts Spawner, and prints the link that creates the first admin account. Then, on your machine (Node.js 20 or later), in a project:
npm install -g spawner-cli
spawner login https://spawner.preview.example.com
spawner init
spawner init writes .spawner/ (a manifest and a Docker Compose file, to adjust), offers to add the instructions for coding agents, and prints the project's slug. An admin adds the project in the dashboard (Projects, New project): that slug, the repository, and the directory of .spawner/ in a monorepo. Then spawner up --wait starts the environment of the branch. The quick start goes through each step, and the examples (Node.js and PostgreSQL; Laravel, Next.js and MySQL) are ready to deploy.
How it works
flowchart LR
clients["browser, agent, CLI"] --> traefik["Traefik on *.preview.example.com"]
traefik --> spawner["spawner.preview.example.com<br>dashboard and API"]
traefik -.->|"checks access to protected URLs"| spawner
traefik --> env1["feat-login--blog.preview.example.com<br>web, api, db on their own network"]
traefik --> env2["main--blog.preview.example.com<br>web, api, db on their own network"]
A project describes its environment in its repository, in .spawner/: a manifest that names its URLs and its seed, and a regular Docker Compose file.
# .spawner/spawner.yaml
version: 1
project: blog
exposures:
- { name: web, service: web, port: 3000 }
- { name: api, service: api, port: 8000 }
seed:
- { service: api, run: [php, artisan, migrate, --seed, --force] }
For each environment, Spawner checks out the branch or receives the worktree, checks the compose file against a security policy, builds and starts it on its own Docker network, seeds it, and routes its URLs through Traefik with HTTPS. Updates keep the data. Every change is a job with a live log, whether it comes from the dashboard, the CLI, the MCP server or the API.
For coding agents
An agent tests its own work in a real environment, from its worktree, without pushing:
spawner up --wait --json: commands print JSON with--jsonand exit with stable codes (4: the environment failed, with the end of the build log; 6: quota or capacity reached; 7:.spawner/refused, with what to fix);spawner url --with-tokengives the header that opens protected URLs, for curl or Playwright;spawner execruns a command in any service;spawner logs --errorskeeps the error lines, stack traces whole;spawner statussays which service crashed and why;spawner mcpis an MCP server for Claude Code, Codex, Cursor and other clients (claude mcp add spawner -- spawner mcp), with nine tools:spawner_up,spawner_status,spawner_list,spawner_logs,spawner_exec,spawner_stats,spawner_url,spawner_shareandspawner_down;- each agent on its own branch gets its own environment and database; agents deploying at once do not get in each other's way.
See coding agents and the CLI.
Many environments on one server
- Sleep: after 2 hours (by default) without a visit or an action, an environment's containers stop; the next visit to a protected URL wakes it up within seconds.
- Shared layers: environments share their base images and dependencies; each one only adds its code and build output (about 4 MiB for the Laravel example). Spawner warns about Dockerfiles that prevent it: see making environments cheap.
- Capacity: Spawner says how many more environments of each project fit, from what they really use, and refuses one that does not fit.
- Lifetime and quotas: by default, environments expire after 72 hours unless someone deploys them again, and each person may own 5. Spawner cleans up what deleted environments leave, and nothing else.
Supervision
Each environment has its logs (by service, errors only, live), the CPU and memory of each service over time, its disk, a timeline of crashes, out-of-memory kills and failing healthchecks, and a terminal into any service; a deleted one stays readable for 7 days. Admins see the server: alerts, 30 days of history, every container, and how many more environments fit.
Security
Branches run unreviewed code: compose files are checked against an allowlist (no host mounts, privileged containers, host network or Docker socket), each environment has its own network, Traefik has no Docker socket, and the server is meant for previews only. Accounts have no passwords (invitations and passkeys, GitHub optional); tokens have scopes and expiries; previews are protected by default, and Spawner's cookies never reach the applications. An audit trail records who did what. No telemetry: on its own, Spawner only asks GitHub for new releases (SPAWNER_UPDATE_CHECK=false turns that off). See security.
What Spawner does not do
One installation runs previews on one server, from Docker Compose: no production, no Kubernetes, no cluster, and no environment opened by itself for a pull request (CI calls spawner up, see the CI guide). See the whole list, and the comparison with other tools.
Documentation
- Quick start: from a fresh install to the first environment
- Installing: requirements, DNS providers, options, upgrades, removal
- Concepts: projects, environments, jobs, lifecycle, access, limits
- The manifest:
.spawner/, its rules, and what makes environments cheap - The CLI and the MCP server: commands, JSON outputs, exit codes, MCP tools
- Coding agents: Claude Code, Codex, Cursor
- Pull requests in CI: previews from GitHub Actions and GitLab CI
- Examples and troubleshooting
- Security, operations (backups, disk, monitoring), configuration (every setting)
- Architecture: how Spawner is built, for contributors
Development
apps/
├── api/ NestJS, Prisma (PostgreSQL): the API and the environment engine
├── cli/ The spawner CLI and MCP server, bundled into one file
└── web/ Vue 3, Vite, Tailwind CSS, PrimeVue
packages/
├── core/ Manifest, compose policy and rendering (pure, shared with the CLI)
├── types/ API types shared by the web app and the CLI
└── utils/ Git input validators
examples/ Projects ready to deploy
scripts/ End-to-end tests, the capacity check, the release
Requirements: Docker with Compose v2, Node.js 22 and pnpm 8.
pnpm install && pnpm build
cp .env.example .env # set SPAWNER_DATA_DIR to an absolute path
docker compose up -d --build # Postgres, Traefik, Spawner: http://spawner.localtest.me
docker logs spawner # the link that creates the first admin account
pnpm dev # or the API on :3000, the web app on :8080, hot reload
pnpm lint && pnpm typecheck && pnpm test
scripts/e2e-engine.sh # end to end: a local stack, the API, the CLI and MCP
Every subdomain of localtest.me resolves to 127.0.0.1. Over plain HTTP, browsers allow passkeys on localhost only: a local install lets invitations log in without one. See scripts for the tests.
Contributing
Issues are welcome: bugs, questions and ideas. Pull requests from outside are not accepted for now; see contributing. Report vulnerabilities privately: security policy.
License
Apache-2.0: free to use, modify and distribute, commercially too. Copyright 2025-2026 Flosk6.
Questions fréquentes
Qu'est-ce que Spawner ?
Preview environments on your self-hosted Spawner server: a copy of your app for each git branch
Comment installer Spawner ?
Il s'exécute sur votre machine. Dans Claude Code : claude mcp add spawner -e 'SPAWNER_URL=<SPAWNER_URL>' -e 'SPAWNER_TOKEN=<your spawner_token>' -- npx -y spawner-cli@2.2.1 mcp. Pour les autres clients, collez la configuration JSON de cette page dans leurs réglages MCP.
Faut-il une clé API pour Spawner ?
Oui. Il attend SPAWNER_TOKEN, à renseigner dans sa configuration.
Spawner est-il open source ?
Oui. Son code est sur GitHub sous licence Apache-2.0.
Qui maintient Spawner ?
Il est publié par Flosk6. AI.tn le référence sans le maintenir ni le recommander.
Issu du registre MCP officiel. Être listé n'est pas une recommandation : vérifiez le code et les permissions d'un serveur avant de lui donner accès à vos données.