Skip to main content

Docker Deployment

Run Spacebot in a container. Two image variants: slim (no browser) and full (includes Chromium for browser workers).

Quick Start

docker run -d \
  --name spacebot \
  -e ANTHROPIC_API_KEY="sk-ant-..." \
  -v spacebot-data:/data \
  -p 19898:19898 \
  ghcr.io/spacedriveapp/spacebot:slim
The web UI is available at http://localhost:19898.

Image Variants

spacebot:slim

Minimal runtime. Everything works except the browser tool.
  • Base: debian:bookworm-slim
  • Size: ~150MB
  • Includes: Spacebot binary, CA certs, SQLite libs, bubblewrap (process sandbox), embedded frontend

spacebot:full

Includes Chromium for browser workers (headless Chrome automation via CDP).
  • Base: debian:bookworm-slim + Chromium
  • Size: ~800MB
  • Includes: everything in slim + Chromium + browser dependencies
Use slim for most deployments. Only use full if you need the browser tool for web automation tasks.

Data Volume

All persistent data lives at /data inside the container. Mount a volume here.
/data/
├── config.toml              # optional, can use env vars instead
├── embedding_cache/         # FastEmbed model cache (~100MB, downloaded on first run)
├── agents/
│   └── main/
│       ├── workspace/       # identity files (SOUL.md, IDENTITY.md, USER.md)
│       ├── data/            # SQLite, LanceDB, redb databases
│       └── archives/        # compaction transcripts
└── logs/                    # log files (daily rotation)
On first launch with no config, Spacebot creates a default main agent with template identity files. The FastEmbed model (~100MB) downloads on first memory operation — subsequent starts use the cache.

Configuration

Environment Variables

The simplest approach. No config file needed.
docker run -d \
  --name spacebot \
  -e ANTHROPIC_API_KEY="sk-ant-..." \
  -e DISCORD_BOT_TOKEN="..." \
  -v spacebot-data:/data \
  -p 19898:19898 \
  ghcr.io/spacedriveapp/spacebot:slim
Available environment variables:
VariableDescription
ANTHROPIC_API_KEYAnthropic API key
OPENAI_API_KEYOpenAI API key
OPENROUTER_API_KEYOpenRouter API key
DISCORD_BOT_TOKENDiscord bot token
SLACK_BOT_TOKENSlack bot token
SLACK_APP_TOKENSlack app token
BRAVE_SEARCH_API_KEYBrave Search API key
SPACEBOT_CHANNEL_MODELOverride channel model
SPACEBOT_WORKER_MODELOverride worker model

Config File

Mount a config file into the volume for full control:
docker run -d \
  --name spacebot \
  -v spacebot-data:/data \
  -v ./config.toml:/data/config.toml:ro \
  -p 19898:19898 \
  ghcr.io/spacedriveapp/spacebot:slim
Config values can reference environment variables with env:VAR_NAME:
[llm]
anthropic_key = "env:ANTHROPIC_API_KEY"
The docker-entrypoint.sh script automatically generates a config.toml from environment variables when no config file exists. Once a config.toml is present on the volume, this generation is skipped entirely.

Docker Compose

services:
  spacebot:
    image: ghcr.io/spacedriveapp/spacebot:slim
    container_name: spacebot
    restart: unless-stopped
    ports:
      - "19898:19898"
    volumes:
      - spacebot-data:/data
    environment:
      - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
      # Optional:
      # - DISCORD_BOT_TOKEN=${DISCORD_BOT_TOKEN}

volumes:
  spacebot-data:
The shm_size and seccomp settings are needed for Chromium to run properly in a container.

Building the Image

From the spacebot repo root:
1

Clone the repository

git clone https://github.com/spacedriveapp/spacebot.git
cd spacebot
2

Build the image

# Slim (no browser)
docker build --target slim -t spacebot:slim .

# Full (with Chromium)
docker build --target full -t spacebot:full .
The multi-stage Dockerfile:
  1. Builder stage — Rust toolchain + Bun. Compiles the React frontend, then builds the Rust binary with the frontend embedded.
  2. Slim stage — Minimal Debian runtime with the compiled binary.
  3. Full stage — Slim + Chromium and its dependencies.
Build time is ~5-10 minutes on first build (downloading and compiling Rust dependencies). Subsequent builds use the cargo cache.

Ports

PortService
19898HTTP API + Web UI
18789Webhook receiver (if enabled in config)
The API server binds to 0.0.0.0 inside the container (overriding the default 127.0.0.1 bind). The webhook port is only needed if you enable the webhook messaging adapter.

Health Check

The API server responds to GET /api/health. Use this for container health checks:
healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost:19898/api/health"]
  interval: 30s
  timeout: 5s
  retries: 3

Container Behavior

  • Spacebot runs in foreground mode (--foreground) inside the container. No daemonization.
  • Logs go to stdout/stderr. Use docker logs to view them.
  • Graceful shutdown on SIGTERM (what docker stop sends). Drains active channels, closes database connections.
  • The PID file and Unix socket (used in daemon mode) are not created.

Updates

Spacebot checks for new releases on startup and every hour. When a new version is available, a banner appears in the web UI. You can also open Settings → Updates for update status, one-click apply controls (Docker), and manual command snippets.
latest is supported and continues to receive updates (it tracks the rolling full image). Use explicit version tags only when you want controlled rollouts.

Manual Update

docker compose pull spacebot
docker compose up -d --force-recreate spacebot

One-Click Update

Mount the Docker socket to enable updating directly from the web UI:
services:
  spacebot:
    image: ghcr.io/spacedriveapp/spacebot:slim
    container_name: spacebot
    restart: unless-stopped
    ports:
      - "19898:19898"
    volumes:
      - spacebot-data:/data
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
When the socket is mounted, the update banner shows an Update now button that pulls the new image and recreates the container automatically. Your /data volume is preserved across updates.
Without the socket mount, the banner still notifies you of new versions but you’ll need to update manually.
One-click updates are intended for containers running Spacebot release tags. If you’re running a custom/self-built image, update by rebuilding your image and recreating the container.

Update API

You can also check for and trigger updates programmatically:
# Check for updates
curl http://localhost:19898/api/update/check

# Force a fresh check
curl -X POST http://localhost:19898/api/update/check

# Apply update (requires Docker socket)
curl -X POST http://localhost:19898/api/update/apply

CI / Releases

Images are built and pushed to ghcr.io/spacedriveapp/spacebot via GitHub Actions (.github/workflows/release.yml). Triggers:
  • Push a v* tag (e.g. git tag v0.1.0 && git push --tags)
  • Manual dispatch from the Actions tab
Tags pushed per release:
TagDescription
v0.1.0-slimVersioned slim
v0.1.0-fullVersioned full
slimRolling slim
fullRolling full
latestRolling (points to full)

Example: Discord Bot Deployment

1

Create a Discord bot

  1. Go to Discord Developer Portal
  2. Create a new application
  3. Go to the Bot tab and create a bot
  4. Copy the bot token
  5. Enable Message Content Intent under Privileged Gateway Intents
2

Invite the bot to your server

Go to OAuth2 → URL Generator:
  • Scopes: bot, applications.commands
  • Bot Permissions: Send Messages, Read Message History, Add Reactions, Embed Links
Copy the generated URL and open it to invite the bot to your server.
3

Deploy with Docker Compose

Create docker-compose.yml:
services:
  spacebot:
    image: ghcr.io/spacedriveapp/spacebot:slim
    container_name: spacebot
    restart: unless-stopped
    ports:
      - "19898:19898"
    volumes:
      - spacebot-data:/data
    environment:
      - ANTHROPIC_API_KEY=sk-ant-your-key-here
      - DISCORD_BOT_TOKEN=your-discord-token-here
      - DISCORD_GUILD_ID=your-guild-id-here

volumes:
  spacebot-data:
Start the container:
docker compose up -d
4

Send your first message

In your Discord server, send a message mentioning the bot:
@Spacebot hello!
The bot will respond in the same channel.

Troubleshooting

Container won’t start

Check the logs:
docker logs spacebot
Common issues:
  • Missing API key environment variable
  • Invalid config.toml syntax
  • Port 19898 already in use

Browser tool not working

Make sure you’re using the full image variant:
docker pull ghcr.io/spacedriveapp/spacebot:full
The slim image does not include Chromium.

Web UI shows empty page

The frontend is embedded in the binary during build. If you built the image without the web UI dependencies, you’ll see an empty page. Pull the official image:
docker pull ghcr.io/spacedriveapp/spacebot:latest

Memory usage growing over time

Spacebot uses LanceDB for vector storage, which can grow over time. You can configure memory decay and pruning in config.toml. See the Memory System documentation.

Next Steps

Configuration

Full config.toml reference with all available options

Discord Setup

Detailed Discord bot setup guide

Model Routing

Configure multi-tier model routing with fallback chains

Memory System

Structured knowledge graph with typed memories and associations

Build docs developers (and LLMs) love