Skip to content

brainz-lab/stack

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Brainz Lab Stack

Self-hosted observability and developer tools platform for Rails applications.

License Docs

Overview

Brainz Lab provides complete observability and developer tools for your Rails apps:

Observability

  • Recall - Structured logging with powerful search
  • Reflex - Error tracking with smart grouping
  • Pulse - APM with distributed tracing
  • Beacon - Uptime monitoring and status pages
  • Sentinel - Infrastructure and host monitoring

Developer Tools

  • Signal - Alerting and notifications hub
  • Flux - Feature flags and experiments
  • Vault - Secrets management
  • Vision - Visual regression testing

Quick Install

curl -fsSL https://raw.githubusercontent.com/brainz-lab/stack/main/install.sh | bash

Requirements

  • Docker & Docker Compose
  • 4GB RAM minimum (8GB recommended for full stack)

Note: The first start takes ~2 minutes while 36 databases are created and schemas are loaded. Subsequent starts are much faster.

Services

Application Services

Service Port Subdomain Description
Recall 3001 recall.localhost Structured logging
Reflex 3002 reflex.localhost Error tracking
Pulse 3003 pulse.localhost APM & tracing
Flux 3004 flux.localhost Feature flags
Signal 3005 signal.localhost Alerting hub
Vault 3006 vault.localhost Secrets management
Beacon 3007 beacon.localhost Uptime monitoring
Vision 3008 vision.localhost Visual testing
Sentinel 3009 sentinel.localhost Infrastructure monitoring

Infrastructure Services

Service Port Description
Traefik 80, 8080 Reverse proxy (dashboard on 8080)
TimescaleDB 5432 PostgreSQL with time-series extensions
Redis 6379 Cache and job queues
MinIO 9000, 9001 S3-compatible object storage

Usage

Start

./scripts/start.sh

Stop

./scripts/stop.sh

View Logs

./scripts/logs.sh          # All services
./scripts/logs.sh recall   # Single service

Reset Data

./scripts/reset.sh

Accessing Services

Via Subdomains (Recommended)

Traefik routes requests based on subdomain. On macOS, .localhost domains resolve automatically. On Linux, add to /etc/hosts:

127.0.0.1 recall.localhost reflex.localhost pulse.localhost
127.0.0.1 flux.localhost signal.localhost vault.localhost
127.0.0.1 beacon.localhost vision.localhost sentinel.localhost

Then access: http://recall.localhost, http://reflex.localhost, etc.

Via Direct Ports

Access services directly: http://localhost:3001 (Recall), http://localhost:3002 (Reflex), etc.

Traefik Dashboard

View routing and health: http://localhost:8080

Integrate with Your App

1. Add the SDK

# Gemfile
gem 'brainzlab'

2. Configure

# config/initializers/brainzlab.rb
BrainzLab.configure do |config|
  config.secret_key = ENV['BRAINZLAB_SECRET_KEY']

  # Self-hosted URLs (via Traefik subdomains)
  config.recall_url = ENV['RECALL_URL']   # http://recall.localhost
  config.reflex_url = ENV['REFLEX_URL']   # http://reflex.localhost
  config.pulse_url  = ENV['PULSE_URL']    # http://pulse.localhost
  config.signal_url = ENV['SIGNAL_URL']   # http://signal.localhost
  config.flux_url   = ENV['FLUX_URL']     # http://flux.localhost
  config.vault_url  = ENV['VAULT_URL']    # http://vault.localhost
end

Tip: Run ./scripts/setup.sh to generate keys and optionally export URLs to your shell profile.

3. Use

# Logging
BrainzLab::Recall.info("User signed up", user_id: user.id)

# Error tracking (automatic in Rails, or manual)
BrainzLab::Reflex.capture(exception, user: current_user)

# APM (automatic instrumentation)
# Just install the gem and it works!

# Custom metrics
BrainzLab::Pulse.increment("orders.created")
BrainzLab::Pulse.gauge("queue.size", Sidekiq::Queue.new.size)

# Feature flags
if BrainzLab::Flux.enabled?(:new_checkout, user: current_user)
  # New checkout flow
end

# Secrets
api_key = BrainzLab::Vault.get("stripe/api_key")

# Alerts
BrainzLab::Signal.trigger("high_error_rate", severity: :critical)

Configuration

Copy .env.example to .env and customize:

cp .env.example .env

Key Settings

Variable Description Default
POSTGRES_USER Database user brainzlab
POSTGRES_PASSWORD Database password brainzlab
RECALL_PORT Recall port 3001
REFLEX_PORT Reflex port 3002
PULSE_PORT Pulse port 3003
FLUX_PORT Flux port 3004
SIGNAL_PORT Signal port 3005
VAULT_PORT Vault port 3006
BEACON_PORT Beacon port 3007
VISION_PORT Vision port 3008
SENTINEL_PORT Sentinel port 3009

Subdomain Configuration (Production)

Variable Description Default
RECALL_HOST Recall subdomain recall.localhost
REFLEX_HOST Reflex subdomain reflex.localhost
PULSE_HOST Pulse subdomain pulse.localhost
FLUX_HOST Flux subdomain flux.localhost
SIGNAL_HOST Signal subdomain signal.localhost
VAULT_HOST Vault subdomain vault.localhost
BEACON_HOST Beacon subdomain beacon.localhost
VISION_HOST Vision subdomain vision.localhost
SENTINEL_HOST Sentinel subdomain sentinel.localhost

Using GitHub Container Registry

To use GHCR instead of Docker Hub:

RECALL_IMAGE=ghcr.io/brainz-lab/recall:latest
REFLEX_IMAGE=ghcr.io/brainz-lab/reflex:latest
PULSE_IMAGE=ghcr.io/brainz-lab/pulse:latest
# ... etc for other services

Production Deployment

Prerequisites

  1. Use a managed database (RDS, Cloud SQL, etc.) or secure your TimescaleDB
  2. Set up HTTPS - Traefik can handle Let's Encrypt automatically
  3. Configure proper secrets in .env
  4. Set up backups for PostgreSQL and MinIO

DNS Configuration

Set up DNS records pointing to your server:

recall.yourdomain.com    → Your server IP
reflex.yourdomain.com    → Your server IP
pulse.yourdomain.com     → Your server IP
flux.yourdomain.com      → Your server IP
signal.yourdomain.com    → Your server IP
vault.yourdomain.com     → Your server IP
beacon.yourdomain.com    → Your server IP
vision.yourdomain.com    → Your server IP
sentinel.yourdomain.com  → Your server IP

Environment Variables for Production

# Database
POSTGRES_USER=brainzlab
POSTGRES_PASSWORD=<strong-password>

# Master keys - leave EMPTY for pre-built images.
# The images include encrypted credentials that match their built-in keys.
# Setting custom master keys will cause "key must be 16 bytes" errors.
RECALL_MASTER_KEY=
REFLEX_MASTER_KEY=
PULSE_MASTER_KEY=
FLUX_MASTER_KEY=
SIGNAL_MASTER_KEY=
VAULT_MASTER_KEY=
BEACON_MASTER_KEY=
VISION_MASTER_KEY=
SENTINEL_MASTER_KEY=

# Secret keys and SDK key (auto-generated by setup.sh)
BRAINZLAB_SECRET_KEY=<generated-key>

# Subdomains (your domain)
RECALL_HOST=recall.yourdomain.com
REFLEX_HOST=reflex.yourdomain.com
PULSE_HOST=pulse.yourdomain.com
FLUX_HOST=flux.yourdomain.com
SIGNAL_HOST=signal.yourdomain.com
VAULT_HOST=vault.yourdomain.com
BEACON_HOST=beacon.yourdomain.com
VISION_HOST=vision.yourdomain.com
SENTINEL_HOST=sentinel.yourdomain.com

Traefik with HTTPS

Update traefik/traefik.yml for production with Let's Encrypt:

entryPoints:
  web:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: websecure
  websecure:
    address: ":443"

certificatesResolvers:
  letsencrypt:
    acme:
      email: your-email@example.com
      storage: /letsencrypt/acme.json
      httpChallenge:
        entryPoint: web

Architecture

┌─────────────────────────────────────────────────────────────────┐
│                        Your Rails App                            │
│                                                                  │
│  ┌─────────────────────────────────────────────────────────┐    │
│  │                    brainzlab gem                         │    │
│  │  Recall │ Reflex │ Pulse │ Signal │ Flux │ Vault        │    │
│  └─────────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                         Traefik                                  │
│              (Reverse Proxy + Load Balancer)                     │
│         recall.* │ reflex.* │ pulse.* │ ...                     │
└─────────────────────────────────────────────────────────────────┘
                              │
     ┌────────────────────────┼────────────────────────┐
     ▼                        ▼                        ▼
┌─────────┐  ┌─────────┐  ┌─────────┐  ┌─────────┐  ┌─────────┐
│ Recall  │  │ Reflex  │  │  Pulse  │  │  Flux   │  │ Signal  │
│  :3001  │  │  :3002  │  │  :3003  │  │  :3004  │  │  :3005  │
└────┬────┘  └────┬────┘  └────┬────┘  └────┬────┘  └────┬────┘
     │            │            │            │            │
     └────────────┴────────────┴────────────┴────────────┘
                              │
     ┌────────────────────────┼────────────────────────┐
     ▼                        ▼                        ▼
┌─────────┐  ┌─────────┐  ┌─────────┐  ┌─────────┐  ┌─────────┐
│  Vault  │  │ Beacon  │  │ Vision  │  │Sentinel │  │  MinIO  │
│  :3006  │  │  :3007  │  │  :3008  │  │  :3009  │  │  :9000  │
└────┬────┘  └────┬────┘  └────┬────┘  └────┬────┘  └─────────┘
     │            │            │            │
     └────────────┴────────────┴────────────┘
                              │
              ┌───────────────┴───────────────┐
              ▼                               ▼
       ┌─────────────┐                 ┌─────────────┐
       │ TimescaleDB │                 │    Redis    │
       │    :5432    │                 │    :6379    │
       └─────────────┘                 └─────────────┘

Health Checks

All services expose a /up endpoint for health checks:

curl http://localhost:3001/up  # Recall
curl http://localhost:3002/up  # Reflex
# ... etc

Traefik dashboard shows service health: http://localhost:8080

Troubleshooting

Services won't start

Check if ports are in use:

lsof -i :3001  # Check if port is taken

Container name conflicts

If you see "container name already in use" errors:

docker-compose down --remove-orphans
docker-compose up -d

Database connection errors

Ensure TimescaleDB is healthy:

docker-compose ps timescaledb
docker-compose logs timescaledb

Services return 502

On first boot, services need ~2 minutes for database setup. Wait and retry:

# Check a specific service
docker-compose logs vault
# Look for "Listening on http://0.0.0.0:3000" to confirm it's ready

Seed warnings

Some services may show seed warnings like NoMethodError or RecordInvalid during first boot. These are non-fatal - the services still start and function correctly.

Reset everything

If something goes wrong and you want a completely fresh start:

./scripts/reset.sh          # Removes all data and volumes
./scripts/start.sh          # Start fresh

Traefik routing issues

Check Traefik dashboard at http://localhost:8080 for:

  • Service health (green = healthy)
  • Router configuration
  • Active routes

View all logs

docker-compose logs -f

Documentation

Full documentation: docs.brainzlab.ai/self-hosting

Related

License

MIT

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages