Skip to content

Instantly share code, notes, and snippets.

@wilcorrea
Created May 7, 2026 14:45
Show Gist options
  • Select an option

  • Save wilcorrea/ff33ac1fb916adf3b54c3e45f8882c21 to your computer and use it in GitHub Desktop.

Select an option

Save wilcorrea/ff33ac1fb916adf3b54c3e45f8882c21 to your computer and use it in GitHub Desktop.
Onyx (AI Knowledge Base) — VPS Deploy for ai.devi.tools
# =============================================================================
# Onyx VPS Environment Configuration
# =============================================================================
# IMPORTANT: Change the passwords below before deploying!
# --- Onyx Image ---
IMAGE_TAG=latest
# --- Domain ---
DOMAIN=ai.devi.tools
# --- Auth ---
AUTH_TYPE=basic
REQUIRE_EMAIL_VERIFICATION=false
# Generate with: openssl rand -hex 32
USER_AUTH_SECRET=CHANGE_ME_RUN_openssl_rand_hex_32
# --- PostgreSQL ---
POSTGRES_USER=postgres
POSTGRES_PASSWORD=CHANGE_ME_STRONG_PASSWORD
# --- MinIO ---
MINIO_ROOT_USER=minioadmin
MINIO_ROOT_PASSWORD=CHANGE_ME_STRONG_PASSWORD
S3_FILE_STORE_BUCKET_NAME=onyx-file-store-bucket
FILE_STORE_BACKEND=s3
# --- Slack Bot (configure after first login) ---
# ONYX_BOT_REACT_EMOJI=hourglass_flowing_sand
# --- Log Level ---
LOG_LEVEL=info

🚀 Onyx Deploy — ai.devi.tools

VPS Contabo 24GB RAM — Full Docker setup com SSL via Let's Encrypt

Pré-requisitos

  • Ubuntu (22.04 ou 24.04) na VPS
  • DNS apontando ai.devi.tools → IP da VPS
  • Portas 80 e 443 abertas no firewall

1. Setup Inicial

# Conectar na VPS
ssh root@<IP_DA_VPS>

# Atualizar e instalar dependências
apt update && apt upgrade -y
apt install -y curl git jq

# Instalar Docker + Compose
curl -fsSL https://get.docker.com | sh
systemctl enable docker && systemctl start docker

# Verificar
docker --version
docker compose version

2. Clonar e Configurar

# Criar diretório
mkdir -p /opt/onyx && cd /opt/onyx

# Baixar os arquivos de deploy
# (ou clone seu repo se preferir)
curl -fsSL https://gist.githubusercontent.com/<USER>/<GIST_ID>/raw/docker-compose.yml -o docker-compose.yml
curl -fsSL https://gist.githubusercontent.com/<USER>/<GIST_ID>/raw/.env -o .env
curl -fsSL https://gist.githubusercontent.com/<USER>/<GIST_ID>/raw/nginx.conf -o nginx.conf

# Editar .env com suas credenciais
nano .env

3. Configurar DNS

No seu provedor DNS, adicione:

A   ai.devi.tools   → <IP_DA_VPS>

4. Iniciar

cd /opt/onyx
docker compose up -d

# Acompanhar logs
docker compose logs -f --tail 50

5. Obter SSL (Let's Encrypt)

# O Caddy (reverse proxy) cuida do SSL automaticamente!
# Basta acessar https://ai.devi.tools

6. Acessar

7. Configurar LLM

Na UI: Admin → LLM Providers → Add:

  • Provider: Anthropic (ou OpenAI, Groq, etc.)
  • API Key: sua chave
  • Model: claude-sonnet-4-20250514

8. Configurar Slack Bot

  1. Criar app em api.slack.com/apps
  2. Scopes: app_mentions:read, channels:history, channels:read, chat:write, groups:history, groups:read, im:history, im:read, im:write, mpim:history, reactions:write, users:read, users:read.email
  3. Ativar Socket Mode (gerar App Token com connections:write)
  4. Event Subscriptions: app_mention, message.im, message.channels, message.groups
  5. Instalar no workspace
  6. Na UI Onyx: Admin → Slack Bot → Add Bot → colar tokens

Manutenção

# Atualizar Onyx
cd /opt/onyx
docker compose pull
docker compose up -d

# Backup do banco
docker exec onyx-relational_db-1 pg_dump -U postgres postgres > backup_$(date +%Y%m%d).sql

# Ver logs
docker compose logs -f api_server
docker compose logs -f background
# Caddyfile — Automatic HTTPS reverse proxy for Onyx
# Caddy handles SSL certificate issuance/renewal via Let's Encrypt automatically.
ai.devi.tools {
# API routes
handle /api/* {
reverse_proxy api_server:8080
}
# WebSocket support for chat streaming
handle /api/chat/send-message-streaming* {
reverse_proxy api_server:8080 {
flush_interval -1
}
}
# Health check
handle /health {
reverse_proxy api_server:8080
}
# Frontend (Next.js)
handle {
reverse_proxy web_server:3000
}
# Upload size limit (5GB for document uploads)
request_body {
max_size 5GB
}
# Timeouts for long LLM responses
reverse_proxy {
transport http {
response_header_timeout 300s
dial_timeout 300s
}
}
}
# =============================================================================
# ONYX — Full Docker Deploy for ai.devi.tools
# =============================================================================
# VPS: Contabo 24GB RAM
# Reverse Proxy: Caddy (automatic HTTPS)
# =============================================================================
name: onyx
services:
# =========================================================================
# REVERSE PROXY (Caddy — automatic SSL)
# =========================================================================
caddy:
image: caddy:2-alpine
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data
- caddy_config:/config
depends_on:
- api_server
- web_server
# =========================================================================
# BACKEND
# =========================================================================
api_server:
image: onyxdotapp/onyx-backend:${IMAGE_TAG:-latest}
command: >
/bin/sh -c "alembic upgrade head &&
echo 'Starting Onyx Api Server' &&
uvicorn onyx.main:app --host 0.0.0.0 --port 8080"
env_file:
- .env
restart: unless-stopped
depends_on:
relational_db:
condition: service_healthy
index:
condition: service_started
cache:
condition: service_started
inference_model_server:
condition: service_healthy
environment:
- AUTH_TYPE=${AUTH_TYPE:-basic}
- POSTGRES_HOST=relational_db
- VESPA_HOST=index
- VESPA_PORT=8081
- REDIS_HOST=cache
- MODEL_SERVER_HOST=inference_model_server
- MODEL_SERVER_PORT=9000
- INDEXING_MODEL_SERVER_HOST=indexing_model_server
- INDEXING_MODEL_SERVER_PORT=9000
- FILE_STORE_BACKEND=${FILE_STORE_BACKEND:-s3}
- S3_ENDPOINT_URL=http://minio:9000
- S3_FILE_STORE_BUCKET_NAME=${S3_FILE_STORE_BUCKET_NAME:-onyx-file-store-bucket}
- S3_AWS_ACCESS_KEY_ID=${MINIO_ROOT_USER:-minioadmin}
- S3_AWS_SECRET_ACCESS_KEY=${MINIO_ROOT_PASSWORD:-minioadmin}
- OPENSEARCH_FOR_ONYX_ENABLED=false
- ENABLE_OPENSEARCH_INDEXING_FOR_ONYX=false
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8080/health')"]
interval: 30s
timeout: 20s
retries: 3
start_period: 30s
logging:
driver: json-file
options:
max-size: "50m"
max-file: "6"
background:
image: onyxdotapp/onyx-backend:${IMAGE_TAG:-latest}
command: >
/bin/sh -c "/app/scripts/supervisord_entrypoint.sh"
env_file:
- .env
restart: unless-stopped
depends_on:
relational_db:
condition: service_healthy
index:
condition: service_started
cache:
condition: service_started
inference_model_server:
condition: service_healthy
indexing_model_server:
condition: service_healthy
environment:
- AUTH_TYPE=${AUTH_TYPE:-basic}
- POSTGRES_HOST=relational_db
- VESPA_HOST=index
- VESPA_PORT=8081
- REDIS_HOST=cache
- MODEL_SERVER_HOST=inference_model_server
- MODEL_SERVER_PORT=9000
- INDEXING_MODEL_SERVER_HOST=indexing_model_server
- INDEXING_MODEL_SERVER_PORT=9000
- FILE_STORE_BACKEND=${FILE_STORE_BACKEND:-s3}
- S3_ENDPOINT_URL=http://minio:9000
- S3_FILE_STORE_BUCKET_NAME=${S3_FILE_STORE_BUCKET_NAME:-onyx-file-store-bucket}
- S3_AWS_ACCESS_KEY_ID=${MINIO_ROOT_USER:-minioadmin}
- S3_AWS_SECRET_ACCESS_KEY=${MINIO_ROOT_PASSWORD:-minioadmin}
- OPENSEARCH_FOR_ONYX_ENABLED=false
- ENABLE_OPENSEARCH_INDEXING_FOR_ONYX=false
- API_SERVER_PROTOCOL=http
- API_SERVER_HOST=api_server
- ONYX_BOT_REACT_EMOJI=${ONYX_BOT_REACT_EMOJI:-hourglass_flowing_sand}
volumes:
- background_logs:/var/log/onyx
- file-system:/app/file-system
logging:
driver: json-file
options:
max-size: "50m"
max-file: "6"
# =========================================================================
# FRONTEND
# =========================================================================
web_server:
image: onyxdotapp/onyx-web-server:${IMAGE_TAG:-latest}
restart: unless-stopped
depends_on:
- api_server
environment:
- INTERNAL_URL=http://api_server:8080
# =========================================================================
# MODEL SERVERS
# =========================================================================
inference_model_server:
image: onyxdotapp/onyx-model-server:${IMAGE_TAG:-latest}
command: >
/bin/sh -c "exec uvicorn model_server.main:app --host 0.0.0.0 --port 9000"
restart: unless-stopped
volumes:
- model_cache_huggingface:/app/.cache/huggingface/
logging:
driver: json-file
options:
max-size: "50m"
max-file: "6"
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:9000/api/health')"]
interval: 20s
timeout: 5s
retries: 3
indexing_model_server:
image: onyxdotapp/onyx-model-server:${IMAGE_TAG:-latest}
command: >
/bin/sh -c "exec uvicorn model_server.main:app --host 0.0.0.0 --port 9000"
restart: unless-stopped
environment:
- INDEXING_ONLY=True
volumes:
- indexing_huggingface_model_cache:/app/.cache/huggingface/
logging:
driver: json-file
options:
max-size: "50m"
max-file: "6"
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:9000/api/health')"]
interval: 20s
timeout: 5s
retries: 3
# =========================================================================
# INFRASTRUCTURE
# =========================================================================
relational_db:
image: postgres:15.2-alpine
shm_size: 1g
command: -c 'max_connections=250'
restart: unless-stopped
environment:
- POSTGRES_USER=${POSTGRES_USER:-postgres}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-password}
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-postgres}"]
interval: 10s
timeout: 5s
retries: 5
volumes:
- db_volume:/var/lib/postgresql/data
index:
image: vespaengine/vespa:8.609.39
restart: unless-stopped
environment:
- VESPA_SKIP_UPGRADE_CHECK=true
volumes:
- vespa_volume:/opt/vespa/var
logging:
driver: json-file
options:
max-size: "50m"
max-file: "6"
cache:
image: redis:7.4-alpine
restart: unless-stopped
command: redis-server --save "" --appendonly no
tmpfs:
- /data
minio:
image: minio/minio:RELEASE.2025-07-23T15-54-02Z-cpuv1
restart: unless-stopped
environment:
MINIO_ROOT_USER: ${MINIO_ROOT_USER:-minioadmin}
MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:-minioadmin}
MINIO_DEFAULT_BUCKETS: ${S3_FILE_STORE_BUCKET_NAME:-onyx-file-store-bucket}
volumes:
- minio_data:/data
command: server /data --console-address ":9001"
healthcheck:
test: ["CMD", "mc", "ready", "local"]
interval: 30s
timeout: 20s
retries: 3
volumes:
caddy_data:
caddy_config:
db_volume:
vespa_volume:
minio_data:
model_cache_huggingface:
indexing_huggingface_model_cache:
background_logs:
file-system:
#!/bin/bash
# =============================================================================
# Onyx VPS Setup Script — ai.devi.tools
# =============================================================================
# Run as root on a fresh Ubuntu 22.04/24.04 VPS (Contabo 24GB)
#
# Usage: curl -fsSL <gist_raw_url>/setup.sh | bash
# =============================================================================
set -euo pipefail
DOMAIN="ai.devi.tools"
INSTALL_DIR="/opt/onyx"
echo "=========================================="
echo " 🚀 Onyx Setup — $DOMAIN"
echo "=========================================="
# --- 1. System Update ---
echo "[1/6] Updating system..."
apt update && apt upgrade -y
apt install -y curl git jq ufw
# --- 2. Firewall ---
echo "[2/6] Configuring firewall..."
ufw allow OpenSSH
ufw allow 80/tcp
ufw allow 443/tcp
ufw --force enable
# --- 3. Docker ---
echo "[3/6] Installing Docker..."
if ! command -v docker &>/dev/null; then
curl -fsSL https://get.docker.com | sh
systemctl enable docker && systemctl start docker
else
echo " Docker already installed"
fi
# --- 4. Create Deploy Directory ---
echo "[4/6] Setting up $INSTALL_DIR..."
mkdir -p "$INSTALL_DIR"
cd "$INSTALL_DIR"
# --- 5. Download Files ---
echo "[5/6] Creating configuration files..."
# Generate secrets
USER_AUTH_SECRET=$(openssl rand -hex 32)
POSTGRES_PASSWORD=$(openssl rand -hex 16)
MINIO_PASSWORD=$(openssl rand -hex 16)
# Create .env with generated secrets
cat > .env << EOF
# Generated on $(date)
IMAGE_TAG=latest
DOMAIN=$DOMAIN
AUTH_TYPE=basic
REQUIRE_EMAIL_VERIFICATION=false
USER_AUTH_SECRET=$USER_AUTH_SECRET
POSTGRES_USER=postgres
POSTGRES_PASSWORD=$POSTGRES_PASSWORD
MINIO_ROOT_USER=minioadmin
MINIO_ROOT_PASSWORD=$MINIO_PASSWORD
S3_FILE_STORE_BUCKET_NAME=onyx-file-store-bucket
FILE_STORE_BACKEND=s3
ONYX_BOT_REACT_EMOJI=hourglass_flowing_sand
LOG_LEVEL=info
EOF
echo " .env created with auto-generated secrets"
echo " PostgreSQL password: $POSTGRES_PASSWORD"
echo " MinIO password: $MINIO_PASSWORD"
# Download docker-compose.yml and Caddyfile
# (In production, these would come from the gist URL)
echo " NOTE: Copy docker-compose.yml and Caddyfile to $INSTALL_DIR"
# --- 6. Start ---
echo "[6/6] Starting services..."
echo ""
echo "=========================================="
echo " ✅ Setup complete!"
echo "=========================================="
echo ""
echo "Next steps:"
echo " 1. Ensure DNS for $DOMAIN points to this server's IP"
echo " 2. Copy docker-compose.yml and Caddyfile to $INSTALL_DIR"
echo " 3. Run: cd $INSTALL_DIR && docker compose up -d"
echo " 4. Wait ~2min for all services to start"
echo " 5. Access: https://$DOMAIN"
echo " 6. First login creates the admin account"
echo ""
echo "Credentials saved in: $INSTALL_DIR/.env"
echo ""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment