|
# ============================================================================= |
|
# 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: |