Manual Host Deployment (VM / On-Prem)
This guide is for organizations that manage their own infrastructure and require direct control over runtime, configuration, and rollout workflows.
Supported targets include:
- Linux VM or instance (AWS EC2, Azure VM, Google Compute Engine, etc.)
- On-premises Linux server
- Any Docker-compatible host managed by your operations team
0. Generate a .env File
Generate .env with auto-generated Strata secrets:
curl -fsSL https://strata.do/self-hosting/env.sh | bash -s -- ./.env
1. Authenticate with the Container Registry
Strata is distributed as a private Docker image. Authenticate to the registry where your organization stores the approved Strata image:
echo YOUR_REGISTRY_TOKEN | docker login registry.gitlab.com -u YOUR_REGISTRY_USERNAME --password-stdin
2. Pull the Image
Use an explicit release tag for production:
docker pull registry.gitlab.com/stratado/server:1.0.0
3. Prepare PostgreSQL
Strata uses four PostgreSQL databases:
| Database | Purpose |
|---|---|
strata_production | Main application data |
strata_production_queue | Internal asynchronous processing metadata |
strata_production_cache | Internal application cache metadata |
strata_production_cable | Real-time connection metadata |
Option A: Automatic Creation
If your PostgreSQL user has the CREATEDB privilege, Strata creates all four databases on first start:
CREATE USER strata WITH PASSWORD 'your_secure_password';
ALTER USER strata CREATEDB;
Option B: Manual Creation
For locked-down environments where the database user cannot create databases:
CREATE USER strata WITH PASSWORD 'your_secure_password';
CREATE DATABASE strata_production OWNER strata;
CREATE DATABASE strata_production_queue OWNER strata;
CREATE DATABASE strata_production_cache OWNER strata;
CREATE DATABASE strata_production_cable OWNER strata;
4. Create Docker Compose File
Create a directory for Strata (e.g., /opt/strata) and add docker-compose.yml:
# docker-compose.yml
services:
web:
image: registry.gitlab.com/stratado/server:${STRATA_VERSION:-latest}
ports:
- "${PORT:-3000}:${STRATA_CONTAINER_PORT:-80}"
env_file: .env
environment:
RAILS_ENV: production
STRATA_RUN_DB_PREPARE: "true"
volumes:
- strata_storage:/rails/storage
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "curl -f http://127.0.0.1:$${STRATA_CONTAINER_PORT:-80}/up || exit 1"]
interval: 30s
timeout: 5s
retries: 3
start_period: 120s
job:
image: registry.gitlab.com/stratado/server:${STRATA_VERSION:-latest}
env_file: .env
environment:
RAILS_ENV: production
STRATA_RUN_DB_PREPARE: "false"
JOB_CONCURRENCY: "${JOB_CONCURRENCY:-4}"
command: ["./bin/jobs"]
volumes:
- strata_storage:/rails/storage
restart: unless-stopped
depends_on:
web:
condition: service_healthy
volumes:
strata_storage:
The web service handles HTTP and database setup. The job service processes background jobs using the same image and shared storage volume.
5. Configure Environment Variables
Set the following variables (e.g. in a .env file in the same directory, or in your shell/system env). At minimum, you need:
# Required
LICENSE_KEY=your_license_key_jwt_token
DB_HOST=your-postgres-host
DB_PORT=5432
DB_USERNAME=strata
DB_PASSWORD=your_secure_password
STRATA_SECRET_KEY_BASE= # Generate with: openssl rand -hex 64
STRATA_ENCRYPTION_PRIMARY_KEY= # Generate with: openssl rand -hex 16
STRATA_ENCRYPTION_DETERMINISTIC_KEY= # Generate with: openssl rand -hex 16
STRATA_ENCRYPTION_KEY_DERIVATION_SALT= # Generate with: openssl rand -hex 16
# Common in production
APP_HOST=strata.yourcompany.com
APP_PROTOCOL=https
STRATA_LOG_LEVEL=info
WEB_CONCURRENCY=2
WEB_THREADS=5
JOB_CONCURRENCY=4
JOB_THREADS=3
See Environment Variables for the complete reference.
6. Start Strata
docker compose up -d
7. Verify
Watch the startup logs:
docker compose logs -f web job
Expected output on first run:
[Strata] Waiting for PostgreSQL at your-db-host:5432...
[Strata] PostgreSQL is ready.
[Strata] Preparing databases...
[Strata] Databases ready.
Check the health endpoint:
curl http://<your-host-or-ip>:<PORT>/up
# Expect HTTP 200
8. Create Your Admin Account
Open the application URL and complete the Setup Wizard to create the first admin account. The setup page is shown only until the first user is created.
SSL / Reverse Proxy
By default, Strata listens on container port 80 (override with STRATA_CONTAINER_PORT if needed). For production deployments, place it behind a reverse proxy that terminates SSL. Set ASSUME_SSL=true and FORCE_SSL=true so Strata correctly handles forwarded HTTPS requests.
See SSL & Reverse Proxy for full setup instructions, including Nginx, Caddy, and AWS ALB examples.
Multi-Instance Deployment
For high availability or load balancing across multiple nodes:
STRATA_SECRET_KEY_BASE
All nodes must share the same STRATA_SECRET_KEY_BASE. This key encrypts sessions, cookies, and signed tokens. If nodes use different keys, users will be logged out when their request hits another node.
Generate a shared key:
openssl rand -hex 64
Set the same STRATA_SECRET_KEY_BASE environment variable on every node — via .env, your orchestrator's secrets management, or however you configure environment variables:
STRATA_SECRET_KEY_BASE=your_shared_secret_key_base_value
Strata Encryption Keys
All nodes must also share the same Strata encryption keys. These keys are required for Strata data-at-rest encryption.
Set the same values on every node:
STRATA_ENCRYPTION_PRIMARY_KEY=your_shared_primary_key
STRATA_ENCRYPTION_DETERMINISTIC_KEY=your_shared_deterministic_key
STRATA_ENCRYPTION_KEY_DERIVATION_SALT=your_shared_key_derivation_salt
Shared Storage
The strata_storage volume stores uploaded files (when using local storage). For multi-node deployments:
- Option A: Use cloud storage (
STORAGE_BACKEND=amazon,google, ormicrosoft) so all nodes share the same file storage. - Option B: Use a shared filesystem (NFS, EFS) mounted as the
strata_storagevolume.
Database
All nodes connect to the same PostgreSQL instance. No special configuration is needed — just ensure all nodes have the same database connection variables.
Upgrade Strategy
Upgrade nodes one at a time (rolling update). Migrations run automatically on startup.