Add Open WebUI
This commit is contained in:
@@ -23,29 +23,35 @@ networks:
|
||||
configs:
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# nginx: reverse proxy for LocalAI (/) and Keycloak (/auth/)
|
||||
# nginx: one server block per subdomain — no path tricks needed
|
||||
# ---------------------------------------------------------------------------
|
||||
nginx_localai_conf:
|
||||
content: |
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name ${DOMAIN:-localhost};
|
||||
|
||||
server_name ${DOMAIN_WEBUI:-localhost};
|
||||
client_max_body_size 512M;
|
||||
|
||||
location /auth/ {
|
||||
proxy_pass http://keycloak:8080/auth/;
|
||||
proxy_http_version 1.1;
|
||||
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 $$http_x_forwarded_proto;
|
||||
proxy_read_timeout 120s;
|
||||
proxy_buffer_size 128k;
|
||||
proxy_buffers 4 256k;
|
||||
proxy_busy_buffers_size 256k;
|
||||
location / {
|
||||
proxy_pass http://openwebui:8080;
|
||||
proxy_http_version 1.1;
|
||||
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 $$http_x_forwarded_proto;
|
||||
proxy_set_header Upgrade $$http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_read_timeout 300s;
|
||||
proxy_send_timeout 300s;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name ${DOMAIN_LOCALAI:-localhost};
|
||||
client_max_body_size 512M;
|
||||
|
||||
location / {
|
||||
proxy_pass http://localai:8080;
|
||||
@@ -61,6 +67,25 @@ configs:
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name ${DOMAIN_AUTH:-localhost};
|
||||
|
||||
location / {
|
||||
proxy_pass http://keycloak:8080;
|
||||
proxy_http_version 1.1;
|
||||
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 $$http_x_forwarded_proto;
|
||||
proxy_read_timeout 120s;
|
||||
proxy_buffer_size 128k;
|
||||
proxy_buffers 4 256k;
|
||||
proxy_busy_buffers_size 256k;
|
||||
}
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Terraform: main.tf — realm, client, roles, and user resources.
|
||||
# seed_users values are declared in terraform.tfvars below, not here.
|
||||
@@ -80,7 +105,7 @@ configs:
|
||||
client_id = "admin-cli"
|
||||
username = var.keycloak_admin_user
|
||||
password = var.keycloak_admin_password
|
||||
url = "http://keycloak:8080/auth"
|
||||
url = "http://keycloak:8080"
|
||||
realm = "master"
|
||||
}
|
||||
|
||||
@@ -93,7 +118,13 @@ configs:
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
variable "localai_base_url" { type = string }
|
||||
variable "localai_base_url" { type = string }
|
||||
variable "openwebui_base_url" { type = string }
|
||||
|
||||
variable "openwebui_client_secret" {
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "seed_users" {
|
||||
type = list(object({
|
||||
@@ -133,12 +164,10 @@ configs:
|
||||
|
||||
valid_redirect_uris = [
|
||||
"$${var.localai_base_url}/api/auth/oidc/callback",
|
||||
"http://localhost:8080/api/auth/oidc/callback",
|
||||
]
|
||||
|
||||
web_origins = [
|
||||
var.localai_base_url,
|
||||
"http://localhost:80",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -182,8 +211,38 @@ configs:
|
||||
]
|
||||
}
|
||||
|
||||
resource "keycloak_openid_client" "openwebui" {
|
||||
realm_id = keycloak_realm.localai.id
|
||||
client_id = "openwebui"
|
||||
name = "Open WebUI"
|
||||
enabled = true
|
||||
access_type = "CONFIDENTIAL"
|
||||
standard_flow_enabled = true
|
||||
direct_access_grants_enabled = false
|
||||
service_accounts_enabled = false
|
||||
client_secret = var.openwebui_client_secret
|
||||
|
||||
valid_redirect_uris = [
|
||||
"$${var.openwebui_base_url}/oauth/oidc/callback",
|
||||
]
|
||||
|
||||
web_origins = [
|
||||
var.openwebui_base_url,
|
||||
]
|
||||
}
|
||||
|
||||
resource "keycloak_openid_user_realm_role_protocol_mapper" "openwebui_realm_roles" {
|
||||
realm_id = keycloak_realm.localai.id
|
||||
client_id = keycloak_openid_client.openwebui.id
|
||||
name = "realm-roles"
|
||||
claim_name = "roles"
|
||||
multivalued = true
|
||||
add_to_id_token = true
|
||||
add_to_access_token = true
|
||||
}
|
||||
|
||||
output "oidc_issuer" {
|
||||
value = "http://keycloak:8080/auth/realms/$${keycloak_realm.localai.realm}"
|
||||
value = "http://keycloak:8080/realms/$${keycloak_realm.localai.realm}"
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -222,7 +281,7 @@ configs:
|
||||
#!/bin/sh
|
||||
set -e
|
||||
echo "Waiting for Keycloak..."
|
||||
until wget -qO- http://keycloak:8080/auth/realms/master > /dev/null 2>&1; do
|
||||
until wget -qO- http://keycloak:8080/realms/master > /dev/null 2>&1; do
|
||||
sleep 5
|
||||
done
|
||||
echo "Keycloak ready."
|
||||
@@ -275,9 +334,8 @@ services:
|
||||
KC_DB_URL: jdbc:postgresql://postgres:5432/keycloak
|
||||
KC_DB_USERNAME: keycloak
|
||||
KC_DB_PASSWORD: ${POSTGRES_PASSWORD:-keycloak_secret}
|
||||
KC_HOSTNAME: https://${DOMAIN:-localhost}/auth
|
||||
KC_HTTP_RELATIVE_PATH: /auth
|
||||
KC_PROXY_HEADERS: xforwarded
|
||||
KC_HOSTNAME: https://${DOMAIN_AUTH:-localhost}
|
||||
KC_PROXY_HEADERS: xforwarded
|
||||
KC_HTTP_ENABLED: "true"
|
||||
volumes:
|
||||
- ./volumes/keycloak/data:/opt/keycloak/data
|
||||
@@ -288,7 +346,7 @@ services:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "exec 3<>/dev/tcp/localhost/8080 && echo -e 'GET /auth/realms/master HTTP/1.0\\r\\nHost: localhost\\r\\n\\r\\n' >&3 && grep -q '200 OK' <(cat <&3)"]
|
||||
test: ["CMD-SHELL", "exec 3<>/dev/tcp/localhost/8080 && echo -e 'GET /realms/master HTTP/1.0\\r\\nHost: localhost\\r\\n\\r\\n' >&3 && grep -q '200 OK' <(cat <&3)"]
|
||||
interval: 15s
|
||||
timeout: 10s
|
||||
retries: 15
|
||||
@@ -303,10 +361,12 @@ services:
|
||||
restart: "no"
|
||||
entrypoint: ["sh", "/entrypoint.sh"]
|
||||
environment:
|
||||
TF_VAR_keycloak_admin_user: ${KEYCLOAK_ADMIN_USER:-admin}
|
||||
TF_VAR_keycloak_admin_password: ${KEYCLOAK_ADMIN_PASSWORD:-admin_secret}
|
||||
TF_VAR_localai_client_secret: ${LOCALAI_OIDC_CLIENT_SECRET:-localai_oidc_secret}
|
||||
TF_VAR_localai_base_url: https://${DOMAIN:-localhost}
|
||||
TF_VAR_keycloak_admin_user: ${KEYCLOAK_ADMIN_USER:-admin}
|
||||
TF_VAR_keycloak_admin_password: ${KEYCLOAK_ADMIN_PASSWORD:-admin_secret}
|
||||
TF_VAR_localai_client_secret: ${LOCALAI_OIDC_CLIENT_SECRET:-localai_oidc_secret}
|
||||
TF_VAR_localai_base_url: https://${DOMAIN_LOCALAI:-localhost}
|
||||
TF_VAR_openwebui_client_secret: ${OPENWEBUI_OIDC_CLIENT_SECRET:-openwebui_oidc_secret}
|
||||
TF_VAR_openwebui_base_url: https://${DOMAIN_WEBUI:-localhost}
|
||||
volumes:
|
||||
- ./volumes/terraform/tf:/tf
|
||||
configs:
|
||||
@@ -341,10 +401,10 @@ services:
|
||||
capabilities: [gpu]
|
||||
environment:
|
||||
LOCALAI_AUTH: "true"
|
||||
LOCALAI_OIDC_ISSUER: https://${DOMAIN:-localhost}/auth/realms/localai
|
||||
LOCALAI_OIDC_ISSUER: https://${DOMAIN_AUTH:-localhost}/realms/localai
|
||||
LOCALAI_OIDC_CLIENT_ID: localai
|
||||
LOCALAI_OIDC_CLIENT_SECRET: ${LOCALAI_OIDC_CLIENT_SECRET:-localai_oidc_secret}
|
||||
LOCALAI_BASE_URL: https://${DOMAIN:-localhost}
|
||||
LOCALAI_BASE_URL: https://${DOMAIN_LOCALAI:-localhost}
|
||||
LOCALAI_ADMIN_EMAIL: ${LOCALAI_ADMIN_EMAIL:-admin@example.com}
|
||||
LOCALAI_API_KEY: ${LOCALAI_API_KEY:-}
|
||||
LOCALAI_REGISTRATION_MODE: invite
|
||||
@@ -370,7 +430,45 @@ services:
|
||||
start_period: 30s
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 5. nginx — reverse proxy
|
||||
# 5. Open WebUI — chat frontend
|
||||
# ---------------------------------------------------------------------------
|
||||
openwebui:
|
||||
image: ghcr.io/open-webui/open-webui:main
|
||||
container_name: localai-openwebui
|
||||
<<: *restart
|
||||
environment:
|
||||
WEBUI_URL: https://${DOMAIN_WEBUI:-localhost}
|
||||
WEBUI_SECRET_KEY: ${OPENWEBUI_SECRET_KEY:-change_me_webui_secret}
|
||||
OPENAI_API_BASE_URL: http://localai:8080/v1
|
||||
OPENAI_API_KEY: ${LOCALAI_API_KEY:-}
|
||||
OPENID_PROVIDER_URL: https://${DOMAIN_AUTH:-localhost}/realms/localai/.well-known/openid-configuration
|
||||
OAUTH_CLIENT_ID: openwebui
|
||||
OAUTH_CLIENT_SECRET: ${OPENWEBUI_OIDC_CLIENT_SECRET:-openwebui_oidc_secret}
|
||||
OAUTH_PROVIDER_NAME: Keycloak
|
||||
OAUTH_SCOPES: openid email profile
|
||||
OAUTH_ROLES_CLAIM: roles
|
||||
OAUTH_ALLOWED_ROLES: localai-user,localai-admin
|
||||
OAUTH_ADMIN_ROLES: localai-admin
|
||||
ENABLE_OAUTH_SIGNUP: "true"
|
||||
ENABLE_LOGIN_FORM: "false"
|
||||
volumes:
|
||||
- ./volumes/openwebui/data:/app/backend/data
|
||||
networks:
|
||||
- localai
|
||||
depends_on:
|
||||
localai:
|
||||
condition: service_healthy
|
||||
keycloak:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "curl -sf http://localhost:8080/health || exit 1"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 5
|
||||
start_period: 30s
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 6. nginx — reverse proxy
|
||||
# ---------------------------------------------------------------------------
|
||||
nginx:
|
||||
image: nginx:alpine
|
||||
|
||||
Reference in New Issue
Block a user