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:
- Node.js process running
hz serve - RethinkDB cluster (can be hosted or self-managed)
- 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
- Add RethinkDB Cloud (Compose) or run RethinkDB on AWS
- Set config vars:
heroku config:set HZ_CONNECT=aws-host:28015 heroku config:set HZ_PROJECT_NAME=myapp - Create
Procfile:web: hz serve --bind 0.0.0.0 --port $PORT
AWS/GCP/Azure Deployment
- RethinkDB: Deploy on EC2/Compute Engine/VMs or use managed services
- Horizon Server: Deploy as Node.js application
- 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:
- Check schema permissions in
.hz/schema.toml - Verify user is in correct group (default, admin, etc.)
- 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