Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
169 changes: 169 additions & 0 deletions deployment/docker_compose/docker-compose.railway.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
version: '3.8'

services:
# API Server
api_server:
image: onyxdotapp/onyx-backend:latest
build:
context: ../../backend
dockerfile: Dockerfile
depends_on:
- db
- redis
- vespa
environment:
# Database
DATABASE_URL: "postgresql://${PGUSER}:${PGPASSWORD}@${PGHOST}:${PGPORT}/${PGDATABASE}"

# Redis
REDIS_HOST: ${REDISHOST}
REDIS_PORT: ${REDISPORT}
REDIS_PASSWORD: ${REDISAUTH}

# Vespa
VESPA_HOST: vespa
VESPA_PORT: 8080

# Auth - simplified for preview
AUTH_TYPE: "disabled"
INTERNAL_AUTH_TOKEN: ${INTERNAL_AUTH_TOKEN:-preview-token-123}

# Preview environment settings
ENV_TYPE: "preview"
DOMAIN: ${RAILWAY_PUBLIC_DOMAIN}
WEB_PROTOCOL: "https"

# Model settings - using minimal models
MODEL_SERVER_HOST: model_server
MODEL_SERVER_PORT: 8000
ENABLE_MINI_CHUNK: "true"

# Other settings
POSTGRES_API_SERVER_POOL_SIZE: 5
POSTGRES_API_SERVER_POOL_OVERFLOW: 10
LOG_LEVEL: "info"
ports:
- "8080:8080"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/api/health"]
interval: 30s
timeout: 10s
retries: 3
Comment on lines +47 to +51
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: API healthcheck is using port 8080 which may conflict with Vespa using the same port (line 101). Consider using different ports or configuring a proxy.


# Background Worker
background:
image: onyxdotapp/onyx-backend:latest
depends_on:
- db
- redis
- vespa
environment:
DATABASE_URL: "postgresql://${PGUSER}:${PGPASSWORD}@${PGHOST}:${PGPORT}/${PGDATABASE}"
REDIS_HOST: ${REDISHOST}
REDIS_PORT: ${REDISPORT}
REDIS_PASSWORD: ${REDISAUTH}
VESPA_HOST: vespa
VESPA_PORT: 8080
MODEL_SERVER_HOST: model_server
MODEL_SERVER_PORT: 8000
command: celery -A onyx.background.celery.celery_run worker --beat --loglevel=info

# Web Server (Next.js Frontend)
web_server:
image: onyxdotapp/onyx-web-server:latest
build:
context: ../../web
dockerfile: Dockerfile
args:
NEXT_PUBLIC_API_URL: "https://${RAILWAY_PUBLIC_DOMAIN}/api"
NEXT_PUBLIC_ENVIRONMENT: "preview"
depends_on:
- api_server
environment:
NEXTAUTH_URL: "https://${RAILWAY_PUBLIC_DOMAIN}"
INTERNAL_AUTH_TOKEN: ${INTERNAL_AUTH_TOKEN:-preview-token-123}
NEXT_PUBLIC_API_URL: "https://${RAILWAY_PUBLIC_DOMAIN}/api"
DISABLE_AUTH: "true"
ports:
- "3000:3000"

# Vespa - without privileged mode
vespa:
image: vespaengine/vespa:latest
environment:
VESPA_CONFIGSERVERS: vespa
VESPA_CONFIGSERVER_JVMARGS: "-Xms1g -Xmx1g"
VESPA_NOOP_PRIVILEGED: "true" # Skip privileged operations
volumes:
- vespa_data:/opt/vespa/var
ports:
- "19100:19100"
- "8080:8080"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:19071/state/v1/health"]
interval: 30s
timeout: 10s
retries: 5
start_period: 60s

# Single model server for preview (simplified)
model_server:
image: onyxdotapp/onyx-model-server:latest
build:
context: ../../backend
dockerfile: Dockerfile.model_server
environment:
CUDA_VISIBLE_DEVICES: "" # CPU only for preview
INDEXING_ONLY: "false"
# Using smaller models for preview
INTENT_ENABLED: "false"
QA_ENABLED: "false"
HF_MODEL_SNAPSHOTS_PATH: /model_snapshots
volumes:
- model_data:/model_snapshots
ports:
- "8000:8000"
deploy:
resources:
limits:
memory: 2G

# Database (using Railway's Postgres)
db:
image: postgres:15
environment:
POSTGRES_DB: ${PGDATABASE}
POSTGRES_USER: ${PGUSER}
POSTGRES_PASSWORD: ${PGPASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5432:5432"

# Redis (using Railway's Redis)
redis:
image: redis:7-alpine
command: redis-server --requirepass ${REDISAUTH}
volumes:
- redis_data:/data
ports:
- "6379:6379"

# Nginx Proxy
nginx:
image: nginx:alpine
volumes:
- ../../deployment/docker_compose/nginx-preview.conf:/etc/nginx/nginx.conf:ro
ports:
- "80:80"
depends_on:
- api_server
- web_server
environment:
DOMAIN: ${RAILWAY_PUBLIC_DOMAIN}

volumes:
postgres_data:
redis_data:
vespa_data:
model_data:
54 changes: 54 additions & 0 deletions deployment/docker_compose/nginx-preview.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
events {
worker_connections 1024;
}

http {
upstream web_server {
server web_server:3000 max_fails=3 fail_timeout=30s;
}

upstream api_server {
server api_server:8080 max_fails=3 fail_timeout=30s;
}

server {
listen 80;
server_name _;

# Frontend requests
location / {
proxy_pass http://web_server;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

# WebSocket support for Next.js HMR
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}

# API requests
location /api {
proxy_pass http://api_server;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

# Increase timeouts for API calls
proxy_connect_timeout 300s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;
}

# Health check endpoint
location /health {
proxy_pass http://api_server/api/health;
}

# Increase client body size for file uploads
client_max_body_size 100M;
Comment on lines +51 to +52
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: client_max_body_size is set to 100M while production uses 5G. This significant difference could cause file upload issues in preview environments.

}
}
126 changes: 126 additions & 0 deletions deployment/railway-setup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
# Railway Preview Environment Setup Guide

This guide explains how to set up automated preview environments for Onyx using Railway.

## Overview

This setup will:
- Deploy a full Onyx instance for each PR
- Provide a unique URL for testing
- Automatically trigger Keystone tests
- Clean up when PRs are closed

## Setup Steps

### 1. Railway Account Setup

1. Create a Railway account at https://railway.app
2. Create a new project called "onyx-preview-environments"
3. Install the Railway GitHub App and connect your repository

### 2. Configure Railway Project

In your Railway project dashboard:

1. **Add Required Services:**
- PostgreSQL (click "New" → "Database" → "PostgreSQL")
- Redis (click "New" → "Database" → "Redis")

2. **Set Environment Variables:**
```bash
# Auth Settings
AUTH_TYPE=disabled
INTERNAL_AUTH_TOKEN=preview-token-123

# Model Settings
ENABLE_MINI_CHUNK=true
MODEL_SERVER_HOST=model_server
MODEL_SERVER_PORT=8000

# Other Settings
LOG_LEVEL=info
ENV_TYPE=preview
```

3. **Get Your Project ID:**
- Go to Project Settings
- Copy the Project ID

### 3. GitHub Repository Setup

1. **Add GitHub Secrets:**
```
RAILWAY_TOKEN # Get from Railway Dashboard → Account Settings → Tokens
RAILWAY_PROJECT_ID # Your Railway project ID
KEYSTONE_API_TOKEN # Your Keystone API token
KEYSTONE_TEST_SUITE_ID # ID of the test suite to run
```

2. **Commit the Files:**
```bash
git add railway.json
git add deployment/docker_compose/docker-compose.railway.yml
git add deployment/docker_compose/nginx-preview.conf
git add .github/workflows/preview-deploy.yml
git commit -m "Add Railway preview environment configuration"
```

### 4. Keystone Integration

Update the workflow file with your actual Keystone API endpoint:
- Replace `https://api.keystone.com/v1/test-runs` with your endpoint
- Adjust the request payload format if needed

## How It Works

1. **PR Created/Updated** → GitHub Action triggers
2. **Railway Deployment** → Creates isolated environment
3. **Health Check** → Waits for services to be ready
4. **Keystone Tests** → Triggers automated test suite
5. **PR Comment** → Updates with preview URL and test status
6. **PR Closed** → Automatically deletes preview environment

## Resource Optimization

The preview configuration includes several optimizations:
- Disabled authentication for easier testing
- Single model server (CPU only)
- Reduced resource allocations
- Simplified Vespa configuration

## Troubleshooting

### Vespa Issues
If Vespa fails to start without privileged mode:
1. Check Railway logs for specific errors
2. Try adding: `VESPA_NOOP_PRIVILEGED=true`
3. Consider using external Vespa instance

### Memory Issues
If services run out of memory:
1. Upgrade Railway plan for more resources
2. Reduce model server memory usage
3. Disable unused features

### Build Failures
1. Check Docker build logs in Railway
2. Ensure all required files are committed
3. Verify base images are accessible

## Cost Estimation

Railway pricing (as of setup):
- $5/month base + usage
- ~$0.01/hour per GB RAM
- Preview environments auto-sleep after inactivity

Estimated cost per PR:
- Active testing: ~$0.50-$1.00/day
- Idle: ~$0.10/day

## Next Steps

1. Test with a sample PR
2. Monitor resource usage
3. Adjust configurations as needed
4. Set up cost alerts in Railway
21 changes: 21 additions & 0 deletions railway.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"$schema": "https://railway.app/railway.schema.json",
"build": {
"builder": "DOCKERFILE",
"dockerfilePath": "deployment/docker_compose/docker-compose.railway.yml"
Comment on lines +4 to +5
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: dockerfilePath points to a docker-compose.yml file but builder is set to DOCKERFILE. Should use NIXPACKS or specify the correct Dockerfile path

},
"deploy": {
"startCommand": "docker-compose -f deployment/docker_compose/docker-compose.railway.yml up",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: docker-compose up without -d will run in foreground and may cause Railway to think the deployment failed when output stops. Use docker-compose -f deployment/docker_compose/docker-compose.railway.yml up -d

"healthcheckPath": "/api/health",
"restartPolicyType": "ON_FAILURE",
"restartPolicyMaxRetries": 3
},
"environments": {
"pr": {
"build": {
"builder": "DOCKERFILE",
"dockerfilePath": "deployment/docker_compose/docker-compose.railway.yml"
}
}
}
}
Loading
Loading