
http://localhost.
If you just need commands, jump to the Quick Start. For the native desktop app, see the Desktop install guide.
1. Prerequisites
Node.js and Python are NOT required on the host. Everything runs inside containers.
OS support
- macOS
- Windows
- Linux
- Colima
macOS 13+ on Intel or Apple Silicon. Docker Desktop with the Virtualization.framework backend is recommended. Apple Silicon pulls
arm64 images transparently.2. Clone and configure
1
Clone the repo
2
Set required env vars
Only two values are genuinely required for first boot; everything else has sensible defaults.
3
Review optional env groups
Open
.env.example for the full list. The groups below are the ones you are most likely to touch.3. First boot
1
Bring up the stack
2
Build the devserver image
The
devserver service in docker-compose.yml exists purely to produce the tesslate-devserver:latest image that every user project container derives from. Its entrypoint: true keeps it from running, but the build still happens when Compose sees it. If docker compose up skipped the build (for example after a clean image prune), run it explicitly:Services
Verify health
health: starting for up to 30 seconds while Alembic migrations run. Tail it until Uvicorn reports ready:
4. Seed the database
On first backend startup the orchestrator automatically runsrun_all_seeds() from orchestrator/app/seeds/__init__.py. That covers themes, bases, agents, skills, MCP servers, and deployment targets on a clean database. Confirm:
5. Access URLs
6. Create your first user
- Sign up in the UI
- Superuser via CLI
- Visit
http://localhost. - Click “Sign up”, enter email and password.
- You are logged in. Billing starts on the FREE tier.
7. Create your first project
1
New project
From the dashboard, click “New project”. Pick a base such as “Vite + React + FastAPI”, give it a name, and confirm. A slug like
my-app-k3x8n2 is generated.2
Wait for scaffolding
The orchestrator copies the template and writes a
docker-compose.yml into /projects/{slug}/. Watch for the “Project ready” toast.3
Start the containers
Click “Start”. Containers spin up on
tesslate-network and register with Traefik. The preview panel loads http://frontend.localhost (or whatever the base’s primary container is called).4
Talk to the agent
Open the chat panel and ask the agent to make a change. For the complete agent tool reference (read/write, bash, sessions, web search, skills, schedules), see the tesslate-agent reference.
8. Clean slate reset
tesslate-postgres-dev-data, tesslate-redis-data, tesslate-projects-data, tesslate-base-cache, and tesslate-gateway-locks.
Database-only reset:
Quick Start
For someone who has already read this guide once:Platform notes
WSL 2 (Windows)
- Clone into the WSL filesystem (for example
~/code/opensail). Bind mounts from/mnt/c/...are slow and drop file-change events. - Run
docker composefrom inside WSL, not from PowerShell. - When piping scripts that pass container paths through
docker exec, prefix withMSYS_NO_PATHCONV=1on Git Bash.
macOS with Colima
Colima replaces Docker Desktop on macOS. OpenSail works with two tweaks:Linux rootless Docker
The orchestrator bind-mounts the Docker socket so it can manage user project containers. Under rootless Docker the socket path is$XDG_RUNTIME_DIR/docker.sock, and the orchestrator inside the container cannot see it at /var/run/docker.sock. Either run rootful Docker for development, or change the volume mount in docker-compose.yml to the rootless socket and set DOCKER_HOST inside the orchestrator. Kubernetes mode sidesteps this entirely.
Volume permissions
On Linux, the Postgres volume is owned by UID 70 (the alpine postgres user). If you shell in as a different UID you may see permission errors writing to/var/lib/postgresql/data. Do not chown the volume from the host; let the container manage it.
Troubleshooting
Port already in use
Port already in use
Symptom: Re-run
bind: address already in use on 80, 5432, 6379, 8000, 5173, or 8080.Override the port in .env:docker compose up -d. If you changed APP_PORT, Traefik dashboard moves with it, so use http://localhost:8081.Orchestrator stuck unhealthy
Orchestrator stuck unhealthy
- Postgres not ready yet: wait 15 more seconds.
SECRET_KEYis empty or still at the placeholder.LITELLM_API_BASEunreachable: boot continues but the log shows warnings.- Port 8000 busy on the host: change
BACKEND_PORT.
*.localhost does not resolve
*.localhost does not resolve
Modern Linux (systemd-resolved), macOS, and Windows with WSL 2 resolve
*.localhost to 127.0.0.1 automatically. Some distros do not.- Linux: add
address=/localhost/127.0.0.1to dnsmasq, or add per-project entries to/etc/hosts. - Windows native: edit
C:\Windows\System32\drivers\etc\hosts. - Chrome and Firefox honor loopback for
*.localhostwithout/etc/hosts.
Hot reload not firing
Hot reload not firing
The compose file already sets
WATCHFILES_FORCE_POLLING=true, CHOKIDAR_USEPOLLING=true, and WATCHPACK_POLLING=true. If it still stops working:- Inotify limit hit on Linux:
sudo sysctl fs.inotify.max_user_watches=524288. - WSL 2: make sure the repo lives inside the WSL filesystem (
~/code/...), not/mnt/c/.... The/mntmount does not emit file events reliably.
Database connection failed
Database connection failed
docker compose logs postgres. Usually a leftover volume with a mismatched password; run the clean slate reset.User project container not reachable
User project container not reachable
- Traefik dashboard at
http://localhost:8080lists every router. Confirm your container is there. - Verify the container has
com.tesslate.routable=true(the orchestrator sets this automatically from the generated compose). - Check the container is on
tesslate-network:docker network inspect tesslate-network.
Docker socket permission denied (Linux)
Docker socket permission denied (Linux)
The orchestrator mounts
/var/run/docker.sock. If you run rootless Docker, the socket lives in $XDG_RUNTIME_DIR/docker.sock and the mount is wrong. Either run rootful Docker or edit the volume mount in docker-compose.yml.Tailing logs
Tailing logs
Next steps
Desktop install
Install the native Tauri desktop app with local SQLite and per-project runtimes.
Local Kubernetes
Mirror production on Minikube with btrfs CSI and Volume Hub.
AWS production deployment
Deploy OpenSail to AWS EKS with Terraform, ECR, and NGINX Ingress.
Publishing Apps
Turn a project into a Tesslate App and list it in the marketplace.
Getting help
Discord
Chat with the OpenSail team and community.
GitHub Issues
File bugs and feature requests.
Email support
Direct support for teams and self-hosters.