← Back to rethinkdb/horizon

How to Deploy & Use rethinkdb/horizon

Horizon Deployment & Usage Guide

Prerequisites

  • Node.js v4.0+ (LTS recommended)
  • RethinkDB v2.0+ (running instance required)
  • npm or yarn package manager
  • Git (for cloning)

Installation

Install Horizon CLI

npm install -g horizon

Verify installation:

hz --version

Install from Source (Development)

git clone https://github.com/rethinkdb/horizon.git
cd horizon
npm install
npm run build  # If build step exists in package.json

Install RethinkDB

macOS:

brew install rethinkdb
rethinkdb  # Start server

Ubuntu/Debian:

source /etc/lsb-release && echo "deb http://download.rethinkdb.com/apt $DISTRIB_CODENAME main" | sudo tee /etc/apt/sources.list.d/rethinkdb.list
wget -qO- https://download.rethinkdb.com/apt/pubkey.gpg | sudo apt-key add -
sudo apt-get update
sudo apt-get install rethinkdb

Docker:

docker run -d -p 28015:28015 -p 8080:8080 --name rethinkdb rethinkdb:latest

Configuration

Project Structure

Horizon expects a project directory containing:

  • .hz/ directory (configuration and schemas)
  • config.toml (optional, for advanced configuration)
  • Static assets (optional, served by hz serve)

RethinkDB Connection

Default connection assumes RethinkDB on localhost:28015. Override with:

hz serve --connect rethinkdb.example.com:28015 --rdb-timeout 30

Configuration File (TOML)

Create .hz/config.toml in your project root:

project_name = "myapp"
bind = ["0.0.0.0"]
port = 8181
rdb_timeout = 20
auto_create_collection = true
auto_create_index = true

Environment Variables

For authentication providers (Facebook, Google, GitHub), set:

export HZ_FACEBOOK_ID="your-app-id"
export HZ_FACEBOOK_SECRET="your-app-secret"
export HZ_GOOGLE_ID="your-client-id"
export HZ_GOOGLE_SECRET="your-client-secret"
export HZ_GITHUB_ID="your-github-id"
export HZ_GITHUB_SECRET="your-github-secret"

Schema Management

Define your collections and permissions in .hz/schema.toml:

[collections.users]
indexes = ["email"]

[groups.default]
[collections.users.permissions.default]
read = true
write = false

Apply schema:

hz schema apply

Save existing schema:

hz schema save > .hz/schema.toml

Build & Run

Development Mode

Start the Horizon server with auto-collection creation:

hz serve --project-name myapp --auto-create-collection --auto-create-index --dev

Options:

  • --project-name, -n: Database name in RethinkDB (default: horizon)
  • --bind, -b: Host to bind (repeatable for multiple)
  • --port, -p: Port to serve on (default: 8181)
  • --connect, -c: RethinkDB host:port
  • --rdb-timeout: Connection timeout in seconds (default: 20)
  • --dev: Development mode (verbose logging, auto-create resources)
  • --start-rethinkdb: Start embedded RethinkDB (if installed)

Production Mode

hz serve --project-name myapp \
  --bind 0.0.0.0 \
  --port 80 \
  --connect production.rethinkdb.internal:28015 \
  --rdb-timeout 30 \
  --secure yes \
  --permissions yes

Database Migration

When upgrading Horizon versions (e.g., to v2.0):

hz migrate --project-name myapp --connect host:port

This handles:

  • Backing up user tables
  • Renaming internal tables (hz_collections, hz_users_auth, hz_groups)
  • Updating metadata version to [2, 0, 0]

Client Library Usage

Install client library:

npm install @horizon/client

Basic usage:

import Horizon from '@horizon/client'

const horizon = new Horizon({ host: 'localhost:8181' })
const chat = horizon('messages')

// Subscribe to realtime updates
chat.order('timestamp', 'descending').limit(10).watch().subscribe(
  items => console.log('Messages:', items)
)

// Insert data
chat.store({ text: 'Hello', timestamp: new Date() })

Deployment

Architecture Overview

Horizon requires:

  1. Node.js process running hz serve
  2. RethinkDB cluster (can be hosted or self-managed)
  3. Reverse proxy (Nginx/Apache) for SSL termination (recommended)

Docker Deployment

FROM node:14-alpine
RUN npm install -g horizon
WORKDIR /app
COPY . .
EXPOSE 8181
CMD ["hz", "serve", "--bind", "0.0.0.0", "--project-name", "myapp"]
# docker-compose.yml
version: '3'
services:
  rethinkdb:
    image: rethinkdb:latest
    volumes:
      - rethinkdb-data:/data
    ports:
      - "28015:28015"
  
  horizon:
    build: .
    ports:
      - "80:8181"
    environment:
      - HZ_CONNECT=rethinkdb:28015
    depends_on:
      - rethinkdb

volumes:
  rethinkdb-data:

Heroku Deployment

  1. Add RethinkDB Cloud (Compose) or run RethinkDB on AWS
  2. Set config vars:
    heroku config:set HZ_CONNECT=aws-host:28015
    heroku config:set HZ_PROJECT_NAME=myapp
    
  3. Create Procfile:
    web: hz serve --bind 0.0.0.0 --port $PORT
    

AWS/GCP/Azure Deployment

  1. RethinkDB: Deploy on EC2/Compute Engine/VMs or use managed services
  2. Horizon Server: Deploy as Node.js application
  3. Systemd service (/etc/systemd/system/horizon.service):
[Unit]
Description=Horizon Server
After=network.target

[Service]
Type=simple
User=horizon
WorkingDirectory=/opt/horizon
ExecStart=/usr/bin/hz serve --project-name myapp --bind 0.0.0.0 --port 8181 --connect localhost:28015
Restart=on-failure
Environment=NODE_ENV=production

[Install]
WantedBy=multi-user.target

SSL/TLS Configuration

Use --secure yes with certificate files:

hz serve --secure yes \
  --key-file /path/to/key.pem \
  --cert-file /path/to/cert.pem

Or terminate SSL at Nginx:

location / {
    proxy_pass http://localhost:8181;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
}

Troubleshooting

RethinkDB Connection Timeout

Error: RethinkDB connection timeout

Solution:

# Increase timeout
hz serve --rdb-timeout 60 --connect your-host:28015

# Verify RethinkDB is running
rethinkdb --bind all  # On RethinkDB host

Schema Version Mismatch

Error: Metadata version mismatch or migration errors

Solution:

# Backup first, then migrate
hz migrate --project-name myapp --connect host:port

Permission Denied Errors

Symptom: Clients cannot read/write collections

Solution:

  1. Check schema permissions in .hz/schema.toml
  2. Verify user is in correct group (default, admin, etc.)
  3. Apply updated schema:
    hz schema apply --project-name myapp
    

Collection Does Not Exist

Error: Collection does not exist

Solution:

# Enable auto-creation (development only)
hz serve --auto-create-collection --auto-create-index

# Or define in schema.toml and apply
hz schema apply

Port Already in Use

# Kill existing process or use different port
hz serve --port 8182

Debugging

Enable verbose logging:

DEBUG=* hz serve --dev

Check RethinkDB tables:

r.db('myapp').tableList().run(conn)
// Should show: users, hz_collections, hz_users_auth, hz_groups