Self-Hosting
Run TheCorporation on your own infrastructure. The platform runs as 4 Docker services built from source.
Architecture
Section titled “Architecture”| Service | Purpose | Port |
|---|---|---|
corp-private-server | Rust API server | 3000 (HTTP), 2222 (Git SSH) |
caddy | Reverse proxy, static site hosting, TLS | 80, 443 |
dragonfly | Redis-compatible KV store (metadata) | 6379 (internal) |
rustfs | S3-compatible object store (blobs) | 9000 (internal) |
Prerequisites
Section titled “Prerequisites”- Docker and Docker Compose v2
- Git
- Node.js 20+ and pnpm (for building static sites)
- ~2 GB RAM, ~10 GB disk
1. Clone both repositories
Section titled “1. Clone both repositories”The build requires both the public and private repos side by side:
mkdir thecorporation && cd thecorporationgit clone https://github.com/thecorporationai/thecorporation-mono.gitgit clone https://github.com/thecorporationai/thecorporation-internal.git2. Configure environment
Section titled “2. Configure environment”Create thecorporation-internal/ops/.env:
# ── Server ────────────────────────────────────────────────────────────────PORT=3000SSH_PORT=2222BASE_URL=https://api.yourdomain.com
# ── Corp platform ─────────────────────────────────────────────────────────CORP_DATA_DIR=/data/corpCORP_JWT_SECRET=<generate-a-random-64-char-hex-string>CORP_STORAGE_BACKEND=kvCORP_REDIS_URL=redis://dragonfly:6379
# ── S3 / RustFS ──────────────────────────────────────────────────────────CORP_S3_BUCKET=corpAWS_ENDPOINT_URL=http://rustfs:9000AWS_REGION=us-east-1AWS_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:
openssl rand -hex 32Environment variables reference
Section titled “Environment variables reference”| Variable | Required | Description |
|---|---|---|
PORT | Yes | API server HTTP port (default: 3000) |
SSH_PORT | Yes | Git-over-SSH port for corp --local access (default: 2222) |
BASE_URL | Yes | Public URL for the API (used in CORS, webhooks) |
CORP_DATA_DIR | Yes | Directory for entity data inside the container |
CORP_JWT_SECRET | Yes | Secret for signing JWT auth tokens |
CORP_STORAGE_BACKEND | Yes | git, kv, or kv+s3 (see Storage Backends below) |
CORP_REDIS_URL | When using kv or kv+s3 | Redis/Dragonfly connection URL |
CORP_S3_BUCKET | When using kv+s3 | S3 bucket name for durable blob storage |
AWS_ENDPOINT_URL | When using RustFS | S3-compatible endpoint URL |
AWS_REGION | When using S3 | AWS region |
AWS_ACCESS_KEY_ID | When using S3/RustFS | S3 access key |
AWS_SECRET_ACCESS_KEY | When using S3/RustFS | S3 secret key |
RUSTFS_ROOT_USER | Yes | RustFS admin username (must match AWS_ACCESS_KEY_ID) |
RUSTFS_ROOT_PASSWORD | Yes | RustFS admin password (must match AWS_SECRET_ACCESS_KEY) |
3. Build and start services
Section titled “3. Build and start services”From the thecorporation-internal/ops/ directory:
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 servicesdocker compose up -d
# Verify the API is healthycurl http://localhost:3000/health# → ok4. Build static sites
Section titled “4. Build static sites”The web UI, docs, and terminal interface are Astro static sites served by Caddy. Build them before they can be served:
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 sitesCORP_API_URL=http://$BACKEND_IP:3000 npm run build:wwwnpm run build:docspnpm --filter @corp/humans build
# Restart Caddy to serve the new filescd ../../opsdocker compose restart caddy5. Configure your domain
Section titled “5. Configure your domain”Edit thecorporation-internal/ops/Caddyfile and replace all thecorporation.ai references with your domain. You need 4 vhosts:
| Subdomain | Purpose |
|---|---|
yourdomain.com | Redirects to www.yourdomain.com |
www.yourdomain.com | Marketing site |
api.yourdomain.com | API server (reverse proxy to port 3000) |
docs.yourdomain.com | Documentation |
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:
docker compose restart caddyStorage backends
Section titled “Storage backends”KV backend (recommended for production)
Section titled “KV backend (recommended for production)”Uses Dragonfly (Redis-compatible) for all metadata. This is the default in the provided docker-compose.yml.
CORP_STORAGE_BACKEND=kvCORP_REDIS_URL=redis://dragonfly:6379KV + S3 backend (durable mode)
Section titled “KV + S3 backend (durable mode)”Adds S3-compatible storage (RustFS) for blob durability. KV holds refs and metadata; S3 holds immutable content-addressed blobs.
CORP_STORAGE_BACKEND=kv+s3CORP_REDIS_URL=redis://dragonfly:6379CORP_S3_BUCKET=corpGit backend (development only)
Section titled “Git backend (development only)”Stores everything in bare git repos on the filesystem. No external services needed, but does not scale well under concurrent writes.
CORP_STORAGE_BACKEND=gitConnect the CLI
Section titled “Connect the CLI”corp config set api_url http://localhost:3000corp config set api_key <your-api-key>corp statusOr use --local to bypass the server and read from CORP_DATA_DIR directly:
corp --local entities listConnect MCP
Section titled “Connect MCP”npx -y @thecorporation/mcp-serverSee MCP Quickstart for details.
Backups
Section titled “Backups”KV backend
Section titled “KV backend”Dragonfly persists data to its Docker volume. Back up the dragonfly-data volume:
docker run --rm -v ops_dragonfly-data:/data -v $(pwd):/backup \ alpine tar czf /backup/dragonfly-backup.tar.gz /dataGit backend
Section titled “Git backend”The entire state lives under CORP_DATA_DIR. A simple volume snapshot or rsync is a complete backup:
docker run --rm -v ops_corp-data:/data -v $(pwd):/backup \ alpine tar czf /backup/corp-data-backup.tar.gz /dataPorts reference
Section titled “Ports reference”| Port | Service | Protocol | Purpose |
|---|---|---|---|
| 80 | Caddy | HTTP | Web traffic (redirects to HTTPS when TLS configured) |
| 443 | Caddy | HTTPS | Web traffic with TLS |
| 3000 | corp-private-server | HTTP | API server |
| 2222 | corp-private-server | SSH | Git-over-SSH for --local CLI access |
| 6379 | Dragonfly | Redis | KV metadata store (internal only) |
| 9000 | RustFS | S3 | Object storage (internal only) |