first commit
This commit is contained in:
77
examples/configs/withnginxreverseproxy/README.md
Normal file
77
examples/configs/withnginxreverseproxy/README.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# Bifrost behind NGINX (Docker Compose)
|
||||
|
||||
This example runs 3 Bifrost containers behind an NGINX reverse proxy.
|
||||
|
||||
## Files
|
||||
|
||||
- `docker-compose.yml` - Starts NGINX and 3 Bifrost nodes
|
||||
- `nginx.conf` - Reverse proxy and load balancing config
|
||||
- `config.json` - Shared Bifrost config for all nodes
|
||||
- `.env.example` - Required environment variables
|
||||
- `helm-values.yaml` - Helm values for Kubernetes + NGINX Ingress
|
||||
- `k8s-ingress.yaml` - Standalone ingress manifest (non-Helm or override)
|
||||
|
||||
## Run
|
||||
|
||||
```bash
|
||||
cd examples/configs/withnginxreverseproxy
|
||||
cp .env.example .env
|
||||
# Edit .env and set real values
|
||||
|
||||
docker compose config
|
||||
docker compose up -d
|
||||
docker compose ps
|
||||
```
|
||||
|
||||
NGINX exposes Bifrost on `http://localhost:8080`.
|
||||
|
||||
## Verify
|
||||
|
||||
```bash
|
||||
# Health through NGINX
|
||||
curl -i http://localhost:8080/health
|
||||
|
||||
# Chat completion through NGINX
|
||||
curl -sS http://localhost:8080/v1/chat/completions \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"model": "gpt-4o-mini",
|
||||
"messages": [{"role": "user", "content": "Say hello"}]
|
||||
}'
|
||||
```
|
||||
|
||||
Streaming check:
|
||||
|
||||
```bash
|
||||
curl -N http://localhost:8080/v1/chat/completions \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"model": "gpt-4o-mini",
|
||||
"stream": true,
|
||||
"messages": [{"role": "user", "content": "stream test"}]
|
||||
}'
|
||||
```
|
||||
|
||||
## Stop
|
||||
|
||||
```bash
|
||||
docker compose down
|
||||
```
|
||||
|
||||
## Kubernetes / Helm
|
||||
|
||||
```bash
|
||||
# Render manifests and verify ingress is present
|
||||
helm template bifrost ./helm-charts/bifrost \
|
||||
-f examples/configs/withnginxreverseproxy/helm-values.yaml
|
||||
|
||||
# Install (or upgrade) with this example
|
||||
helm upgrade --install bifrost ./helm-charts/bifrost \
|
||||
-f examples/configs/withnginxreverseproxy/helm-values.yaml
|
||||
```
|
||||
|
||||
Validate ingress manifest only:
|
||||
|
||||
```bash
|
||||
kubectl apply --dry-run=client -f examples/configs/withnginxreverseproxy/k8s-ingress.yaml
|
||||
```
|
||||
33
examples/configs/withnginxreverseproxy/config.json
Normal file
33
examples/configs/withnginxreverseproxy/config.json
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"$schema": "https://www.getbifrost.ai/schema",
|
||||
"encryption_key": "env.BIFROST_ENCRYPTION_KEY",
|
||||
"config_store": {
|
||||
"enabled": false
|
||||
},
|
||||
"logs_store": {
|
||||
"enabled": false
|
||||
},
|
||||
"client": {
|
||||
"drop_excess_requests": false,
|
||||
"enable_logging": true,
|
||||
"allowed_origins": [
|
||||
"*"
|
||||
],
|
||||
"max_request_body_size_mb": 100
|
||||
},
|
||||
"providers": {
|
||||
"openai": {
|
||||
"keys": [
|
||||
{
|
||||
"name": "openai-primary",
|
||||
"value": "env.OPENAI_API_KEY",
|
||||
"models": [
|
||||
"gpt-4o-mini",
|
||||
"gpt-4o"
|
||||
],
|
||||
"weight": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
54
examples/configs/withnginxreverseproxy/docker-compose.yml
Normal file
54
examples/configs/withnginxreverseproxy/docker-compose.yml
Normal file
@@ -0,0 +1,54 @@
|
||||
services:
|
||||
nginx:
|
||||
image: nginx:alpine
|
||||
container_name: bifrost-nginx
|
||||
ports:
|
||||
- "8080:80"
|
||||
volumes:
|
||||
- ./nginx.conf:/etc/nginx/nginx.conf:ro
|
||||
depends_on:
|
||||
- bifrost-1
|
||||
- bifrost-2
|
||||
- bifrost-3
|
||||
restart: unless-stopped
|
||||
|
||||
bifrost-1:
|
||||
image: maximhq/bifrost:latest
|
||||
container_name: bifrost-1
|
||||
env_file:
|
||||
- .env
|
||||
volumes:
|
||||
- ./config.json:/app/config.json:ro
|
||||
- bifrost_data_1:/app/data
|
||||
expose:
|
||||
- "8080"
|
||||
restart: unless-stopped
|
||||
|
||||
bifrost-2:
|
||||
image: maximhq/bifrost:latest
|
||||
container_name: bifrost-2
|
||||
env_file:
|
||||
- .env
|
||||
volumes:
|
||||
- ./config.json:/app/config.json:ro
|
||||
- bifrost_data_2:/app/data
|
||||
expose:
|
||||
- "8080"
|
||||
restart: unless-stopped
|
||||
|
||||
bifrost-3:
|
||||
image: maximhq/bifrost:latest
|
||||
container_name: bifrost-3
|
||||
env_file:
|
||||
- .env
|
||||
volumes:
|
||||
- ./config.json:/app/config.json:ro
|
||||
- bifrost_data_3:/app/data
|
||||
expose:
|
||||
- "8080"
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
bifrost_data_1:
|
||||
bifrost_data_2:
|
||||
bifrost_data_3:
|
||||
43
examples/configs/withnginxreverseproxy/helm-values.yaml
Normal file
43
examples/configs/withnginxreverseproxy/helm-values.yaml
Normal file
@@ -0,0 +1,43 @@
|
||||
image:
|
||||
tag: "v1.4.18"
|
||||
|
||||
replicaCount: 3
|
||||
|
||||
ingress:
|
||||
enabled: true
|
||||
className: nginx
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/proxy-body-size: "100m"
|
||||
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
|
||||
nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
|
||||
nginx.ingress.kubernetes.io/proxy-buffering: "off"
|
||||
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
||||
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
|
||||
hosts:
|
||||
- host: bifrost.example.com
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
tls:
|
||||
- secretName: bifrost-tls
|
||||
hosts:
|
||||
- bifrost.example.com
|
||||
|
||||
bifrost:
|
||||
encryptionKey: "env.BIFROST_ENCRYPTION_KEY"
|
||||
client:
|
||||
enableLogging: true
|
||||
maxRequestBodySizeMb: 100
|
||||
providers:
|
||||
openai:
|
||||
keys:
|
||||
- name: "openai-primary"
|
||||
value: "env.OPENAI_API_KEY"
|
||||
models: ["gpt-4o-mini", "gpt-4o"]
|
||||
weight: 1
|
||||
|
||||
env:
|
||||
- name: OPENAI_API_KEY
|
||||
value: "replace-with-real-key"
|
||||
- name: BIFROST_ENCRYPTION_KEY
|
||||
value: "replace-with-32-byte-random-string"
|
||||
27
examples/configs/withnginxreverseproxy/k8s-ingress.yaml
Normal file
27
examples/configs/withnginxreverseproxy/k8s-ingress.yaml
Normal file
@@ -0,0 +1,27 @@
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: bifrost
|
||||
annotations:
|
||||
cert-manager.io/cluster-issuer: letsencrypt-prod
|
||||
nginx.ingress.kubernetes.io/proxy-body-size: "100m"
|
||||
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
|
||||
nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
|
||||
nginx.ingress.kubernetes.io/proxy-buffering: "off"
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: bifrost.example.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: bifrost
|
||||
port:
|
||||
number: 8080
|
||||
tls:
|
||||
- secretName: bifrost-tls
|
||||
hosts:
|
||||
- bifrost.example.com
|
||||
35
examples/configs/withnginxreverseproxy/nginx.conf
Normal file
35
examples/configs/withnginxreverseproxy/nginx.conf
Normal file
@@ -0,0 +1,35 @@
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
upstream bifrost_backend {
|
||||
least_conn;
|
||||
server bifrost-1:8080;
|
||||
server bifrost-2:8080;
|
||||
server bifrost-3:8080;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
|
||||
location / {
|
||||
proxy_pass http://bifrost_backend;
|
||||
|
||||
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;
|
||||
|
||||
proxy_http_version 1.1;
|
||||
proxy_buffering off;
|
||||
proxy_request_buffering off;
|
||||
proxy_read_timeout 300s;
|
||||
proxy_send_timeout 300s;
|
||||
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user