Skip to main content

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:

DatabasePurpose
strata_productionMain application data
strata_production_queueInternal asynchronous processing metadata
strata_production_cacheInternal application cache metadata
strata_production_cableReal-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, or microsoft) so all nodes share the same file storage.
  • Option B: Use a shared filesystem (NFS, EFS) mounted as the strata_storage volume.

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.