@r8s/open-webui 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +144 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +304 -0
- package/dist/index.js.map +1 -0
- package/package.json +14 -7
- package/__tests__/open-webui.test.ts +0 -457
- package/examples/basic.tsx +0 -8
- package/src/index.tsx +0 -426
- package/tsconfig.json +0 -15
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import type { SecretRef } from '@r8s/recipes';
|
|
2
|
+
export interface OpenWebuiProps {
|
|
3
|
+
/** Resource name (defaults to 'open-webui') */
|
|
4
|
+
name?: string;
|
|
5
|
+
/** Kubernetes namespace (defaults to 'default') */
|
|
6
|
+
namespace?: string;
|
|
7
|
+
/** Container image tag (defaults to 'latest' — pin a version in production) */
|
|
8
|
+
version?: string;
|
|
9
|
+
/** Public hostname for the chat UI (required) */
|
|
10
|
+
host: string;
|
|
11
|
+
/**
|
|
12
|
+
* Number of replicas (defaults to 1). Multiple replicas need a shared
|
|
13
|
+
* object store for uploads/RAG (this recipe errors when `storage` is
|
|
14
|
+
* set with replicas > 1 — its PVC is ReadWriteOnce) and Redis-backed
|
|
15
|
+
* websocket coordination (WEBSOCKET_MANAGER=redis + REDIS_URL).
|
|
16
|
+
*/
|
|
17
|
+
replicas?: number;
|
|
18
|
+
/**
|
|
19
|
+
* PVC size for uploads and RAG document storage (e.g. '10Gi'). When set,
|
|
20
|
+
* a `${name}-uploads` PersistentVolumeClaim is rendered and mounted at
|
|
21
|
+
* /app/backend/data. WebService cannot express volume mounts, which is
|
|
22
|
+
* why this component composes a raw Deployment (probes /health:8080).
|
|
23
|
+
* The PVC is ReadWriteOnce — combining this with replicas > 1 throws
|
|
24
|
+
* (single-node attach); multi-replica installs must move files/RAG to
|
|
25
|
+
* an S3-compatible store and set WEBSOCKET_MANAGER=redis.
|
|
26
|
+
*/
|
|
27
|
+
storage?: string;
|
|
28
|
+
/**
|
|
29
|
+
* OpenAI-compatible API base URL for the model backend (defaults to
|
|
30
|
+
* 'https://api.berget.ai/v1'). The key itself is never passed as a
|
|
31
|
+
* prop — it arrives via secretKeyRef from the secrets bundle below.
|
|
32
|
+
*/
|
|
33
|
+
backend?: string;
|
|
34
|
+
/**
|
|
35
|
+
* Name of an existing Secret holding `modelApiKey` (the key used to
|
|
36
|
+
* call `backend`) and `secretKey` (the WEBUI_SECRET_KEY used to sign
|
|
37
|
+
* auth tokens). Required unless a secrets backend (openbao/vault) is
|
|
38
|
+
* configured on the surrounding Platform — the backend then provisions
|
|
39
|
+
* both keys automatically. Plaintext keys are not supported.
|
|
40
|
+
*/
|
|
41
|
+
secretsName?: string;
|
|
42
|
+
/**
|
|
43
|
+
* OAuth/OIDC SSO client — register Open WebUI as a client in Keycloak
|
|
44
|
+
* (the Auth recipe) and reference the client secret through the backend.
|
|
45
|
+
* Uses the upstream OAUTH_* env names; OPENID_PROVIDER_URL carries the
|
|
46
|
+
* issuer (Open WebUI appends /.well-known/openid-configuration itself).
|
|
47
|
+
*/
|
|
48
|
+
sso?: {
|
|
49
|
+
/** OIDC discovery issuer, e.g. https://keycloak.example.com/realms/platform */
|
|
50
|
+
issuer: string;
|
|
51
|
+
/** Client id registered at the issuer (non-sensitive) */
|
|
52
|
+
clientId: string;
|
|
53
|
+
/** Reference to the Kubernetes Secret holding the client secret */
|
|
54
|
+
clientSecretRef: SecretRef;
|
|
55
|
+
/** Scope list (defaults to 'openid email profile') */
|
|
56
|
+
scopes?: string;
|
|
57
|
+
};
|
|
58
|
+
/** Provision a redis-backed replication group for caching/events (default: false) */
|
|
59
|
+
cache?: boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Air-gapped installs: sets OFFLINE_MODE (disable runtime model/param
|
|
62
|
+
* fetches), removes the update checks and disables the native Ollama
|
|
63
|
+
* API — only OpenAI-compatible backends are served (default: false).
|
|
64
|
+
*/
|
|
65
|
+
offline?: boolean;
|
|
66
|
+
/** Requested resources */
|
|
67
|
+
resources?: {
|
|
68
|
+
requests?: {
|
|
69
|
+
cpu?: string;
|
|
70
|
+
memory?: string;
|
|
71
|
+
};
|
|
72
|
+
limits?: {
|
|
73
|
+
cpu?: string;
|
|
74
|
+
memory?: string;
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
/** TLS configuration (defaults to letsencrypt-prod cluster issuer) */
|
|
78
|
+
tls?: {
|
|
79
|
+
secretName: string;
|
|
80
|
+
clusterIssuer: string;
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Open WebUI — self-hosted chat frontend for OpenAI-compatible backends.
|
|
85
|
+
*
|
|
86
|
+
* @title OpenWebui
|
|
87
|
+
* @category AI & Chat
|
|
88
|
+
*
|
|
89
|
+
* Composes:
|
|
90
|
+
* - CNPG Postgres cluster (users, chats, presets) via the Database recipe
|
|
91
|
+
* - Open WebUI Deployment + Service + Endpoint (websocket-friendly
|
|
92
|
+
* proxy annotations; works through Ingress or Envoy Gateway)
|
|
93
|
+
* - Optional PVC for uploaded files and RAG documents
|
|
94
|
+
* (`${name}-uploads` mounted at /app/backend/data)
|
|
95
|
+
* - Optional redis replication group for caching (`cache`,
|
|
96
|
+
* service ${name}-redis)
|
|
97
|
+
* - Model API key + WEBUI_SECRET_KEY provisioned through the Platform
|
|
98
|
+
* secrets backend (openbao / vault), or referenced from an existing
|
|
99
|
+
* Secret
|
|
100
|
+
* - OAuth/OIDC SSO against the Keycloak `Auth` recipe
|
|
101
|
+
*
|
|
102
|
+
* Wrap the component in `<Platform secrets={{ backend: 'openbao' }}>` and
|
|
103
|
+
* the OPENAI_API_KEY / WEBUI_SECRET_KEY pair is provisioned for you.
|
|
104
|
+
* Without a backend you must point `secretsName` at a pre-created Secret.
|
|
105
|
+
* The Perplexity-style "search the web" extras are not wired — only
|
|
106
|
+
* OPENAI-models via the OpenAI-compatible `backend`.
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* import { Platform } from '@r8s/recipes'
|
|
110
|
+
* import { OpenWebui } from '@r8s/open-webui'
|
|
111
|
+
*
|
|
112
|
+
* export default (
|
|
113
|
+
* <Platform secrets={{ backend: 'openbao', mount: 'kv', path: 'apps' }}>
|
|
114
|
+
* <OpenWebui
|
|
115
|
+
* name="chat"
|
|
116
|
+
* host="chat.example.com"
|
|
117
|
+
* version="v0.6.5"
|
|
118
|
+
* storage="10Gi"
|
|
119
|
+
* />
|
|
120
|
+
* </Platform>
|
|
121
|
+
* )
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* import { Platform } from '@r8s/recipes'
|
|
125
|
+
* import { OpenWebui } from '@r8s/open-webui'
|
|
126
|
+
*
|
|
127
|
+
* export default (
|
|
128
|
+
* <Platform secrets={{ backend: 'openbao', mount: 'kv', path: 'apps' }}>
|
|
129
|
+
* <OpenWebui
|
|
130
|
+
* name="chat"
|
|
131
|
+
* host="chat.example.com"
|
|
132
|
+
* storage="10Gi"
|
|
133
|
+
* cache
|
|
134
|
+
* sso={{
|
|
135
|
+
* issuer: 'https://keycloak.example.com/realms/platform',
|
|
136
|
+
* clientId: 'open-webui',
|
|
137
|
+
* clientSecretRef: { secret: 'chat-sso', key: 'clientSecret' },
|
|
138
|
+
* }}
|
|
139
|
+
* />
|
|
140
|
+
* </Platform>
|
|
141
|
+
* )
|
|
142
|
+
*/
|
|
143
|
+
export declare function OpenWebui(props: OpenWebuiProps): import("@r8s/core").r8sElement;
|
|
144
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAK7C,MAAM,WAAW,cAAc;IAC7B,+CAA+C;IAC/C,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,mDAAmD;IACnD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,+EAA+E;IAC/E,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAA;IACZ;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;;;OAKG;IACH,GAAG,CAAC,EAAE;QACJ,+EAA+E;QAC/E,MAAM,EAAE,MAAM,CAAA;QACd,yDAAyD;QACzD,QAAQ,EAAE,MAAM,CAAA;QAChB,mEAAmE;QACnE,eAAe,EAAE,SAAS,CAAA;QAC1B,sDAAsD;QACtD,MAAM,CAAC,EAAE,MAAM,CAAA;KAChB,CAAA;IACD,qFAAqF;IACrF,KAAK,CAAC,EAAE,OAAO,CAAA;IACf;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,0BAA0B;IAC1B,SAAS,CAAC,EAAE;QACV,QAAQ,CAAC,EAAE;YAAE,GAAG,CAAC,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE,CAAA;QAC5C,MAAM,CAAC,EAAE;YAAE,GAAG,CAAC,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE,CAAA;KAC3C,CAAA;IACD,sEAAsE;IACtE,GAAG,CAAC,EAAE;QACJ,UAAU,EAAE,MAAM,CAAA;QAClB,aAAa,EAAE,MAAM,CAAA;KACtB,CAAA;CACF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2DG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,kCA6R9C"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OpenWebui = OpenWebui;
|
|
4
|
+
const jsx_runtime_1 = require("@r8s/core/jsx-runtime");
|
|
5
|
+
const core_1 = require("@r8s/core");
|
|
6
|
+
const defaults_1 = require("@r8s/core/defaults");
|
|
7
|
+
const recipes_1 = require("@r8s/recipes");
|
|
8
|
+
const redis_1 = require("@r8s/crds/redis");
|
|
9
|
+
const operator_redis_1 = require("@r8s/operator-redis");
|
|
10
|
+
/**
|
|
11
|
+
* Open WebUI — self-hosted chat frontend for OpenAI-compatible backends.
|
|
12
|
+
*
|
|
13
|
+
* @title OpenWebui
|
|
14
|
+
* @category AI & Chat
|
|
15
|
+
*
|
|
16
|
+
* Composes:
|
|
17
|
+
* - CNPG Postgres cluster (users, chats, presets) via the Database recipe
|
|
18
|
+
* - Open WebUI Deployment + Service + Endpoint (websocket-friendly
|
|
19
|
+
* proxy annotations; works through Ingress or Envoy Gateway)
|
|
20
|
+
* - Optional PVC for uploaded files and RAG documents
|
|
21
|
+
* (`${name}-uploads` mounted at /app/backend/data)
|
|
22
|
+
* - Optional redis replication group for caching (`cache`,
|
|
23
|
+
* service ${name}-redis)
|
|
24
|
+
* - Model API key + WEBUI_SECRET_KEY provisioned through the Platform
|
|
25
|
+
* secrets backend (openbao / vault), or referenced from an existing
|
|
26
|
+
* Secret
|
|
27
|
+
* - OAuth/OIDC SSO against the Keycloak `Auth` recipe
|
|
28
|
+
*
|
|
29
|
+
* Wrap the component in `<Platform secrets={{ backend: 'openbao' }}>` and
|
|
30
|
+
* the OPENAI_API_KEY / WEBUI_SECRET_KEY pair is provisioned for you.
|
|
31
|
+
* Without a backend you must point `secretsName` at a pre-created Secret.
|
|
32
|
+
* The Perplexity-style "search the web" extras are not wired — only
|
|
33
|
+
* OPENAI-models via the OpenAI-compatible `backend`.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* import { Platform } from '@r8s/recipes'
|
|
37
|
+
* import { OpenWebui } from '@r8s/open-webui'
|
|
38
|
+
*
|
|
39
|
+
* export default (
|
|
40
|
+
* <Platform secrets={{ backend: 'openbao', mount: 'kv', path: 'apps' }}>
|
|
41
|
+
* <OpenWebui
|
|
42
|
+
* name="chat"
|
|
43
|
+
* host="chat.example.com"
|
|
44
|
+
* version="v0.6.5"
|
|
45
|
+
* storage="10Gi"
|
|
46
|
+
* />
|
|
47
|
+
* </Platform>
|
|
48
|
+
* )
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* import { Platform } from '@r8s/recipes'
|
|
52
|
+
* import { OpenWebui } from '@r8s/open-webui'
|
|
53
|
+
*
|
|
54
|
+
* export default (
|
|
55
|
+
* <Platform secrets={{ backend: 'openbao', mount: 'kv', path: 'apps' }}>
|
|
56
|
+
* <OpenWebui
|
|
57
|
+
* name="chat"
|
|
58
|
+
* host="chat.example.com"
|
|
59
|
+
* storage="10Gi"
|
|
60
|
+
* cache
|
|
61
|
+
* sso={{
|
|
62
|
+
* issuer: 'https://keycloak.example.com/realms/platform',
|
|
63
|
+
* clientId: 'open-webui',
|
|
64
|
+
* clientSecretRef: { secret: 'chat-sso', key: 'clientSecret' },
|
|
65
|
+
* }}
|
|
66
|
+
* />
|
|
67
|
+
* </Platform>
|
|
68
|
+
* )
|
|
69
|
+
*/
|
|
70
|
+
function OpenWebui(props) {
|
|
71
|
+
const { name = 'open-webui', namespace = 'default', version = 'latest', host, replicas = 1, storage, backend = 'https://api.berget.ai/v1', secretsName, sso, cache = false, offline = false, resources = {
|
|
72
|
+
requests: { memory: '1Gi', cpu: '500m' },
|
|
73
|
+
limits: { memory: '4Gi', cpu: '2000m' },
|
|
74
|
+
}, tls = { secretName: `${name}-tls`, clusterIssuer: 'letsencrypt-prod' }, } = props;
|
|
75
|
+
const sharedOperators = (0, core_1.useContext)(defaults_1.OperatorContext);
|
|
76
|
+
const secretProvider = (0, core_1.useContext)(defaults_1.SecretContext);
|
|
77
|
+
const resources_ = [];
|
|
78
|
+
// --- Validation -----------------------------------------------------------
|
|
79
|
+
// The uploads PVC is ReadWriteOnce: a single volume can only be attached
|
|
80
|
+
// to one node at a time, so extra replicas with `storage` set would
|
|
81
|
+
// crash-loop. Multi-replica installs are viable only with a shared
|
|
82
|
+
// S3-compatible object store and WEBSOCKET_MANAGER=redis for socket
|
|
83
|
+
// fan-out.
|
|
84
|
+
if (storage && replicas > 1) {
|
|
85
|
+
throw new Error(`OpenWebui "${name}" cannot combine storage with replicas > 1.\n` +
|
|
86
|
+
`\n` +
|
|
87
|
+
`The ${name}-uploads PVC is ReadWriteOnce and Open WebUI keeps ` +
|
|
88
|
+
`uploads/RAG on it — mounting it on multiple nodes is impossible, ` +
|
|
89
|
+
`so extra replicas would stay Unschedulable or crash-loop. ` +
|
|
90
|
+
`Multi-replica deployments also need WEBSOCKET_MANAGER=redis plus a ` +
|
|
91
|
+
`REDIS_URL for socket coordination.\n` +
|
|
92
|
+
`\n` +
|
|
93
|
+
`Fix: either run a single replica alongside the PVC:\n` +
|
|
94
|
+
` <OpenWebui name="${name}" host="${host}" storage="${storage}" replicas={1} />\n` +
|
|
95
|
+
`\n` +
|
|
96
|
+
`Or drop the storage prop and move uploads to S3-compatible storage ` +
|
|
97
|
+
`with a Redis instance (cache) before scaling out:\n` +
|
|
98
|
+
` <OpenWebui name="${name}" host="${host}" replicas={3} cache />`);
|
|
99
|
+
}
|
|
100
|
+
const dbHost = `${name}-rw`;
|
|
101
|
+
const dbCredentialsName = `${name}-db-credentials`;
|
|
102
|
+
const appSecretsName = secretsName ?? `${name}-secrets`;
|
|
103
|
+
// --- Secret provisioning -------------------------------------------------
|
|
104
|
+
// The model API key and the WEBUI_SECRET_KEY are the crown jewels of an
|
|
105
|
+
// Open WebUI install — never render them as plaintext. With a secrets
|
|
106
|
+
// backend they are provisioned through the backend (keys `modelApiKey`
|
|
107
|
+
// and `secretKey`); otherwise reference a pre-created Secret.
|
|
108
|
+
if (!secretsName) {
|
|
109
|
+
if (!secretProvider ||
|
|
110
|
+
(secretProvider.backend !== 'vault' && secretProvider.backend !== 'openbao')) {
|
|
111
|
+
throw new Error(`OpenWebui "${name}" requires application secrets (OPENAI_API_KEY, WEBUI_SECRET_KEY).\n` +
|
|
112
|
+
`\n` +
|
|
113
|
+
`The model API key for "${backend}" and the auth-token signing key must ` +
|
|
114
|
+
`not be rendered as plaintext.\n` +
|
|
115
|
+
`\n` +
|
|
116
|
+
`Fix: configure a secrets backend on the Platform:\n` +
|
|
117
|
+
` <Platform secrets={{ backend: 'openbao', mount: 'kv', path: 'apps' }}>\n` +
|
|
118
|
+
` <OpenWebui name="${name}" host="${host}" />\n` +
|
|
119
|
+
` </Platform>\n` +
|
|
120
|
+
`\n` +
|
|
121
|
+
`Or reference a pre-created Secret (keys: modelApiKey, secretKey):\n` +
|
|
122
|
+
` <OpenWebui name="${name}" host="${host}" secretsName="${name}-secrets" />`);
|
|
123
|
+
}
|
|
124
|
+
const spec = {
|
|
125
|
+
...(secretProvider.backend === 'vault'
|
|
126
|
+
? { vaultAuthRef: secretProvider.authRef }
|
|
127
|
+
: { openbaoAuthRef: secretProvider.authRef }),
|
|
128
|
+
mount: secretProvider.mount,
|
|
129
|
+
type: 'kv-v2',
|
|
130
|
+
path: `${secretProvider.path ?? name}/${name}/secrets`,
|
|
131
|
+
destination: { create: true, name: appSecretsName },
|
|
132
|
+
};
|
|
133
|
+
resources_.push(secretProvider.backend === 'vault'
|
|
134
|
+
? (0, core_1.jsx)('VaultStaticSecret', {
|
|
135
|
+
apiVersion: 'secrets.hashicorp.com/v1beta1',
|
|
136
|
+
kind: 'VaultStaticSecret',
|
|
137
|
+
metadata: { name: `${name}-secrets`, namespace },
|
|
138
|
+
spec,
|
|
139
|
+
})
|
|
140
|
+
: (0, core_1.jsx)('OpenBaoStaticSecret', {
|
|
141
|
+
apiVersion: 'secrets.openbao.org/v1beta1',
|
|
142
|
+
kind: 'OpenBaoStaticSecret',
|
|
143
|
+
metadata: { name: `${name}-secrets`, namespace },
|
|
144
|
+
spec,
|
|
145
|
+
}));
|
|
146
|
+
}
|
|
147
|
+
// --- Operators ------------------------------------------------------------
|
|
148
|
+
if (cache) {
|
|
149
|
+
resources_.push(...(0, operator_redis_1.declareIfMissing)(sharedOperators));
|
|
150
|
+
}
|
|
151
|
+
// Redis — caching (OT-Container-Kit operator). A replication group so
|
|
152
|
+
// the single ${name}-redis master service fronts a 3-node replication
|
|
153
|
+
// set (1 master + 2 replicas) instead of a lone stateful pod.
|
|
154
|
+
if (cache) {
|
|
155
|
+
resources_.push((0, redis_1.RedisReplicationComponent)({
|
|
156
|
+
metadata: { name: `${name}-redis`, namespace },
|
|
157
|
+
spec: {
|
|
158
|
+
clusterSize: 3,
|
|
159
|
+
kubernetesConfig: { image: 'redis:7.2-alpine' },
|
|
160
|
+
},
|
|
161
|
+
}));
|
|
162
|
+
}
|
|
163
|
+
// --- Uploads/RAG PVC --------------------------------------------------------
|
|
164
|
+
// WebService cannot mount volumes, so the app controller below is a raw
|
|
165
|
+
// Deployment. The PVC is rendered alongside and bound when `storage` is
|
|
166
|
+
// set. Without it, uploaded files and RAG documents are lost on restart.
|
|
167
|
+
if (storage) {
|
|
168
|
+
const pvc = {
|
|
169
|
+
apiVersion: 'v1',
|
|
170
|
+
kind: 'PersistentVolumeClaim',
|
|
171
|
+
metadata: { name: `${name}-uploads`, namespace },
|
|
172
|
+
spec: {
|
|
173
|
+
accessModes: ['ReadWriteOnce'],
|
|
174
|
+
resources: { requests: { storage } },
|
|
175
|
+
},
|
|
176
|
+
};
|
|
177
|
+
resources_.push((0, core_1.jsx)('PersistentVolumeClaim', pvc));
|
|
178
|
+
}
|
|
179
|
+
// --- Env wiring --------------------------------------------------------------
|
|
180
|
+
// Every credential arrives via secretKeyRef — declared BEFORE plain env
|
|
181
|
+
// vars in the container env array, so Kubernetes dependent-variable
|
|
182
|
+
// expansion resolves the $(VAR) templates below at runtime.
|
|
183
|
+
const secretRefs = {
|
|
184
|
+
PGPASSWORD: { secret: dbCredentialsName, key: 'password' },
|
|
185
|
+
OPENAI_API_KEY: { secret: appSecretsName, key: 'modelApiKey' },
|
|
186
|
+
WEBUI_SECRET_KEY: { secret: appSecretsName, key: 'secretKey' },
|
|
187
|
+
...(sso ? { OAUTH_CLIENT_SECRET: sso.clientSecretRef } : {}),
|
|
188
|
+
};
|
|
189
|
+
const envVars = [];
|
|
190
|
+
for (const [envName, ref] of Object.entries(secretRefs)) {
|
|
191
|
+
const typed = typeof ref === 'string' ? { secret: ref } : ref;
|
|
192
|
+
envVars.push({
|
|
193
|
+
name: envName,
|
|
194
|
+
valueFrom: { secretKeyRef: { name: typed.secret, key: typed.key ?? envName } },
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
const env = {
|
|
198
|
+
WEBUI_URL: `https://${host}`,
|
|
199
|
+
ENABLE_OPENAI_API: 'true',
|
|
200
|
+
// This recipe targets OpenAI-compatible backends only — the native
|
|
201
|
+
// Ollama API discovery stays off (offline mode forces the same).
|
|
202
|
+
ENABLE_OLLAMA_API: 'false',
|
|
203
|
+
OPENAI_API_BASE_URL: backend,
|
|
204
|
+
// Deterministic parts inlined; the password arrives via $(PGPASSWORD)
|
|
205
|
+
// (secret-backed var declared first in the env array).
|
|
206
|
+
DATABASE_URL: `postgresql://${name}:$(PGPASSWORD)@${dbHost}:5432/${name}`,
|
|
207
|
+
...(cache ? { REDIS_URL: `redis://${name}-redis:6379` } : {}),
|
|
208
|
+
// Upstream OAUTH_* names; ENABLE_OAUTH_SIGNUP (default true) governs
|
|
209
|
+
// whether local-password login is offered alongside the SSO flow.
|
|
210
|
+
...(sso
|
|
211
|
+
? {
|
|
212
|
+
ENABLE_OAUTH_SIGNUP: 'true',
|
|
213
|
+
OPENID_PROVIDER_URL: sso.issuer,
|
|
214
|
+
OAUTH_CLIENT_ID: sso.clientId,
|
|
215
|
+
OPENID_REDIRECT_URI: `https://${host}/oauth/oidc/callback`,
|
|
216
|
+
OAUTH_SCOPES: sso.scopes ?? 'openid email profile',
|
|
217
|
+
}
|
|
218
|
+
: {}),
|
|
219
|
+
...(offline
|
|
220
|
+
? {
|
|
221
|
+
OFFLINE_MODE: 'true',
|
|
222
|
+
ENABLE_UPDATE_CHECK: 'false',
|
|
223
|
+
}
|
|
224
|
+
: {}),
|
|
225
|
+
};
|
|
226
|
+
for (const [key, value] of Object.entries(env)) {
|
|
227
|
+
envVars.push({ name: key, value });
|
|
228
|
+
}
|
|
229
|
+
// --- App controller (raw Deployment — WebService cannot mount volumes) -----
|
|
230
|
+
// Generous probe delays/failures: first-boot runs Alembic migrations
|
|
231
|
+
// against Postgres before /health starts answering.
|
|
232
|
+
const deployment = {
|
|
233
|
+
apiVersion: 'apps/v1',
|
|
234
|
+
kind: 'Deployment',
|
|
235
|
+
metadata: { name, namespace, labels: { app: name } },
|
|
236
|
+
spec: {
|
|
237
|
+
replicas,
|
|
238
|
+
selector: { matchLabels: { app: name } },
|
|
239
|
+
template: {
|
|
240
|
+
metadata: { labels: { app: name } },
|
|
241
|
+
spec: {
|
|
242
|
+
containers: [
|
|
243
|
+
{
|
|
244
|
+
name: 'open-webui',
|
|
245
|
+
image: `ghcr.io/open-webui/open-webui:${version}`,
|
|
246
|
+
imagePullPolicy: 'Always',
|
|
247
|
+
ports: [{ containerPort: 8080 }],
|
|
248
|
+
env: envVars,
|
|
249
|
+
resources,
|
|
250
|
+
livenessProbe: {
|
|
251
|
+
httpGet: { path: '/health', port: 8080 },
|
|
252
|
+
initialDelaySeconds: 30,
|
|
253
|
+
periodSeconds: 10,
|
|
254
|
+
failureThreshold: 6,
|
|
255
|
+
},
|
|
256
|
+
readinessProbe: {
|
|
257
|
+
httpGet: { path: '/health', port: 8080 },
|
|
258
|
+
initialDelaySeconds: 30,
|
|
259
|
+
periodSeconds: 5,
|
|
260
|
+
failureThreshold: 6,
|
|
261
|
+
},
|
|
262
|
+
...(storage && {
|
|
263
|
+
volumeMounts: [{ name: 'uploads', mountPath: '/app/backend/data' }],
|
|
264
|
+
}),
|
|
265
|
+
},
|
|
266
|
+
],
|
|
267
|
+
...(storage && {
|
|
268
|
+
volumes: [{ name: 'uploads', persistentVolumeClaim: { claimName: `${name}-uploads` } }],
|
|
269
|
+
}),
|
|
270
|
+
},
|
|
271
|
+
},
|
|
272
|
+
},
|
|
273
|
+
};
|
|
274
|
+
// Database parent wraps the app so the CNPG cluster, its credentials
|
|
275
|
+
// secret (${name}-db-credentials) and connection conventions stay
|
|
276
|
+
// consistent with the r8s Database recipe. The raw Deployment sets
|
|
277
|
+
// DATABASE_URL statically (the WebService auto-PG block does not apply).
|
|
278
|
+
resources_.push((0, core_1.jsx)(recipes_1.Database, {
|
|
279
|
+
backup: false,
|
|
280
|
+
name,
|
|
281
|
+
namespace,
|
|
282
|
+
storage: '10Gi',
|
|
283
|
+
children: (0, core_1.jsx)('Deployment', deployment),
|
|
284
|
+
}));
|
|
285
|
+
// --- Service -----------------------------------------------------------------
|
|
286
|
+
const service = {
|
|
287
|
+
apiVersion: 'v1',
|
|
288
|
+
kind: 'Service',
|
|
289
|
+
metadata: { name, namespace },
|
|
290
|
+
spec: {
|
|
291
|
+
type: 'ClusterIP',
|
|
292
|
+
selector: { app: name },
|
|
293
|
+
ports: [{ port: 8080, targetPort: 8080 }],
|
|
294
|
+
},
|
|
295
|
+
};
|
|
296
|
+
resources_.push((0, core_1.jsx)('Service', service));
|
|
297
|
+
// --- Endpoint — websocket-friendly proxy timeouts ------------------------------
|
|
298
|
+
resources_.push((0, jsx_runtime_1.jsx)(recipes_1.Endpoint, { name: `${name}-endpoint`, namespace: namespace, host: host, serviceName: name, servicePort: 8080, tls: tls, annotations: {
|
|
299
|
+
'nginx.ingress.kubernetes.io/proxy-read-timeout': '300',
|
|
300
|
+
'nginx.ingress.kubernetes.io/proxy-send-timeout': '300',
|
|
301
|
+
} }));
|
|
302
|
+
return (0, core_1.jsx)(core_1.Fragment, { children: resources_ });
|
|
303
|
+
}
|
|
304
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@r8s/open-webui",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Open WebUI
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "Open WebUI \u2014 chat frontend for OpenAI-compatible backends, Postgres persistence, uploads/RAG storage, OIDC SSO, optional Redis cache",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Berget AI AB",
|
|
7
7
|
"homepage": "https://r8s.berget.ai",
|
|
@@ -29,13 +29,20 @@
|
|
|
29
29
|
},
|
|
30
30
|
"category": "AI & Assistants",
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@r8s/core": "^0.
|
|
33
|
-
"@r8s/crds": "^0.
|
|
34
|
-
"@r8s/k8s-types": "^0.
|
|
35
|
-
"@r8s/recipes": "^0.
|
|
32
|
+
"@r8s/core": "^0.3.0",
|
|
33
|
+
"@r8s/crds": "^0.3.0",
|
|
34
|
+
"@r8s/k8s-types": "^0.3.0",
|
|
35
|
+
"@r8s/recipes": "^0.3.0"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"typescript": "^5.3.0",
|
|
39
|
-
"vitest": "^1.0.0"
|
|
39
|
+
"vitest": "^1.0.0",
|
|
40
|
+
"@r8s/operator-redis": "^0.22.0"
|
|
41
|
+
},
|
|
42
|
+
"files": [
|
|
43
|
+
"dist"
|
|
44
|
+
],
|
|
45
|
+
"peerDependencies": {
|
|
46
|
+
"@r8s/operator-redis": "^0.22.0"
|
|
40
47
|
}
|
|
41
48
|
}
|