Skip to content

Self-hosting ​

Casama runs on your own hardware. One machine with Docker runs the whole stack: Supabase (Postgres, Auth, REST and Realtime), the Casama API and worker, the sandbox supervisor and egress proxy for bot computers, the TURN relay for live view, and Caddy for HTTPS. Self-hosted Casama has no paywall and no usage limits: billing is switched off in the bundled stack.

This page covers what you get, what you need, and how to install. When the server is running, see Configuration for every setting and Operations for upgrades, backups and monitoring.

What you get ​

./install.sh starts these services from infra/compose/docker-compose.yml (Compose project casama):

ServiceWhat it does
caddyThe one public address. Gets TLS certificates automatically and routes requests to the API, Supabase or the web app.
apiThe Casama API (port 8787 inside the stack), plus Pages on port 8790.
workerRuns bots: chats, routines, memory, connections and scheduled jobs.
dbSupabase Postgres 17. Holds all data, including encrypted secrets in Supabase Vault.
authSupabase Auth (accounts, sign-in, two-step sign-in, SAML SSO).
restPostgREST, used by the apps for reads.
realtimeSupabase Realtime, which streams chat and run updates to the apps.
kongThe Supabase gateway in front of Auth, REST and Realtime.
migrateRuns once at each start. Waits for Auth and Realtime, then applies Casama's database migrations.
supervisorCreates, sleeps and wakes bot computers. The only service with access to the Docker socket.
egressThe only route from computers to the internet. Blocks private, loopback and cloud metadata addresses.
turnA coturn relay for live view of desktop computers.

Optional Compose profiles add more:

ProfileServicesTurn it on with
webThe web app at the same address./install.sh --web
monitoringPrometheus, node-exporter and Grafana./install.sh --monitoring
s3SeaweedFS, S3-compatible object storageSee Object storage
imagesBuild-only services for the computer imagesUsed by the installer

How a request flows:

text
Apps, CLI, browser
        |
        v
  Caddy :80/:443 --- /v1, /hooks, /connect, /healthz, /readyz ---> api :8787
        |      \---- /auth/v1, /rest/v1, /realtime/v1 --------> kong ---> auth, rest, realtime
        |       \--- everything else ------------------------> web (profile "web")
  Caddy :8790 ------ Pages (bots' web pages, own origin) ------> api :8790

  worker ---> supervisor ---> computer containers (one private network each)
                                   |-- internet only through egress
                                   \-- live view media only through turn :3478

Bot computers are Docker containers named casama-c-<id>. They run as a non-root user with a read-only root filesystem, no Linux capabilities, CPU, memory and process limits, and a private network whose only way out is the egress proxy. See Computer providers for details and for running computers on E2B, Daytona, Kubernetes and others.

Requirements ​

WhatMinimum
OSLinux with Docker Engine. macOS with Docker Desktop works for trials.
DockerDocker Engine with Docker Compose v2 (docker compose). Your user must be able to run docker.
Toolsgit, bash, openssl and curl
CPU and RAM4 vCPU and 8 GB RAM for a few computers at once. Plan on about 2 GB RAM per running computer.
Disk40 GB or more. The images take about 6 GB; home folders and snapshots take the rest.
DomainFor a public server, a DNS name (for example casama.example.com) pointing at the machine.

The installer warns when the machine has less than about 8 GB of memory, because computers may not start reliably.

Ports ​

PortProtocolUsed for
80TCPHTTP, and Let's Encrypt certificate checks
443TCPHTTPS: the API, Supabase and the web app
3478UDP, TCPTURN relay for live view
8790TCPPages, when you serve them on a port instead of their own domain
127.0.0.1:3001TCPGrafana (monitoring profile), on the loopback interface only

For a public server, open 80, 443 and 3478 (UDP and TCP) in your firewall. With --local, nothing needs to be reachable from other machines.

Domain and TLS ​

With --domain, Caddy requests a certificate for that name the first time it starts. Before you install, make sure:

  • the domain's A (or AAAA) record points at the server, and
  • ports 80 and 443 are reachable from the internet.

If another proxy already terminates TLS in front of the machine, see Behind another proxy.

Install ​

  1. Clone the repository on the server:

    sh
    git clone https://github.com/stackwares/casama && cd casama
  2. Run the installer with your domain:

    sh
    ./install.sh --domain casama.example.com

    For a trial on your own computer, use ./install.sh --local instead.

  3. Wait for the installer to finish. It prints the address when the API is ready:

    text
    Casama is running at https://casama.example.com
  4. Back up infra/compose/.env somewhere safe. It holds every key for this installation.

The installer:

  1. Checks that Docker, Docker Compose v2 and OpenSSL are available and that Docker is running.
  2. On Linux, uses gVisor (runsc) for computers if Docker lists it as a runtime.
  3. Generates every secret with OpenSSL and writes infra/compose/.env (mode 600). This includes the database passwords, the Supabase JWT secret and keys, a SAML signing key, and the tokens the services use to talk to each other.
  4. Pulls the Supabase, Caddy and other images (two at a time, with up to five retries, because public registries rate-limit anonymous pulls).
  5. Builds the Casama images: api (shared by the worker), supervisor, egress, turn and the headless computer image.
  6. Starts the stack and waits up to three minutes for /readyz to answer.

A fresh install that builds every image from scratch takes a few minutes, plus the time to download about 3 GB of third-party images. Re-running it with images in place takes about a minute.

Installer options ​

OptionWhat it does
--domain <name>Public server at https://<name> with automatic HTTPS. Sets CASAMA_SITE to the domain and the TURN host to the domain.
--localThis machine only, over plain HTTP. The address is http://localhost (or http://localhost:<port>).
--http-port <n>The host port for HTTP (default 80). Mostly useful with --local, for example --local --http-port 8080.
--with-desktopAlso builds the desktop computer image, needed for live view and desktop apps. Slower.
--monitoringAdds the monitoring profile: Prometheus, node-exporter and Grafana.
--webAdds the web profile: the Flutter web app at the same address. The build runs Flutter in Docker and takes a while.
--no-startWrites .env and builds the images, but doesn't start the stack.
-h, --helpPrints the usage.

With neither --domain nor --local, the installer asks for a domain. An empty answer (or no terminal) means a local install.

To force clean image builds, set CASAMA_BUILD_FLAGS, which is passed to docker compose build:

sh
CASAMA_BUILD_FLAGS=--no-cache ./install.sh

Re-running keeps your settings

When infra/compose/.env exists, the installer keeps it as is and only adds settings that newer releases introduced. --domain, --local and --http-port have no effect on a re-run. To change the address later, edit the settings in Core and URLs.

--local versus --domain ​

--local--domain casama.example.com
Addresshttp://localhost[:port]https://casama.example.com
TLSNoneAutomatic (Let's Encrypt through Caddy)
Who can reach itThis machineAnyone who can reach the domain
Sign-up allowlistNot available (needs an https hook URL)Available
Live view TURN hostlocalhostThe domain

The same steps from the CLI ​

The Casama CLI wraps the installer:

sh
casama selfhost init --dir ~/casama --domain casama.example.com

init takes --domain, --local, --http-port, --with-desktop and --monitoring. For --web or --no-start, run ./install.sh directly. Every casama selfhost command finds the checkout through --dir, then the CASAMA_SELFHOST_DIR environment variable, then the current directory.

First sign-in and the instance owner ​

The first account created on a new server becomes the instance owner. Owners get the admin console under Settings, where they can see the health of each service, manage workspaces and check for updates.

  1. Open the Casama app and point it at your server (see the next section).
  2. Create an account with email and password.
  3. Add a model key (or a local model endpoint) and create your first bot.

A new server doesn't send email, so start with a password: emailed sign-in links need SMTP. New accounts are confirmed automatically until you turn email confirmation on.

To name the owners explicitly instead, set INSTANCE_ADMIN_EMAILS to a comma-separated list of emails in infra/compose/.env, then run casama selfhost up.

Connect the apps and the CLI ​

In the app (iOS, Android, macOS, Windows, Linux):

  1. On the sign-in screen, tap More options.
  2. Tap the Server chip, which shows the current server.
  3. Enter your server's address, for example https://casama.example.com, and tap Connect.

The app remembers the address. If it can't reach a server, the error screen also offers Use a different server. The web app (--web) always uses the address it's served from.

With the CLI:

sh
casama config --api-url https://casama.example.com
casama signup --email you@example.com     # or: casama login --email you@example.com

You can also pass the address for a single command with the global --api option (casama --api https://casama.example.com login --email you@example.com) or set CASAMA_API_URL.

Run a server on your own computer ​

The desktop app (macOS, Windows and Linux) can install and start a local server for you:

  1. Start Docker Desktop.
  2. On the sign-in screen, tap More options → Run Casama on this computer.
  3. Tap Start the server.

The app checks that Docker and Compose v2 are running, downloads the self-host bundle into its support folder, runs install.sh --local --http-port 8080, waits for the server, then connects to http://localhost:8080. If a server already answers there, it connects right away. Only this computer can reach it.

Other ways to deploy ​

MethodWhat runsComputersWhere to start
install.sh (recommended)Everything on one Docker hostDocker on the same host, or another providerThis page
CoolifyThe same compose file, through CoolifyDocker on the Coolify serverdeploy/coolify/README.md
Kubernetes (Helm)API, worker, supervisor and optionally the web appPods in their own namespaceHelm chart
Render, Railway, DigitalOcean App PlatformAPI and worker onlyCloud Connect, the desktop companion, or a supervisor elsewheredeploy/README.md

Coolify ​

Coolify runs Docker Compose stacks with the Docker socket, so it can host the full stack.

  1. On the Coolify server, run ./install.sh --no-start --domain casama.example.com once from a checkout to generate infra/compose/.env.

  2. In Coolify, create a Docker Compose resource from the repository with the compose file infra/compose/docker-compose.yml, and paste the variables from infra/compose/.env.

  3. Let Coolify's proxy route your domain to the caddy service on port 80 and set CASAMA_SITE=:80, because Coolify terminates TLS.

  4. Build the computer image once on the server:

    sh
    docker compose -f infra/compose/docker-compose.yml --profile images build computer-headless

Render, Railway and DigitalOcean App Platform ​

These platforms have no Docker socket, so they run only the API and worker, against a Supabase project (Supabase Cloud or your own Supabase) for Postgres and Auth. Bots get computers from Cloud Connect, from people's own machines through the desktop companion, or from a supervisor you run elsewhere (SUPERVISOR_URL and SUPERVISOR_TOKEN).

PlatformFileNotes
Renderdeploy/render/render.yamlBlueprint: an API web service and a worker
Railwaydeploy/railway/railway.jsonTwo services from the same repository; set MODE on each
DigitalOcean App Platformdeploy/digitalocean/app.yamldoctl apps create --spec deploy/digitalocean/app.yaml

Before the first start, apply the migrations to the Supabase database from a checkout:

sh
supabase db push --db-url "$DATABASE_URL"

Every platform needs DATABASE_URL, SUPABASE_URL, SUPABASE_ANON_KEY, SUPABASE_JWT_SECRET (from the Supabase project settings), INTERNAL_TOKEN (32 or more random characters) and PUBLIC_APP_URL. On Railway, the API service sets MODE=api and PORT=8787; the worker sets MODE=worker and API_INTERNAL_URL to the API's private address on port 8787.

Production hardening ​

Use gVisor for computers ​

gVisor (runsc) gives each computer its own kernel boundary. Install it on the Linux host and register it with Docker (see the gVisor documentation), then check that Docker lists it:

sh
docker info | grep -i runsc

A first install picks it up automatically. On an existing install, set it yourself:

  1. In infra/compose/.env, set SANDBOX_RUNTIME=runsc.
  2. Run casama selfhost up.

New computers start under gVisor. Running computers keep their runtime until they sleep and wake.

Without gVisor, computers use Docker's default runtime (runc) together with the other controls: a non-root user, a read-only root filesystem, no capabilities, no-new-privileges, per-computer networks, the egress proxy and resource limits.

Run computers on a second host ​

For public servers, keep untrusted code and the Docker socket off the machine that holds your data. Run the supervisor, egress proxy and TURN relay on a second host, and point the API and worker at it over a private network or WireGuard. See Run computers on a separate host.

Firewall ​

  • Allow inbound 80/tcp, 443/tcp and 3478 (UDP and TCP) only. Allow 8790/tcp only if you serve Pages on a port.
  • Keep Grafana on the loopback interface and reach it through an SSH tunnel.
  • Never expose the supervisor (8788), the API's internal port (8787) or Postgres to the internet.
  • Docker's published ports bypass some host firewalls (ufw, for example). Check from another machine that only the ports above answer.

Other checks ​

  • Serve Pages from their own domain, so bots' pages never share an origin with Casama. See Pages.
  • Turn on email confirmation and set up SMTP.
  • Restrict who can sign up with DISABLE_SIGNUP or the sign-up allowlist.
  • Set up encrypted backups and copy them off the machine.
  • Consider encryption at rest for workspace content.

Apache-2.0, except ee/ (Casama Enterprise License). Contribute