Deploy with Docker
Host Sugabots on a server or a hosting platform so your team can use it.
The Quickstart runs Sugabots on your own computer. To use it with other people, host it somewhere they can reach over HTTPS, and set up email so they receive their invites.
Sugabots is a single Docker image, ghcr.io/nitrictech/sugabots, that serves
both the web app and the API. It stores everything in PostgreSQL 18.
Requirements
- A Linux server with Docker and Docker Compose, or a hosting platform that runs Docker images
- A domain name, such as
sugabots.example.com, pointed at the server - An email provider, such as Resend
On your own server
-
Create
compose.ymlMake a folder for Sugabots, and save this in it as
compose.yml. Replacesugabots.example.comwith your domain, andexample.comin the sender with the domain you'll send email from.compose.yml name: sugabots services: sugabots: image: ghcr.io/nitrictech/sugabots:latest ports: - "3000:3000" environment: DATABASE_URL: postgres://sugabots:${POSTGRES_PASSWORD}@postgres:5432/sugabots PUBLIC_URL: https://sugabots.example.com BETTER_AUTH_SECRET: ${BETTER_AUTH_SECRET:?Set it in .env} CREDENTIALS_ENCRYPTION_KEY: ${CREDENTIALS_ENCRYPTION_KEY:?Set it in .env} EMAIL_PROVIDER: resend EMAIL_RESEND_API_KEY: ${EMAIL_RESEND_API_KEY:?Set it in .env} EMAIL_TRANSACTIONAL_FROM: Sugabots <no-reply@example.com> depends_on: postgres: condition: service_healthy restart: unless-stopped postgres: image: postgres:18-alpine environment: POSTGRES_USER: sugabots POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?Set it in .env} POSTGRES_DB: sugabots volumes: - postgres_data:/var/lib/postgresql healthcheck: test: ["CMD-SHELL", "pg_isready -U sugabots -d sugabots"] interval: 5s retries: 12 restart: unless-stopped volumes: postgres_data:PUBLIC_URLmust be the address people see in their browser: links in emails and sign-in redirects are built from it. Every other setting is in the configuration reference.To keep files on a volume rather than in the database, add those settings now, before anyone uses Sugabots.
-
Create
.envIn the same folder, generate the database password and the two secret keys:
Terminal echo "POSTGRES_PASSWORD=$(openssl rand -hex 32)" >> .env echo "BETTER_AUTH_SECRET=$(openssl rand -base64 32)" >> .env echo "CREDENTIALS_ENCRYPTION_KEY=$(openssl rand -base64 32)" >> .envThen add your Resend API key. If you don't have one yet, follow Resend to get one:
.env EMAIL_RESEND_API_KEY=re_your_api_key -
Start Sugabots
Terminal docker compose up -dSugabots sets up its database on the first start. Check that it's running with
docker compose logs sugabots. -
Add HTTPS
Sugabots serves plain HTTP on port 3000. Put a reverse proxy in front of it to serve HTTPS. With Caddy, which gets and renews certificates automatically, add this to
/etc/caddy/Caddyfile:/etc/caddy/Caddyfile sugabots.example.com { reverse_proxy 127.0.0.1:3000 }Then reload Caddy:
Terminal sudo systemctl reload caddyYour domain's DNS must already point at the server for Caddy to get a certificate.
Another reverse proxy works too, as long as it:
- passes WebSocket connections, which a bot's live desktop uses
- accepts uploads up to 30 MB, the largest file people can attach
Caddy does both by default. nginx does neither until it's told to: without these settings, a bot's desktop never connects, and most phone photos are refused as too large. Add this to
/etc/nginx/sites-available/sugabots, and link it into/etc/nginx/sites-enabled/:/etc/nginx/sites-available/sugabots map $http_upgrade $connection_upgrade { default upgrade; '' close; } server { listen 80; server_name sugabots.example.com; # Room for a 30 MB attachment. nginx's default is 1 MB. client_max_body_size 32m; location / { proxy_pass http://127.0.0.1:3000; proxy_http_version 1.1; # Passes WebSocket connections on to Sugabots. proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_set_header Host $host; } }Check the configuration and reload nginx, then add HTTPS with Certbot, which adds the certificate to this server block:
Terminal sudo nginx -t && sudo systemctl reload nginx sudo certbot --nginx -d sugabots.example.com -
Create your account
Open
https://sugabots.example.comand sign up. A new installation lets its first account in without an invitation, and you own the workspace you create.
On a hosting platform
Platforms such as Suga, Railway and Render can run the image and provide HTTPS.
On Suga, the
Sugabots template
creates the service and its PostgreSQL 18 database for you. On other platforms,
create a PostgreSQL 18 database, then a service from
ghcr.io/nitrictech/sugabots:latest.
Either way, the service needs these settings:
DATABASE_URL: the database's connection stringPUBLIC_URL: the service's HTTPS addressBETTER_AUTH_SECRETandCREDENTIALS_ENCRYPTION_KEY: generate each withopenssl rand -base64 32- The email settings from
compose.ymlabove:EMAIL_PROVIDER,EMAIL_RESEND_API_KEYandEMAIL_TRANSACTIONAL_FROM
See the configuration reference for what each does.
Files on a volume
Sugabots keeps files, such as attachments and large tool results, in the
database unless told otherwise. There, every file adds to the database and its
backups, and each one is held in memory while it's saved. To keep them on a
volume instead, add these settings and a files volume to compose.yml,
keeping what's already there:
services:
sugabots:
environment:
BLOB_STORE_PROVIDER: filesystem
BLOB_STORE_FILESYSTEM_ROOT: /data/files
volumes:
- files:/data/files
volumes:
postgres_data:
files:Add both: without the volume, files are lost when the container is replaced,
such as when you update. Then run docker compose up -d. The compose.yml
the Quickstart downloads has these lines, commented out.
Choose before you start using Sugabots. Files already kept stay in the database, and Sugabots can't open them unless you switch back.
To keep files in a folder on the server rather than a Docker volume, make the folder and give it to the user Sugabots runs as:
sudo mkdir -p /srv/sugabots/files
sudo chown 1000:1000 /srv/sugabots/filesKeep the two settings, but mount the folder in place of files:/data/files,
and leave out files: at the end:
services:
sugabots:
volumes:
- /srv/sugabots/files:/data/filesIf Sugabots can't write to the folder, it stops, and
docker compose logs sugabots says why.
On a hosting platform, attach a persistent disk at /data/files, set the same
two settings, and run one copy of the service: the disk belongs to one server.
Without a disk, keep the default: files kept in the container are lost when
it's replaced.
Sugabots sends email for invites and address verification. Without a provider, emails are only printed to the logs, and you have to send people their links yourself.
Resend
-
Verify your domain
Create a Resend account. Under Domains, add the domain you'll send from, add the DNS records Resend shows you, and wait for the domain to be verified.
-
Create an API key
Under API Keys, create a key with Sending access.
-
Configure Sugabots
Put the key in
.envasEMAIL_RESEND_API_KEY, and setEMAIL_TRANSACTIONAL_FROMincompose.ymlto an address on the domain you verified. Then restart withdocker compose up -d, and invite someone from Settings → Members to check that email arrives.
Other providers
To send through another provider, point Sugabots at a small service of your own that passes each email on. See the webhook settings in the configuration reference.
Resend is the first provider built in, and more are on the way. Each one is a short module in the Sugabots repository, so if yours isn't supported yet, adding it is a welcome contribution.
Sandboxes
To run your bots' sandboxes on your own server with Docker, the server needs Linux 5.9 or later. Check which version it runs with:
uname -rOn an older version, sandboxes start and bots can run commands in them, but nothing opens from the dock on a sandbox's desktop: its apps bounce and never appear. Ubuntu 20.04, for example, comes with 5.4. Install a newer kernel, or a newer release of your operating system, and restart the server.
What OpenSandbox can see
OpenSandbox adds your connections' credentials to a sandbox's requests as they leave it. For secure (HTTPS) connections, it decrypts each one beside the sandbox, adds the credentials, and encrypts it again before it goes on to the site. So OpenSandbox can read the sandbox's connections, the browser's on its desktop included, and whoever runs your OpenSandbox can see what's sent through them, such as a password typed into a site.
If you run OpenSandbox yourself, that's you. Otherwise, choose someone you'd trust with it.
Updating
Back up first, then pull the new image and restart:
docker compose pull
docker compose up -dSugabots applies any database migrations when it starts.
To try changes before they're released, use ghcr.io/nitrictech/sugabots:edge
instead of :latest. It's rebuilt each time the main branch changes, so it can
break. Each build is also tagged sha- and its commit, such as
sha-a1b2c3d, if you want to stay on one.
Backups
Back up two things: the database, and the .env file holding the keys. Keep
them together: without its keys, a restored database can't read its saved API
keys, and everyone has to sign in again.
To write the database to a file:
docker compose exec -T postgres pg_dump -U sugabots sugabots > sugabots-backup.sqlTo restore, put the .env from the same backup beside compose.yml. Then
stop Sugabots, replace the database with an empty one, load the backup, and
start Sugabots again:
docker compose stop sugabots
docker compose exec -T postgres dropdb -U sugabots sugabots
docker compose exec -T postgres createdb -U sugabots sugabots
docker compose exec -T postgres psql -U sugabots -d sugabots < sugabots-backup.sql
docker compose start sugabotsThis deletes whatever is in the database before loading the backup. If the backup is from an older version, Sugabots applies the newer migrations when it starts.
If you keep files on a volume, back it up after the database, and restore it from the same backup: the database lists the files, and the volume holds them. In the same folder, write the volume to a file:
docker run --rm -v sugabots_files:/data/files -v "$PWD":/backup alpine \
tar czf /backup/sugabots-files.tar.gz -C /data/files .To restore it, run this before docker compose start sugabots above:
docker run --rm -v sugabots_files:/data/files -v "$PWD":/backup alpine \
tar xzf /backup/sugabots-files.tar.gz -C /data/filesFor a folder on the server, archive the folder itself instead.
On a hosting platform, use the platform's database backups, and its disk backups if you keep files on a disk. Keep a copy of the two keys too.
Building the image yourself
To run your own changes, build the image from a checkout of the repository and
use it in place of ghcr.io/nitrictech/sugabots:latest:
docker build -t sugabots .