Quickstart
Get Started
Configure Docker Compose
Create a docker-compose.yml file with your Monospace configuration. This example sets up:
- Monospace — the application
- PostgreSQL — system database
- RabbitMQ — event bus for email delivery and webhooks
name: monospace
services:
# ---------------------------------------------------------------------------
# PostgreSQL — system database
# ---------------------------------------------------------------------------
postgres:
image: postgres:17
restart: unless-stopped
command: postgres -c 'max_connections=200'
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: monospace
POSTGRES_DB: monospace
POSTGRES_HOST_AUTH_METHOD: md5
POSTGRES_INITDB_ARGS: --auth-host=md5
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres -d monospace"]
interval: 5s
timeout: 5s
retries: 10
networks:
- monospace
# ---------------------------------------------------------------------------
# RabbitMQ — event bus (required for email delivery & webhooks)
# ---------------------------------------------------------------------------
rabbitmq:
image: rabbitmq:3.13-management
restart: unless-stopped
environment:
RABBITMQ_DEFAULT_USER: monospace
RABBITMQ_DEFAULT_PASS: monospace
volumes:
- rabbitmq_data:/var/lib/rabbitmq
healthcheck:
test: ["CMD", "rabbitmq-diagnostics", "-q", "ping"]
interval: 10s
timeout: 5s
retries: 10
networks:
- monospace
# ---------------------------------------------------------------------------
# Key generator — ephemeral init container that writes JWT + KMS keys once
# ---------------------------------------------------------------------------
keygen:
image: alpine:3.21
command:
- sh
- -c
- |
set -e
mkdir -p /keys
# Only generate if keys don't already exist
if ! [ -f /keys/jwt_private.pem ] || ! [ -f /keys/jwt_public.pem ] || ! [ -f /keys/kms_master.key ]; then
apk add --no-cache openssl > /dev/null
openssl genpkey -algorithm ED25519 -out /keys/jwt_private.pem
openssl pkey -in /keys/jwt_private.pem -pubout -out /keys/jwt_public.pem
openssl rand -base64 32 | tr -d '\n' > /keys/kms_master.key
echo "Keys generated."
else
echo "Keys already exist, skipping generation."
fi
chown 65532:65532 /keys/jwt_private.pem /keys/jwt_public.pem /keys/kms_master.key
chmod 600 /keys/jwt_private.pem /keys/jwt_public.pem /keys/kms_master.key
volumes:
- keys_data:/keys
# ---------------------------------------------------------------------------
# Monospace — the application
# ---------------------------------------------------------------------------
monospace:
image: monospace/monospace:v0.0.4
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
rabbitmq:
condition: service_healthy
keygen:
condition: service_completed_successfully
ports:
- "8100:8100"
volumes:
- keys_data:/keys:ro
- uploads_data:/uploads
environment:
# Server
DIRECTUS_HOST: "0.0.0.0"
DIRECTUS_PORT: "8100"
DIRECTUS_BASE_URL: "http://localhost:8100"
# System database
DIRECTUS_SYSTEM_DATABASE__PROVIDER: "postgres"
DIRECTUS_SYSTEM_DATABASE__HOST: "postgres"
DIRECTUS_SYSTEM_DATABASE__PORT: "5432"
DIRECTUS_SYSTEM_DATABASE__USER: "postgres"
DIRECTUS_SYSTEM_DATABASE__PASSWORD: "monospace"
DIRECTUS_SYSTEM_DATABASE__DBNAME: "monospace"
# File storage (local, inside the container)
DIRECTUS_SYSTEM_FILE_STORAGE__PROVIDER: "local"
DIRECTUS_SYSTEM_FILE_STORAGE__ROOT_PATH: "/uploads"
# RabbitMQ
DIRECTUS_RABBITMQ__HOST: "rabbitmq"
DIRECTUS_RABBITMQ__PORT: "5672"
DIRECTUS_RABBITMQ__USER: "monospace"
DIRECTUS_RABBITMQ__PASSWORD: "monospace"
DIRECTUS_RABBITMQ__VHOST: "/"
# JWT keys (generated by keygen init container)
DIRECTUS_JWT_PRIVATE_KEY__FILE: "/keys/jwt_private.pem"
DIRECTUS_JWT_PUBLIC_KEY__FILE: "/keys/jwt_public.pem"
# KMS (generated by keygen init container)
DIRECTUS_KMS__TYPE: "directus"
DIRECTUS_KMS__MASTER_KEY__FILE: "/keys/kms_master.key"
# Auth tokens
DIRECTUS_ACCESS_TOKEN_TTL: "15m"
DIRECTUS_REFRESH_TOKEN_TTL: "7days"
# Cookie — disable Secure flag so HTTP works out of the box
DIRECTUS_COOKIE_SECURE: "false"
# Default login and password
DIRECTUS_ADMIN_EMAIL: "admin@example.com"
DIRECTUS_ADMIN_PASSWORD: "monospace"
networks:
- monospace
volumes:
postgres_data:
rabbitmq_data:
keys_data:
uploads_data:
networks:
monospace:
Start the Services
Launch all services using Docker Compose:
docker compose up -d
Wait for all containers to start (this may take 1-2 minutes on first run).
Verify services are running:
docker compose ps
Access the Studio UI
Once all services are running, access the Monospace Studio interface:
Studio UI: http://localhost:8100

Create Your First Project
Your organization is the top-level tenant. Within an organization you have projects that contain your schemas and data source connections.
Create a new project and specify:
- Project Name
- Project URL

Configure a Data Source
A system database is already configured via Docker Compose and is sufficient for local development.

To add additional data sources, navigate to Data Model > Data Sources and choose from the available connectors. Connecting multiple databases to a single project is a core capability of the platform.

Configure a Collection
Navigate to Data Model to view your Collections. If you connected an existing database, your tables will already appear as collections thanks to Database Introspection.
Each collection has tabs for managing Columns, Relations, and other configuration.

To create a new collection, click Add Collection and specify a name.

Once created, you can add columns to define the shape of your data.

Manage Your Data
Head to the Content module to browse, create, and edit items within your collections.

Next Steps
Now you're up and running with the basics. Explore the platform further:
- Organization Hierarchy - Understand the hierarchy of organizations, projects, and data sources
- Data Model - Define collections, columns, and relationships across your data sources
- Data Connectors - Connect additional databases
- Access & Permissions - Control who can access and modify your data
- System Resources - Configure project settings and manage your environment