This guide covers production deployment, configuration, and operations for OnePlatform — a self-hosted data integration and low-code application platform.
Prerequisites
| Requirement | Minimum | Recommended |
| Docker | 24.x | latest stable |
| Docker Compose | v2.20+ | latest stable |
| RAM | 4 GB | 8 GB+ |
| CPU | 2 cores | 4 cores+ |
| Disk | 20 GB | 100 GB+ (depends on data volume) |
| OS | Linux (amd64 or arm64) | Ubuntu 22.04 LTS |
Quick Start
# 1. Clone the repository
git clone https://github.com/your-org/oneplatform.git
cd oneplatform
# 2. Copy the example environment file and fill in secrets
cp .env.example .env
$EDITOR .env
# 3. Start all services
docker compose -f docker/docker-compose.yml up -d
# 4. Follow the first-run wizard in your browser
open http://localhost:8080
Note: The UI is served on port 8080. The API gateway listens on port 3000.
The setup wizard (bootstrap) runs automatically on first launch. It guides you through creating the first admin user and generates the master encryption key. Save the master key before the timer expires — it cannot be recovered.
Configuration
All configuration is done through environment variables. Copy .env.example to .env and customise the values below.
Core settings
| Variable | Default | Description |
OP_BASE_URL | http://localhost:8080 | Public-facing URL including protocol and port. Must match the address users type in their browser. Used in redirect URIs, email links, and CORS. |
OP_ALLOWED_ORIGINS | http://localhost:8080 | Comma-separated list of allowed CORS origins. In production set this to your exact frontend URL. |
Database
| Variable | Default | Description |
POSTGRES_PASSWORD | dev_postgres_superuser | Superuser password for the internal PostgreSQL instance. Change this in production. |
Object storage (MinIO)
| Variable | Default | Description |
OP_MINIO_USER | minioadmin | MinIO root username. Change in production. |
OP_MINIO_PASSWORD | (required) | MinIO root password. Set a strong random value. |
Email (SMTP)
Email is optional. When unset, password reset and email verification are disabled.
| Variable | Default | Description |
OP_SMTP_HOST | (empty) | SMTP server hostname (e.g. smtp.sendgrid.net). |
OP_SMTP_PORT | (empty) | SMTP port (typically 587 for STARTTLS or 465 for SSL). |
OP_SMTP_USER | (empty) | SMTP authentication username. |
OP_SMTP_PASS | (empty) | SMTP authentication password. |
OP_SMTP_FROM | (empty) | From address for outgoing emails (e.g. noreply@example.com). |
OP_SMTP_SECURE | true | Set to false for STARTTLS on port 587. |
OP_REQUIRE_EMAIL_VERIFICATION | false | Require users to verify their email before logging in. |
Rate limiting
| Variable | Default | Description |
OP_GLOBAL_RATE_LIMIT | 10000 | Maximum requests per minute across all tenants. Adjust based on expected traffic. |
Ingestion
| Variable | Default | Description |
OP_INGESTION_BATCH_SIZE | 1000 | Records processed per ingestion batch. Lower for low-memory environments. |
OP_LARGE_SYNC_CONCURRENCY | 3 | Parallel connectors for large sync jobs. |
Ontology
| Variable | Default | Description |
OP_MIGRATION_TIMEOUT | 3600 | Maximum seconds for a schema migration to complete before it is marked failed. |
OP_ONTOLOGY_POLL_INTERVAL | 15 | Seconds between ontology schema cache refresh. |
Execution / Plugin sandbox
| Variable | Default | Description |
OP_SANDBOX_POOL_SIZE | 5 | Number of pre-warmed plugin sandbox processes. Increase for high plugin throughput. |
OP_CONNECTOR_TIMEOUT_SECONDS | 300 | Maximum execution time for a connector sync before it is killed. |
Security
| Variable | Default | Description |
OP_WEBHOOK_ALLOW_HTTP | false | Set to true to allow webhooks to plain HTTP URLs. Never enable in production. |
OP_SERVICE_TOKEN_SECRET | (required) | Shared secret for inter-service authentication. Generate with openssl rand -hex 32. |
Production Checklist
Work through this list before going live.
TLS
Secrets
Backups
Monitoring
Access control
Scaling Guide
OnePlatform's services are stateless (except PostgreSQL and Redis) and can be scaled horizontally.
Stateless services (scale out freely)
| Service | Notes |
gateway | Scale to handle inbound request volume. Use a load balancer upstream. |
auth | Scale for login throughput. Sessions are stored in PostgreSQL. |
ingestion | Scale for connector sync throughput. Each instance takes jobs from BullMQ. |
ontology | Scale for schema read throughput. Ontology is read-heavy. |
pipeline | Scale for pipeline execution throughput. |
app | Scale for app serve throughput. |
plugin | Scale for plugin execution throughput. |
logging | Scale for log write throughput. |
# Example: scale gateway to 3 replicas
docker compose -f docker/docker-compose.yml up -d --scale gateway=3
Stateful services (do not scale without care)
| Service | Scaling approach |
postgres | Use a managed PostgreSQL service (RDS, Cloud SQL, Neon) or set up streaming replication with a connection pooler. |
redis | Use Redis Cluster or a managed Redis service (ElastiCache, Upstash). |
minio | Use MinIO distributed mode or replace with S3-compatible cloud storage. |
Minimum production topology
[Load Balancer / TLS terminator]
|
┌────────────────┼────────────────┐
| | |
[gateway] [gateway] [gateway]
| | |
┌────────┴────────────────┴────────────────┘
| | | | | | | |
[auth] [ingestion] [ontology] [pipeline] [app] [plugin] [logging] [execution]
| |
└──────────────────────[postgres] [redis] [minio]──────────────┘
Troubleshooting
"Could not connect to OnePlatform" on the setup page
The browser cannot reach the API gateway.
- Check that Docker is running:
docker ps - Check all containers are up:
docker compose -f docker/docker-compose.yml ps - Check the gateway port:
curl http://localhost:3000/healthz - Check gateway logs:
docker compose -f docker/docker-compose.yml logs gateway
Services fail to start
Common causes:
- Missing
.env file: cp .env.example .env and fill in required values. - Port conflict: Another service is using port 3000 (API gateway) or 8080 (UI). Free the conflicting port or adjust docker-compose port mappings.
- Database connection error: Check
POSTGRES_PASSWORD matches in all services. - Insufficient memory: Increase Docker's memory limit to at least 4 GB.
Plugin sandbox errors
- Check
OP_SANDBOX_POOL_SIZE is not 0. - Check container has sufficient CPU (sandbox processes are CPU-bound).
- Review plugin logs:
docker compose -f docker/docker-compose.yml logs plugin.
Sync jobs stuck in "running"
- Check the ingestion service is running:
docker compose -f docker/docker-compose.yml ps ingestion. - Check Redis is reachable (BullMQ queue):
docker compose -f docker/docker-compose.yml logs redis. - Manually cancel stuck jobs via
op connector trigger <id> or the connector detail page.
Migrations failing
- Check
OP_MIGRATION_TIMEOUT is long enough for your data volume. - Review ontology logs:
docker compose -f docker/docker-compose.yml logs ontology. - Migrations can be rolled back from the Ontology > Migrations page.
# 1. Pull the latest images
docker compose -f docker/docker-compose.yml pull
# 2. Restart services with zero-downtime rolling update (requires a load balancer)
docker compose -f docker/docker-compose.yml up -d --no-deps --build
# 3. Run database migrations (auto-applied on service startup)
# Watch the logs to confirm migration success
docker compose -f docker/docker-compose.yml logs --follow ontology ingestion
Always take a database snapshot before updating.