Self-hosting Community Edition
Start Monad Community Edition on an apex domain and its chat subdomain, then claim the single chat workspace through email verification.
Monad Community Edition is a web-only, single-workspace deployment. Configure
two hosts: your apex site, such as example.com, and the application at
chat.example.com. The tenant and workspace slugs are both fixed to chat.
Before you start
The supported deployment needs Bun, PostgreSQL with the extensions and logical
replication settings in docker/Dockerfile.postgres, and persistent storage for
the database. The included Docker Compose file supplies a compatible PostgreSQL
service and optional MinIO object storage.
Copy .env.example to .env.local and set at least:
APP_DOMAINto the apex host without a scheme, for exampleexample.com.DATABASE_URLto a direct PostgreSQL connection. Do not use a transaction pooler for migrations, logical replication, or pub/sub listeners.SECRETS_PHRASEto a long value from a secret manager. It protects sessions, OAuth state, and encrypted integration credentials; changing it without a coordinated credential migration makes stored secrets unreadable.MONAD_INITIAL_OWNER_EMAILto the mailbox that will claim the fixed workspace.RESEND_API_KEYandEMAIL_FROMfor verification, invitation, and reset email.
Create DNS records for both the apex and chat host, route both to the same
Monad service, and terminate HTTPS at the reverse proxy. Preserve the incoming
Host, X-Forwarded-Host, X-Forwarded-Proto, and client-address headers. Do
not publish the application over plain HTTP outside local development.
Start and claim the instance
Install the pinned dependencies, apply migrations, and start the server:
bun install --frozen-lockfile
bun run db:migrate
bun run build
bun run start
After PostgreSQL is available, apply migrations and start Monad. On its first
start, CE creates the chat workspace, the built-in Monad assistant, and exactly
two starter spaces: #general and #random. Concurrent replicas use a database
lock, so only one performs this initialization.
Before first start, set MONAD_INITIAL_OWNER_EMAIL, RESEND_API_KEY, and
EMAIL_FROM. Monad sends that owner the normal verification link after the
fixed workspace is created. The owner verifies the address, chooses a handle,
display name, and password on /accept-invite, then signs in. If Resend rejects
delivery, bootstrap does not commit its marker and the next startup safely
rotates the token and retries.
Additional members and approved guest-link claimants use the same Resend-backed verification and account-setup flow. Verification tokens are never returned in Settings or agent output.
Account recovery
CE includes the normal forgot-password and Resend reset-email flow. Users should
still enroll a passkey under Settings → Account → Security as a second sign-in
method. Keep RESEND_API_KEY and the sending domain operational; without email
delivery, users who also lose every passkey cannot complete in-app recovery.
Storage and optional services
Object payloads use PostgreSQL when the three S3 credentials are absent. To use
AWS S3, MinIO, or another compatible service, set S3_ACCESS_KEY_ID,
S3_SECRET_ACCESS_KEY, and S3_BUCKET; S3_ENDPOINT is needed for a custom
endpoint and S3_REGION defaults to us-east-1. A partially configured S3
block falls back to PostgreSQL and emits a warning. When S3 is enabled, new
objects are written there and reads retain a PostgreSQL fallback for objects
that have not migrated yet.
Users can add their own OpenRouter and Firecrawl keys in Settings, or operators
can provide deployment-wide OPENROUTER_API_KEY and FIRECRAWL_API_KEY values.
Web Push is optional and requires one stable VAPID pair:
NEXT_PUBLIC_VAPID_PUBLIC_KEY, VAPID_PRIVATE_KEY, and
VAPID_CONTACT_EMAIL. Missing VAPID configuration disables push without
disabling the rest of CE.
Backups and recovery
Back up PostgreSQL with a consistent tool such as pg_dump --format=custom and
test restores into a separate database. A PostgreSQL-only deployment is fully
covered by that database backup. If S3 is configured, back up or version the
bucket as well: PostgreSQL contains object metadata, but newly uploaded bytes
live in the bucket. Keep the database and bucket recovery points together.
Back up .env.local through the secret manager, especially SECRETS_PHRASE
and VAPID keys. Do not place secrets in the database dump archive. Recovery is
complete only after a restored instance can read an existing encrypted MCP or
connector credential and download a representative object.
Upgrades
Before upgrading, read the release notes and take a database backup plus a
bucket backup when S3 is enabled. Build the new release, run
bun run db:migrate once against the direct database URL, and then replace the
application replicas. Migrations are forward-only: do not run an older Monad
binary against an upgraded database. A rollback that crosses a migration
boundary requires restoring the matching pre-upgrade database and bucket
backup.
The historical migration stream is intentionally preserved. CE replays it and then applies shared migrations plus the CE stream; it never receives new Cloud-only migration SQL. Moving an existing Cloud database to CE is not a supported downgrade because the CE cleanup migration deliberately removes hosted-only state.
Health checks and troubleshooting
Use GET /api/health as the basic process health check. Operators diagnosing
realtime delivery can also inspect /api/health/cdc and
/api/health/sync-v2; either returns 503 when its stream is unhealthy. Check
structured server logs for database, object-store, or VAPID configuration
warnings, and set LOG_LEVEL=debug only for short diagnostic windows because
it is intentionally more verbose.
Workspace owners and admins can open Settings → About this instance to copy the CE source revision and current schema migration for a support or security report. The same page shows whether PostgreSQL or S3 stores objects and whether Web Push, OpenRouter, Firecrawl, the connector framework, and MCP are ready. An optional service that you did not configure is shown as Not configured; an incomplete configuration is shown as Needs attention with the missing environment variable names.
CE refuses to start if the database contains another tenant or workspace, or if either fixed slug was renamed. It does not silently choose among rows. Use the Cloud edition when the deployment needs multiple workspaces, managed billing, managed connectors, native apps, or hosted operations.