Skip to content

Self-Hosting

Run TheCorporation on your own infrastructure. The platform runs as 4 Docker services built from source.

ServicePurposePort
corp-private-serverRust API server3000 (HTTP), 2222 (Git SSH)
caddyReverse proxy, static site hosting, TLS80, 443
dragonflyRedis-compatible KV store (metadata)6379 (internal)
rustfsS3-compatible object store (blobs)9000 (internal)

  • Docker and Docker Compose v2
  • Git
  • Node.js 20+ and pnpm (for building static sites)
  • ~2 GB RAM, ~10 GB disk

The build requires both the public and private repos side by side:

Terminal window
mkdir thecorporation && cd thecorporation
git clone https://github.com/thecorporationai/thecorporation-mono.git
git clone https://github.com/thecorporationai/thecorporation-internal.git

Create thecorporation-internal/ops/.env:

Terminal window
# ── Server ────────────────────────────────────────────────────────────────
PORT=3000
SSH_PORT=2222
BASE_URL=https://api.yourdomain.com
# ── Corp platform ─────────────────────────────────────────────────────────
CORP_DATA_DIR=/data/corp
CORP_JWT_SECRET=<generate-a-random-64-char-hex-string>
CORP_STORAGE_BACKEND=kv
CORP_REDIS_URL=redis://dragonfly:6379
# ── S3 / RustFS ──────────────────────────────────────────────────────────
CORP_S3_BUCKET=corp
AWS_ENDPOINT_URL=http://rustfs:9000
AWS_REGION=us-east-1
AWS_ACCESS_KEY_ID=<your-rustfs-access-key>
AWS_SECRET_ACCESS_KEY=<your-rustfs-secret-key>
# ── RustFS credentials ───────────────────────────────────────────────────
RUSTFS_ROOT_USER=<same-as-AWS_ACCESS_KEY_ID>
RUSTFS_ROOT_PASSWORD=<same-as-AWS_SECRET_ACCESS_KEY>

Generate a JWT secret:

Terminal window
openssl rand -hex 32
VariableRequiredDescription
PORTYesAPI server HTTP port (default: 3000)
SSH_PORTYesGit-over-SSH port for corp --local access (default: 2222)
BASE_URLYesPublic URL for the API (used in CORS, webhooks)
CORP_DATA_DIRYesDirectory for entity data inside the container
CORP_JWT_SECRETYesSecret for signing JWT auth tokens
CORP_STORAGE_BACKENDYesgit, kv, or kv+s3 (see Storage Backends below)
CORP_REDIS_URLWhen using kv or kv+s3Redis/Dragonfly connection URL
CORP_S3_BUCKETWhen using kv+s3S3 bucket name for durable blob storage
AWS_ENDPOINT_URLWhen using RustFSS3-compatible endpoint URL
AWS_REGIONWhen using S3AWS region
AWS_ACCESS_KEY_IDWhen using S3/RustFSS3 access key
AWS_SECRET_ACCESS_KEYWhen using S3/RustFSS3 secret key
RUSTFS_ROOT_USERYesRustFS admin username (must match AWS_ACCESS_KEY_ID)
RUSTFS_ROOT_PASSWORDYesRustFS admin password (must match AWS_SECRET_ACCESS_KEY)

From the thecorporation-internal/ops/ directory:

Terminal window
cd thecorporation-internal/ops
# Build the Rust server (first build takes ~5 min, cached rebuilds ~1 min)
docker compose build corp-private-server
# Start all services
docker compose up -d
# Verify the API is healthy
curl http://localhost:3000/health
# → ok

The web UI, docs, and terminal interface are Astro static sites served by Caddy. Build them before they can be served:

Terminal window
cd thecorporation-internal/services/web
# Get the backend container IP (needed for www build)
BACKEND_IP=$(docker inspect ops-corp-private-server-1 \
--format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' | head -1)
# Build all 3 sites
CORP_API_URL=http://$BACKEND_IP:3000 npm run build:www
npm run build:docs
pnpm --filter @corp/humans build
# Restart Caddy to serve the new files
cd ../../ops
docker compose restart caddy

Edit thecorporation-internal/ops/Caddyfile and replace all thecorporation.ai references with your domain. You need 4 vhosts:

SubdomainPurpose
yourdomain.comRedirects to www.yourdomain.com
www.yourdomain.comMarketing site
api.yourdomain.comAPI server (reverse proxy to port 3000)
docs.yourdomain.comDocumentation

For automatic TLS, change the http:// prefixes to your domain names (Caddy provisions Let’s Encrypt certificates automatically when you use bare domain names instead of http://).

After editing, restart Caddy:

Terminal window
docker compose restart caddy

Uses Dragonfly (Redis-compatible) for all metadata. This is the default in the provided docker-compose.yml.

Terminal window
CORP_STORAGE_BACKEND=kv
CORP_REDIS_URL=redis://dragonfly:6379

Adds S3-compatible storage (RustFS) for blob durability. KV holds refs and metadata; S3 holds immutable content-addressed blobs.

Terminal window
CORP_STORAGE_BACKEND=kv+s3
CORP_REDIS_URL=redis://dragonfly:6379
CORP_S3_BUCKET=corp

Stores everything in bare git repos on the filesystem. No external services needed, but does not scale well under concurrent writes.

Terminal window
CORP_STORAGE_BACKEND=git

Terminal window
corp config set api_url http://localhost:3000
corp config set api_key <your-api-key>
corp status

Or use --local to bypass the server and read from CORP_DATA_DIR directly:

Terminal window
corp --local entities list

Terminal window
npx -y @thecorporation/mcp-server

See MCP Quickstart for details.


Dragonfly persists data to its Docker volume. Back up the dragonfly-data volume:

Terminal window
docker run --rm -v ops_dragonfly-data:/data -v $(pwd):/backup \
alpine tar czf /backup/dragonfly-backup.tar.gz /data

The entire state lives under CORP_DATA_DIR. A simple volume snapshot or rsync is a complete backup:

Terminal window
docker run --rm -v ops_corp-data:/data -v $(pwd):/backup \
alpine tar czf /backup/corp-data-backup.tar.gz /data

PortServiceProtocolPurpose
80CaddyHTTPWeb traffic (redirects to HTTPS when TLS configured)
443CaddyHTTPSWeb traffic with TLS
3000corp-private-serverHTTPAPI server
2222corp-private-serverSSHGit-over-SSH for --local CLI access
6379DragonflyRedisKV metadata store (internal only)
9000RustFSS3Object storage (internal only)