환경 변수
이 페이지에는 현재 Libre WebUI 백엔드, 프런트엔드, 유지 관리 스크립트가 읽는 운영자용 환경 변수가 나열됩니다. 내부 테스트 전용 canary는 의도적으로 제외합니다.
백엔드 서버
| 변수 | 기본값 | 용도 |
|---|---|---|
NODE_ENV | development | 런타임 모드 |
PORT | 개발 3001, 프로덕션 8080 | 백엔드 HTTP 포트 |
TRUST_PROXY | 미설정(Helm은 0) | 클라이언트 주소를 도출할 때 신뢰하는 정확한 리버스 프록시 홉 수 |
CORS_ORIGIN | 로컬 개발 출처 | 쉼표로 구분한 허용 브라우저 출처 |
SERVE_FRONTEND | 미설정 | true이면 빌드된 프런트엔드를 백엔드에서 제공 |
DOCKER_ENV | 미설정 | true이면 Docker 중심 동작 활성화 |
DATA_DIR | backend/data; 패키지 CLI는 ~/.libre-webui | 영구 데이터 디렉터리 |
PLATFORM_PREFLIGHT_TMP_DIR | backend/temp/preflight; 패키지 CLI는 사용자 캐시 | 비공개 DB/WAL 시작 검사 사본용 작업 공간. 데이터베이스와 WAL을 수용하도록 설정 |
PLUGIN_UPLOAD_TEMP_DIR | OS 임시 디렉터리 아래 libre-webui-plugin-uploads | 진행 중 플러그인 업로드 작업 공간 |
PLUGINS_DIR | $DATA_DIR/plugins | 설치/사용자 지정 플러그인의 쓰기 가능 디렉터리 |
BASE_URL | http://localhost:3001 | OAuth 콜백 기본값에 사용하는 기본 URL |
LOG_LEVEL | info(테스트는 warn) | 백엔드 로그 수준 |
LOG_FORMAT | text | json은 타임스탬프, 상관 ID, 민감 정보 제거를 포함한 구조화 한 줄 로그로 전환 |
OTEL_EXPORTER_OTLP_ENDPOINT | 미설정 | 선택적 OTLP/HTTP JSON 텔레메트리 내보내기. 미설정이면 프로세스 밖으로 전송하지 않음 |
OTEL_EXPORTER_OTLP_HEADERS | 미설정 | OTLP 수집기로 보내는 쉼표 구분 key=value 헤더(예: 인증) |
OTEL_SERVICE_NAME | libre-webui | 내보낸 텔레메트리의 service.name 리소스 속성 |
WEBUI_HOST | 루프백; Docker는 0.0.0.0 | HTTP 수신 주소 |
OPEN_BROWSER | 프런트엔드 제공 시 true | 자동 브라우저 실행을 막으려면 false 설정 |
FULL_DOCUMENT_CONTEXT_MAX_TOKENS | 32000 | 채팅별 전체 문서 문맥 모드 토큰 제한(1000-2000000) |
GALLERY_RETENTION_DAYS | 미설정(영구 보관) | 스케줄러 스윕으로 지정 일수보다 오래된 갤러리 미디어 삭제 |
RECOVERY_DRILL_INTERVAL_HOURS | 미설정(훈련 꺼짐) | N시간마다 검증된 복구 훈련 자동 실행(solo 프로필) |
RECOVERY_DRILL_HISTORY | 60 | 보관할 복구 훈련 기록 수 |
소스 실행은 셸의 작업 디렉터리와 관계없이 상대 DATA_DIR, PLUGINS_DIR, PLATFORM_PREFLIGHT_TMP_DIR 값을 백엔드 디렉터리에 고정합니다. DATA_DIR가 미설정이거나 새 소스 예제 DATA_DIR=./data이면 루트 및 백엔드 워크스페이스 명령 모두 backend/data를 사용합니다. 호환성을 위해 DATA_DIR=./backend/data를 가진 기존 소스 설정은 계속 backend/backend/data를 선택합니다. 중지된 상태에서 의도적으로 백업 및 마이그레이션할 때만 바꾸세요. 미설정 소스 프로필은 backend/backend/data만 기존 영구 스토리지일 때도 계속 사용합니다. 두 위치 모두 상태가 있는데 경로를 선택하지 않으면 추측, 복사, 병합하지 않고 안전하게 시작이 실패합니다.
npx, 전역 npm, 대화형 Homebrew 실행기는 대신 ~/.libre-webui 아래에 데이터를 보존합니다. 실행기에 명시한 상대 DATA_DIR는 호출자의 작업 디렉터리를 기준으로 해석되어 백엔드 시작 전에 절대 경로로 바뀝니다. 명시적 상대 PLUGINS_DIR도 같은 규칙을 따릅니다. 미설정이면 쓰기 가능 플러그인은 $DATA_DIR/plugins 아래에 있습니다. 검사 작업 공간은 데이터 디렉터리 밖의 사용자 쓰기 가능 캐시를 기본값으로 사용합니다. macOS는 ~/Library/Caches/libre-webui, Windows는 %LOCALAPPDATA%\libre-webui, 기타 시스템은 ${XDG_CACHE_HOME:-~/.cache}/libre-webui입니다. Homebrew 서비스는 같은 홈 데이터 디렉터리를 고정하고 작업 공간에 Homebrew var/libre-webui/preflight를 사용합니다. 캐시가 데이터베이스와 WAL을 담지 못하면 PLATFORM_PREFLIGHT_TMP_DIR를 명시하세요. 제공된 Docker 및 Helm 배포는 별도 마운트가 뒷받침하는 절대 /app/backend/data, /app/backend/temp/preflight 경로를 사용합니다.
플랫폼 기반
기본 solo 프로필은 SQLite, 로컬 암호화 Blob, 암호화 내장 벡터, 로컬 조율, 내장 영구 워커를 사용합니다. team 프로필은 PostgreSQL, 비공개 S3 호환 Blob, PGVector, Redis, 외부 워커를 사용합니다. Team 설정은 안전하게 실패하며 모든 공유 종속성을 함께 선택해야 합니다.
| 변수 | 기본값 | 용도 |
|---|---|---|
LIBRE_PLATFORM_MODE | solo | 일관된 solo 또는 team 프로필 선택 |
DATABASE_BACKEND | sqlite | sqlite 또는 postgres 선택 |
DATABASE_URL | 미설정 | PostgreSQL 연결 URL. postgres 사용 시 필수 |
DATABASE_SSL_MODE | verify-full | PostgreSQL TLS 정책: disable, require, 호스트 이름 검증 verify-full |
POSTGRES_MIGRATION_MODE | apply | 리더 잠금 아래 호환 마이그레이션 실행. 읽기 전용 스키마 검사에는 validate |
POSTGRES_POOL_MAX | 10 | 애플리케이션 또는 워커 프로세스당 최대 PostgreSQL 연결(1-100) |
POSTGRES_CONNECT_TIMEOUT_MS | 5000 | PostgreSQL 연결 타임아웃(1-60000 ms) |
POSTGRES_IDLE_TIMEOUT_MS | 30000 | PostgreSQL 유휴 연결 타임아웃(1-600000 ms) |
POSTGRES_STATEMENT_TIMEOUT_MS | 30000 | PostgreSQL 문장 타임아웃(1-600000 ms) |
POSTGRES_MIGRATION_LOCK_TIMEOUT_MS | 60000 | 마이그레이션 리더 잠금을 기다리는 시간(1-600000 ms) |
BLOB_STORE_BACKEND | local | 암호화 local 스토리지 또는 비공개 s3 선택 |
VECTOR_STORE_BACKEND | SQLite에서는 embedded | 암호화 embedded 벡터 또는 pgvector 선택 |
COORDINATION_BACKEND | solo는 local; team은 redis | 프로세스 로컬 또는 Redis 조율 선택 |
REDIS_URL | 미설정 | redis: 또는 rediss: URL. Redis 조율 시 필수 |
REDIS_KEY_PREFIX | libre | Libre 조율 키의 1-64자 네임스페이스 |
REDIS_CONNECT_TIMEOUT_MS | 5000 | 초기 Redis 연결 타임아웃. 최대 60초 |
JOB_WORKER_MODE | solo는 embedded; team은 external | 앱 내부 또는 독립 공유 워커에서 핸들러 실행 |
RESOURCE_LEASE_TTL_MS | 30000 | 영구 작업 리소스 소유권 조율 임대 TTL(5000-300000, 범위 밖이면 시작 실패) |
JOB_WORKER_CONCURRENCY | 4 | 워커 하나가 동시에 실행할 영구 작업 수(1-32) |
CHAT_STREAM_EVENT_RETENTION_HOURS | 24 | 시간별 스윕이 채팅 스트림 청크 이벤트를 제거하기 전 보관 시간 |
PLATFORM_EVENT_RETENTION_DAYS | 30 | 시간별 스윕이 영구 이벤트를 제거하기 전 보관 일수 |
PLATFORM_JOB_RETENTION_DAYS | 30 | 시간별 스윕이 완료된 비라이프사이클 작업을 제거하기 전 보관 일수 |
LIBRE_SKIP_STARTUP_INTEGRITY_SCAN | 미설정 | 1은 다음 시작의 심층 기존 암호문 검사를 건너뜀(탈출구. 그 외에는 스키마 세대별 캐시) |
STORAGE_ENCRYPTION_KEYS | 미설정 | 시크릿 JSON 키 맵. 현재 ENCRYPTION_KEY와 일치하는 legacy를 포함해야 함 |
STORAGE_ENCRYPTION_ACTIVE_KEY_ID | 미설정 | 새 로컬 Blob 및 내장 벡터 쓰기에 사용할 키 ID |
BLOB_QUOTA_BYTES_PER_USER | 10737418240 | 소유자별 영구 평문 Blob 바이트 최대값(양의 안전 정수) |
BLOB_QUOTA_RESERVATION_TTL_MS | 3600000 | 방치된 스트리밍 할당량 예약의 수명(최소 60000 ms) |
S3_BUCKET | 미설정 | 비공개 S3 호환 버킷. s3 사용 시 필수 |
S3_REGION | 미설정 | S3 리전. s3 사용 시 필수 |
S3_ENDPOINT | 제공자 기본값 | MinIO 또는 다른 호환 서비스용 선택적 절대 HTTP(S) 엔드포인트 |
S3_ACCESS_KEY_ID | SDK 자격 증명 체인 | 선택적 명시 S3 접근 키 |
S3_SECRET_ACCESS_KEY | SDK 자격 증명 체인 | 명시적 접근 키 설정 시 필수 |
S3_SESSION_TOKEN | 미설정 | 명시적 S3 자격 증명과 함께 쓰는 선택적 토큰 |
S3_FORCE_PATH_STYLE | false | path-style 주소가 필요한 서비스는 true 설정 |
S3_BLOB_PREFIX | libre/blobs | Libre가 소유한 불투명 버킷 키 접두사 |
버전 관리 스토리지 키 맵이 없으면 스토리지 어댑터는 기존 ENCRYPTION_KEY를 키 ID legacy로 사용합니다. 이것도 없으면 새로 만들거나 수정하지 않고 기존 ${DATA_DIR}/.encryption_key를 읽습니다. 명시적 설정과 영구 파일은 일치해야 합니다. 기존 키가 있는 상태에서 버전 관리 맵을 도입하면 모든 객체와 벡터를 다시 쓰거나 래핑하고 검증할 때까지 정확한 ID legacy 아래에 키를 유지하세요. 충돌, 안전하지 않은 파일 권한, 심볼릭 링크, 설정 키 누락은 안전하게 실패합니다.
Redis는 조율 수단이지 정본 영속성이 아닙니다. Redis만 선택해도 SQLite, 로컬 파일, 기타 프로세스 소유 상태가 복제본 간에 안전해지지 않습니다. Team 모드에서 HTTP 속도 제한, 채팅/WebSocket 연결, STT/TTS/오디오 제공자 작업, 아카이브 가져오기, Work 터미널 세션은 Redis 기반 공유 수용량을 사용합니다. 용량은 프로세스마다가 아니라 모든 복제본에 적용됩니다. 승인 및 갱신 가능 permit 실패는 503을 반환하거나 진행 작업을 중단합니다. Libre는 독립 로컬 카운터로 대체하지 않습니다. 플랫폼 기반을 참조하세요.
번들 team Compose 프로필과 Helm 차트는 위의 모든 team 플랫폼 선택기와 조정 값을 애플리케이션과 외부 워커 모두에 전달합니다. Helm 차트에서 비시크릿 선택기는 env 아래에 둡니다. 연결 또는 키 자료는 secrets.redisUrl, secrets.databaseUrl, secrets.storageEncryptionKeys를 설정합니다. PostgreSQL 풀 제한은 프로세스별이므로 데이터베이스에 최소 (replicaCount + worker.replicaCount) * POSTGRES_POOL_MAX 연결과 운영·마이그레이션 여유를 확보하세요. 관리형 또는 원격 PostgreSQL에는 DATABASE_SSL_MODE=verify-full을 유지합니다. 번들 team Compose 프로필만 비공개 프로젝트 네트워크에 데이터베이스 리스너가 격리되므로 disable을 선택합니다. Team Helm은 안정된 secrets.jwtSecret 하나도 요구하며 같은 Secret 키를 모든 애플리케이션 및 워커 Pod에 마운트합니다. JWT 시크릿이 없으면 프로세스 로컬 서명 자료가 생성될 수 있기 때문입니다. S3는 불투명 키와 암호문을 받으며 버킷 및 제공자 URL은 애플리케이션 메타데이터에 저장되지 않습니다.
통합 solo 및 team 아카이브는 PostgreSQL 풀 및 타임아웃 설정, Redis 연결 타임아웃, 두 Blob 할당량 설정, 플랫폼 선택기, S3 주소 설정을 서명 및 암호화된 보호 설정에 보존합니다. 깨끗한 복원은 평문 아카이브 메타데이터에 값을 넣지 않고 일치하는 배포 재생성에 필요한 운영 값을 게시할 수 있습니다.
번들 team Compose와 Helm의 애플리케이션/외부 워커 쌍은 같은 OLLAMA_BASE_URL, OLLAMA_TIMEOUT, OLLAMA_LONG_OPERATION_TIMEOUT, OLLAMA_MAX_CONTEXT를 받습니다. 문서 임베딩, 영구 채팅, Work 실행의 제공자 호출은 워커에서 실행되므로 프로세스 간 값이 달라서는 안 됩니다. 두 서버 엔트리포인트는 로컬 또는 공유 상태를 만들기 전에 세 숫자 값을 완전한 10진수 양의 정수로 파싱합니다. 300000ms 같은 부분 값, 지수/16진 표기, 범위 밖 값, 표준 타임아웃보다 짧은 장기 작업 타임아웃은 시작을 실패시킵니다.
Helm은 TRUST_PROXY를 0~16의 정확한 정수 홉 수로 제한하고 HTTP 애플리케이션 Pod에만 전달합니다. 직접 트래픽에는 기본값 0을 유지하세요. ingress/load-balancer 고정 체인의 정확한 수를 설정하고 런타임의 무제한 true 형식은 쓰지 마세요. 잘못된 수는 공유 속도 제한에서 클라이언트를 프록시 주소 아래 묶거나 클라이언트가 제공한 주소를 신뢰하게 합니다.
PostgreSQL 스키마 호환성은 정확한 버전 기준입니다. Helm 앱과 워커는 Recreate를 사용합니다. Team 업그레이드 전에 모든 이전 Pod를 드레인하고 종료한 뒤 새 프로세스 하나가 advisory 리더 잠금 아래 마이그레이션하게 합니다. 혼합 바이너리 버전 또는 무중단 스키마 배포를 주장하지 마세요. 롤백은 일치하는 이전 바이너리를 시작하기 전에 검증된 업그레이드 전 team 아카이브를 깨끗한 PostgreSQL/S3 대상으로 복원하는 것입니다.
활성 team 애플리케이션에는 worker.replicaCount >= 1이 필요합니다. Helm은 준비 실패를 기다리지 않고 영구 워커가 없는 활성 앱을 거부합니다. 전체 일시 중지에는 애플리케이션과 워커 수를 모두 0으로 설정하세요. 앱 0, 워커 양수는 의도적인 워커 전용 드레인 또는 복구 모드이며 웹 트래픽을 제공하지 않고 대기 작업을 계속 처리합니다.
비공개 백업 도우미
다음 변수는 deploy/private/libre-webui-backup을 설정하며 애플리케이션 프로세스가 아니라 유지 관리 스크립트가 읽습니다.
| 변수 | 기본값 | 용도 |
|---|---|---|
LIBRE_WEBUI_STACK_DIR | /opt/libre-webui | 비공개 Compose 파일이 있는 디렉터리 |
LIBRE_WEBUI_BACKUP_DIR | /var/backups/libre-webui | 백업 세트 및 잠금 파일의 보호 디렉터리 |
LIBRE_WEBUI_BACKUP_RETENTION_DAYS | 14 | 완료된 백업 세트를 제거할 나이 |
LIBRE_WEBUI_CONTAINER_NAME | libre-webui | 검사할 배포 애플리케이션 컨테이너 |
LIBRE_WEBUI_BACKUP_KEY_DIR | /etc/libre-webui/backup-keys | 비공개 아카이브 암호화 및 서명 키 디렉터리 |
LIBRE_WEBUI_RESTORE_IMAGE | 복원 시 필수 | 검토된 불변 Libre 이미지 ID 또는 다이제스트 |
LIBRE_WEBUI_RESTORE_CONFIG_DIR | /etc/libre-webui/restored 아래 볼륨별 경로 | 복구된 설정의 새 디렉터리 |
systemd 유닛은 선택적인 root 소유 /etc/libre-webui/backup.env에서 백업 재정의를 불러옵니다. 모드를 0600으로 설정하세요. 스택 디렉터리, 보존 기간, 컨테이너 이름, 백업 키 디렉터리를 직접 설정할 수 있습니다. 유닛 파일시스템 샌드박스는 기본 백업 디렉터리 아래만 쓰기를 허용합니다. 사용자 지정 LIBRE_WEBUI_BACKUP_DIR에는 미리 만든 정확한 디렉터리를 ReadWritePaths= 서비스 drop-in에도 추가해야 합니다. 비공개 원격 배포를 참조하세요.
인증 및 보안
| 변수 | 기본값 | 용도 |
|---|---|---|
ENABLE_SIGNUP | false | 첫 로컬 관리자 이후 등록 허용 |
JWT_SECRET | 개발 환경에서 생성/대체 | JWT 서명 시크릿. 프로덕션에서는 명시적으로 설정 |
JWT_EXPIRES_IN | 7d | 세션 토큰 수명 |
ENCRYPTION_KEY | 자동 생성 | 암호화 값용 64자 16진수 키 |
DEBUG_ENCRYPTION | 미설정 | 설정 시 암호화 디버그 출력 기록 |
TURNSTILE_SITE_KEY | 미설정 | 로그인 및 가입용 Cloudflare Turnstile 사이트 키 |
TURNSTILE_SECRET_KEY | 미설정 | 백엔드 검증용 Cloudflare Turnstile 시크릿 키 |
TURNSTILE_EXPECTED_HOSTNAME | BASE_URL의 호스트 이름 | Cloudflare 검증 응답에 필요한 호스트 이름 |
MFA_REQUIRED_MODE | 미설정(관리자 스위치, optional) | 2단계 정책을 optional 또는 required로 고정 |
WEBAUTHN_RP_ID | 요청 호스트 이름 | 여러 호스트 이름 뒤 패스키의 고정 relying-party ID |
VAPID_PUBLIC_KEY | 생성 후 암호화 저장 | Web Push VAPID 공개 키 고정(base64url P-256 point) |
VAPID_PRIVATE_KEY | 생성 후 암호화 저장 | Web Push VAPID 비공개 키 고정(base64url scalar) |
VAPID_SUBJECT | mailto:admin@localhost | 서명된 Web Push 인증 내부의 연락처 claim |
두 Turnstile 키가 모두 있을 때만 Turnstile이 활성화됩니다.
ENABLE_SIGNUP=false여도 빈 데이터베이스의 첫 로컬 관리자는 허용하고 이후 로컬 및 OAuth 계정은 차단합니다. 원격에서 접근 가능한 초기 설정 경로는 첫 시작 전에 외부 신원 경계로 보호하세요.
발급된 모든 JWT는 서버 측 세션(sid claim)에 연결됩니다. 로그아웃하거나 설정 → 세션에서 세션을 취소하면 모든 복제본에서 토큰이 즉시 무효화되고 실시간 WebSocket 연결이 닫힙니다. 보안 감사 보존은 다음으로 설정합니다.
| 변수 | 기본값 | 용도 |
|---|---|---|
AUDIT_RETENTION_DAYS | 180 | 보안 감사 이벤트 로그 행 보존 일수 |
일반 OIDC Single Sign-On
검색 문서가 있는 모든 OpenID Connect 제공자를 로그인에 사용할 수 있습니다. 흐름은 PKCE(S256), CSRF state, 서명 검증된 ID 토큰 안의 nonce 검증을 사용합니다. 신원은 안정된 sub claim으로 연결됩니다.
| 변수 | 기본값 | 용도 |
|---|---|---|
OIDC_ISSUER_URL | 미설정 | 발급자 기본 URL. <issuer>/.well-known/openid-configuration에서 검색 |
OIDC_CLIENT_ID | 미설정 | 제공자에 등록한 OAuth 클라이언트 ID |
OIDC_CLIENT_SECRET | 미설정 | OAuth 클라이언트 시크릿 |
OIDC_DISPLAY_NAME | Single Sign-On | 로그인 버튼에 표시되는 라벨 |
OIDC_SCOPES | openid profile email | 요청 범위 |
OIDC_CALLBACK_URL | BASE_URL + OIDC 콜백 경로 | 제공자에 등록한 리디렉션 URI |
OIDC_ALLOWED_EMAIL_DOMAINS | 미설정 | 쉼표 목록. 설정 시 해당 도메인 중 하나의 검증된 이메일 필요 |
OIDC_GROUP_CLAIM | groups | 그룹 이름을 담는 ID 토큰 claim |
OIDC_ADMIN_GROUPS | 미설정 | 쉼표 목록. 설정 시 로그인마다 claim 구성원에 따라 관리자 역할 결정 |
OIDC_SYNC_GROUPS | false | true이면 로그인마다 Libre 그룹 소속을 그룹 claim과 조정 |
발급자 URL, 클라이언트 ID, 클라이언트 시크릿이 모두 있어야 OIDC가 활성화됩니다. 연결되지 않은 로컬 계정이 이미 쓰는 이메일은 조용히 병합하지 않고 거부하며 계정 생성은 계속 ENABLE_SIGNUP을 따릅니다.
인증을 약화하지 않고 Chat WebSocket 수용량을 조정할 수 있습니다.
| 변수 | 기본값 | 용도 |
|---|---|---|
CHAT_WS_MAX_PAYLOAD_BYTES | 10 MiB | 허용하는 최대 WebSocket 메시지 크기 |
CHAT_WS_MAX_MESSAGES_PER_MINUTE | 120 | 연결별 분당 WebSocket 메시지 상한 |
CHAT_WS_MAX_ACTIVE_GENERATIONS_PER_USER | 4 | 계정별 허용 제공자 생성 수 |
CHAT_WS_MAX_CONNECTIONS_PER_USER | 5 | 계정별 동시 인증 소켓 수 |
WEBSOCKET_TICKET_TTL_MS | 30000 | 일회용 Chat/Work 티켓 수명. 최대 60초 |
브라우저는 일반 Authorization 헤더를 불투명 티켓으로 교환하고 짧게 유효한 값만 WebSocket 업그레이드 URL에 넣습니다. 티켓은 1회용이고 프로토콜과 세션에 묶이며 해시로만 저장됩니다. 영구 세션 토큰이 리버스 프록시 요청 대상 로그에 들어가지 않습니다. CORS_ORIGIN 또는 BASE_URL이 설정되면 Origin 헤더가 있는 브라우저 업그레이드는 설정된 출처 중 하나와 일치해야 합니다. 원격 접근 배포에서는 하나 이상을 설정하세요. 둘 다 없으면 로컬 개발 호환성을 위해 Origin 필터가 허용적입니다.
Origin이 없는 업그레이드는 브라우저 Origin 제어를 사용할 수 없는 Electron 및 비브라우저 클라이언트를 위해 의도적으로 지원됩니다. 그래도 유효한 1회용 티켓과 같은 현재 계정, Work 접근, 작업 검사가 필요합니다. 티켓을 인증 경계로 취급하고 일반 TLS, 방화벽, 리버스 프록시 제어로 비브라우저 접근을 제한하세요.
OAuth
| 변수 | 용도 |
|---|---|
GITHUB_CLIENT_ID | GitHub OAuth 클라이언트 ID |
GITHUB_CLIENT_SECRET | GitHub OAuth 클라이언트 시크릿 |
GITHUB_CALLBACK_URL | GitHub 콜백 URL 재정의 |
HUGGINGFACE_CLIENT_ID | Hugging Face OAuth 클라이언트 ID |
HUGGINGFACE_CLIENT_SECRET | Hugging Face OAuth 클라이언트 시크릿 |
HUGGINGFACE_CALLBACK_URL | Hugging Face 콜백 URL 재정의 |
콜백 URL을 설정하지 않으면 Libre WebUI가 BASE_URL에서 기본값을 만듭니다.
Ollama
| 변수 | 기본값 | 용도 |
|---|---|---|
OLLAMA_BASE_URL | http://localhost:11434 | Ollama API 기본 URL |
OLLAMA_TIMEOUT | 300000 | 표준 Ollama 요청 타임아웃(1,000-3,600,000 ms) |
OLLAMA_LONG_OPERATION_TIMEOUT | 900000 | 장기 작업 타임아웃(1,000-3,600,000 ms, OLLAMA_TIMEOUT보다 짧을 수 없음) |
OLLAMA_MAX_CONTEXT | 32768 | 자동 채택 최대 모델 문맥(128-2,097,152 토큰) |
웹 검색
| 변수 | 기본값 | 용도 |
|---|---|---|
SEARXNG_URL | 미설정 | 웹 검색 설정의 기본 SearXNG 엔드포인트. 관리자가 설정 > 검색에서 별도 활성화 |
Libre Claw
| 변수 | 기본값 | 용도 |
|---|---|---|
LIBRE_CLAW_BASE_URL | http://127.0.0.1:8766 | 선택적 Libre Claw 데몬 URL |
LIBRE_CLAW_TIMEOUT_MS | 30000 | Libre Claw HTTP 요청 타임아웃 |
Work 런타임
다음 변수는 Libre WebUI 백엔드를 실행하는 컴퓨터 또는 Kubernetes 클러스터의 Work 실행을 설정합니다. 기본 런타임은 Docker이며 Helm 차트는 work.enabled=true일 때 Kubernetes를 선택합니다.
| 변수 | 기본값 | 용도 |
|---|---|---|
WORK_RUNTIME_IMAGE | node:22.22-bookworm@sha256:2d178f2785b96dfbf62a416ca2e40f50e30150b4ff3320d706f0d96e90600eb3 | Work 샌드박스용 고정 이미지 |
WORK_DOCKER_COMMAND | docker | 프로세스에서 사용할 수 있는 Docker 백엔드 CLI 실행 파일 |
WORK_COMMAND_TIMEOUT_MS | 120000 | 기본 타임아웃. 도구는 최대 600000 ms 요청 가능 |
WORK_MAX_OUTPUT_CHARS | 50000 | 각 스트림에 적용되는 stdout/stderr 캡처 제한 |
WORK_MAX_AGENT_ROUNDS | 48 | 실행 하나의 제공자 독립 모델/도구 라운드 예산 |
WORK_STATUS_BLURB_MODEL | 1 | 실행 후 에이전트 사이드바 상태 행을 쓰는 모델 요청 하나를 건너뛰려면 0 설정 |
WORK_MEMORY_LIMIT | 2g | 각 Work 컨테이너에 전달하는 메모리 제한 |
WORK_CPU_LIMIT | 2 | 각 Work 컨테이너에 전달하는 CPU 제한 |
WORK_PIDS_LIMIT | 256 | 각 Work 컨테이너에 전달하는 프로세스 제한 |
WORK_PREVIEW_PORT | 4173 | 작업 컨테이너 안에서 미리보기 서버가 사용할 포트 |
WORK_PREVIEW_BIND | 127.0.0.1 | 작업 미리보기 포트를 공개하는 호스트 인터페이스. 네이티브 Docker Engine Compose 배포에서는 접근 가능한 비공개 브리지 인터페이스를 사용해야 합니다 |
WORK_DOCKER_PUBLISHED_HOST | 앱 기본값: WORK_PREVIEW_BIND와 동일, Compose 기본값: host.docker.internal | Docker가 공개한 미리보기, 화면, 오디오 포트에 백엔드가 연결할 호스트/IP |
WORK_COMPUTER_SCREEN_PORT | 6080 | GUI 샌드박스의 Work Computer 화면 브리지(websockify) 컨테이너 포트 |
WORK_COMPUTER_AUDIO_PORT | 6081 | GUI 샌드박스의 Work Computer 오디오 브리지(websockify → PulseAudio monitor) 컨테이너 포트 |
WORK_MAX_ACTIVE_RUNTIMES_GLOBAL | 3 | 전체 인스턴스의 동시 런타임 기반 작업 수 |
WORK_MAX_ACTIVE_RUNTIMES_PER_USER | 2 | 사용자 한 명의 동시 런타임 기반 작업 수 |
WORK_MAX_TASKS_GLOBAL | 500 | 전체 인스턴스의 최대 영구 Work 작업 수 |
WORK_MAX_TASKS_PER_USER | 100 | 관리자 한 명의 최대 영구 Work 작업 수 |
WORK_NETWORK_NAME | libre-webui-work | 네트워크 활성 작업용 관리 샌드박스 브리지 네트워크 |
WORK_RUN_LEASE_WAIT_MS | 60000 | 복제본 충돌을 보고하기 전에 작업의 공유 런타임 임대를 기다리는 시간(team 모드) |
WORK_RUNTIME_DNS | 미설정 | 네트워크 활성 작업에 강제하는 쉼표 구분 리졸버 IP |
WORK_DOCKER_SOCKET | DOCKER_HOST가 unix:// 또는 tcp://이면 해당 값, 그 외 /var/run/docker.sock | 터미널 및 진단용 Docker Engine 엔드포인트 |
WORK_TERMINAL_MAX_SESSIONS_PER_TASK | 2 | 작업 하나에 연결 가능한 동시 브라우저 터미널 수 |
WORK_TERMINAL_IDLE_TIMEOUT_MS | 900000 | 터미널 세션을 닫기 전 유휴 타임아웃 |
WORK_RUNTIME_IDLE_TIMEOUT_MS | 0(비활성) | 이 시간 동안 활동이 없으면 샌드박스 중지(미리보기 포함) |
WORK_HOST_WORKSPACES_ENABLED | false | 작업이 볼륨 대신 호스트 폴더를 사용하도록 허용 |
WORK_HOST_WORKSPACE_ROOTS | 서버 사용자 홈 디렉터리 | 호스트 워크스페이스가 속해야 하는 : 구분 루트 |
WORK_RUNTIME_BACKEND | docker | 샌드박스 백엔드: docker 또는 kubernetes |
WORK_K8S_NAMESPACE | libre-webui-work | Kubernetes 샌드박스 Pod 및 PVC 네임스페이스 |
WORK_K8S_STORAGE_CLASS | 클러스터 기본값 | 워크스페이스 PVC용 StorageClass |
WORK_K8S_WORKSPACE_SIZE | 5Gi | 작업별 워크스페이스 PVC 크기(실제 디스크 할당량) |
WORK_K8S_POD_READY_TIMEOUT_MS | 900000 | 샌드박스 Pod가 Running에 도달할 때까지 대기(이미지 가져오기 포함) |
WORK_K8S_POD_GONE_TIMEOUT_MS | 60000 | 삭제한 샌드박스 Pod가 사라질 때까지 대기 |
AGENT_CLI_MODELS_ENABLED | 미설정(관리자 스위치, 꺼짐) | Agents 기능 켜기/끄기 고정. 미설정이면 사용자 관리의 관리자 스위치 사용(기본 비활성) |
TOOLS_ACCESS_MODE | 미설정(관리자 스위치, 관리자 전용) | 채팅 도구를 admins 또는 all-users로 고정하고 사용자 관리 스위치 잠금 |
STT_ACCESS_MODE | 미설정(관리자 스위치, 모든 사용자) | 음성 인식을 admins 또는 all-users로 고정하고 사용자 관리 스위치 잠금 |
TTS_ACCESS_MODE | 미설정(관리자 스위치, 모든 사용자) | 음성 합성을 admins 또는 all-users로 고정하고 사용자 관리 스위치 잠금 |
VOICE_MODE_ACCESS_MODE | 미설정(관리자 스위치, 모든 사용자) | 핸즈프리 음성 모드를 admins 또는 all-users로 고정하고 사용자 관리 스위치 잠금 |
VOICE_CLONING_ACCESS_MODE | 미설정(관리자 스위치, 모든 사용자) | 음성 복제를 admins 또는 all-users로 고정하고 사용자 관리 스위치 잠금 |
TOOLS_PRIVATE_NETWORK_ALLOWLIST | 미설정 | 도구 서버와 Webhook 목적지가 사설 주소로 해석할 수 있는 정확한 호스트 이름(쉼표 구분), 고정 |
AGENT_CLI_TIMEOUT_MS | 600000 | agent CLI를 종료하기 전 최대 실행 시간 |
CODEX_OAUTH_MODELS_ENABLED | true | 관리자에게 Codex (ChatGPT) 제공자 표시 |
CODEX_HOME | ~/.codex | Codex CLI 로그인(auth.json)을 읽는 위치 |
Agent CLI 바이너리와 Codex OAuth 자격 증명은 노드 로컬입니다. 검색과 실행이 같은 파일시스템과 환경을 보는 solo 프로세스에서만 지원됩니다. Team 모드는 외부 워커에서 영구 채팅 작업을 실행하므로 AGENT_CLI_MODELS_ENABLED=false와 CODEX_OAUTH_MODELS_ENABLED=false를 모두 요구합니다. 다른 값은 애플리케이션 복제본에만 있을 수 있는 제공자를 광고하지 않도록 시작 시 거부됩니다. 공유 PostgreSQL에 자격 증명과 라우팅이 저장되거나 모든 애플리케이션 및 워커에 동일하게 전달되는 Ollama 또는 제공자 플러그인을 사용하세요.
Docker 백엔드에서 호스트 워크스페이스는 실제 디렉터리를 /workspace에 바인드 마운트해 자체 Docker 볼륨 대신 해당 파일을 직접 읽고 씁니다. Kubernetes는 호스트 폴더 워크스페이스를 거부합니다. 이는 Docker 샌드박스를 의도적으로 약화합니다. 필요하지 않으면 WORK_HOST_WORKSPACES_ENABLED를 끄고 WORK_HOST_WORKSPACE_ROOTS 범위를 최대한 좁히세요. 요청 경로는 루트와 비교하기 전에 심볼릭 링크를 해석하며 .ssh, .gnupg, .aws, .config 같은 폴더는 무조건 거부됩니다.
Agent CLI 모델은 서버에 설치된 코딩 에이전트(claude, codex)를 선택 가능한 채팅 모델로 공개하므로 구독 에이전트가 API 키 없이 답할 수 있습니다. 관리자만 볼 수 있고 CLI는 Libre WebUI 서버 사용자로 실행되어 해당 사용자의 에이전트 자격 증명을 상속합니다. 해당 에이전트에 셸 접근을 주는 것과 동일하게 취급하세요.
Docker에서 네트워크 활성 Work 작업은 관리 WORK_NETWORK_NAME 브리지에 연결됩니다. 컨테이너 간 통신이 비활성화되어 한 샌드박스에서 다른 샌드박스 또는 배포 자체의 컨테이너에 도달할 수 없습니다. WORK_RUNTIME_DNS는 지원되는 Docker 외부 통신 정책 훅입니다. 필터링 리졸버를 지정해 이름 기반 허용/거부 목록을 적용합니다. IPv4/IPv6 주소가 아닌 항목은 거부되고 기록됩니다. DNS 필터링은 직접 IP 송신을 제한하지 않으므로 필요하면 호스트 방화벽 규칙을 추가하세요. Kubernetes 백엔드는 대신 차트의 기본 거부 NetworkPolicies와 work.networkPolicy.blockedEgressCidrs 값을 사용합니다.
Docker에서 대화형 터미널과 시스템 진단은 Docker Engine API와 직접 통신합니다. WORK_DOCKER_SOCKET이 있으면 사용하고, 없으면 DOCKER_HOST(소켓 프록시 같은 unix:// 소켓 또는 평문 HTTP tcp:// 엔드포인트. docker-compose.socket-proxy.yml 참조), 그마저 없으면 /var/run/docker.sock을 사용합니다. 이 클라이언트가 다룰 수 없는 DOCKER_HOST(ssh:// 또는 DOCKER_TLS_VERIFY가 설정된 tcp://)는 터미널과 Docker 진단을 사용 불가로 표시합니다. Work의 나머지는 해당 엔드포인트를 이해하는 Docker CLI를 통해 계속 실행됩니다. Kubernetes에서는 터미널이 Pod exec 하위 리소스를 사용하며 Docker 엔드포인트를 사용하지 않습니다.
Work는 백엔드 시작 시 이 값을 읽습니다. 미리보기 포트는 작업 컨테이너 내부에 있으며, Libre WebUI는 모든 호스트 인터페이스에 직접 공개하지 않고 동적으로 할당된 루프백 포트로 게시합니다.
런타임 이미지를 검토된 버전 또는 다이제스트로 고정하세요. 동시성 또는 리소스 제한을 늘리면 하나 이상의 자율 실행이 소비할 수 있는 런타임 용량이 증가합니다. WORK_MAX_AGENT_ROUNDS는 Ollama 및 플러그인 기반 실행에 동일하게 적용되며 더 낮은 플러그인 전용 상한은 없습니다. 도구 호출 안전 예산은 max(128, WORK_MAX_AGENT_ROUNDS × 8)입니다. 라운드 예산을 소진하면 Work가 모델에 도구 없는 최종 인계를 요청하고 원시 라운드 제한 오류 또는 거짓 완료 대신 최종 needs_input 상태로 끝납니다. 후속 실행은 같은 영구 워크스페이스에서 계속됩니다. 영구 도구 출력에는 원본 약 20,000자와 잘림 마커라는 별도 제한이 있습니다.
이 변수는 이미 연결 가능한 Work 런타임을 조정합니다. 저장소 단일 인스턴스 Compose 배포는 기본으로 활성화되어 있습니다. 이미지에 Docker CLI가 포함되고 Compose 파일이 호스트 Docker 소켓을 마운트합니다. 다음 두 Compose 수준 변수가 연결을 제어합니다.
| 변수 | 기본값 | 용도 |
|---|---|---|
DOCKER_GID | 0 | 컨테이너 사용자에 추가되는 호스트 Docker 소켓 그룹 ID |
DOCKER_SOCKET | /var/run/docker.sock | 마운트할 Docker 소켓의 호스트 경로 |
DOCKER_GID는 컨테이너 내부에서 보이는 소켓 그룹이어야 합니다. macOS 호스트는 다른 값을 보고합니다. Team Compose 기본 구성은 소켓을 마운트하지 않고 docker-compose.team.work.yml을 추가할 때까지 Docker 기반 Work를 사용할 수 없게 합니다. 프로덕션 오버레이는 애플리케이션과 워커 모두에 같은 내부 필터링 프록시 엔드포인트를 주며 소켓 마운트나 소켓 그룹을 주지 않습니다. 프록시는 런타임이 쓰는 Docker API 섹션만 허용하지만 컨테이너 생성은 여전히 Docker 호스트 제어 자격 증명입니다. 더 강한 경계에는 전용 또는 rootless Work 데몬을 사용하세요. Helm 차트는 노드 런타임 소켓을 절대 마운트하지 않습니다. work.enabled=true로 네이티브 Pod/PVC Work 백엔드를 활성화합니다.
solo 프로필은 SQLite, 로컬 파일, 프로세스 로컬 조율을 사용하므로 애플리케이션 복제본이 0 또는 1이어야 합니다. Helm 차트는 의도적 일시 중지에 0을 허용하고 더 큰 solo 복제본 수 및 자동 확장을 거부합니다. 완전한 team 프로필은 PostgreSQL, S3, PGVector, Redis가 공유 상태를 소유하므로 여러 애플리케이션 복제본과 외부 워커를 사용할 수 있습니다. Work 샌드박스 Pod는 두 프로필에서 독립적으로 확장됩니다. Team 모드의 외부 워커는 애플리케이션 Pod와 같은 Kubernetes 런타임 이미지, StorageClass, work.env 제한을 받습니다.
저장소 Compose 파일은 WEBUI_BIND_ADDRESS(기본값 127.0.0.1)와 WEBUI_PORT(기본값 8080)도 허용합니다. 신뢰된 LAN 또는 호스트 리버스 프록시가 포트에 도달해야 하지 않는 한 루프백 기본값을 유지하세요.
제공자 모델 검색
제공자 모델 카탈로그가 없거나 오래되면 자동으로 다시 검색되어 새로 불러올 때 현재 제공 모델을 반영합니다. 다음 변수로 주기를 조정합니다.
| 변수 | 기본값 | 용도 |
|---|---|---|
PLUGIN_MODEL_DISCOVERY_TTL_MS | 21600000(6 h) | 저장 카탈로그가 다음 플러그인 목록 읽기에서 갱신될 나이 |
PLUGIN_MODEL_DISCOVERY_RETRY_MS | 600000(10 min) | 실패 제공자를 자주 검사하지 않도록 하는 최소 시도 간격 |
PLUGIN_MODEL_DISCOVERY_REFRESH_DEADLINE_MS | 3000 | 응답 전 플러그인 목록이 새로 고침을 기다리는 시간 |
기한을 넘긴 새로 고침도 완료되어 다음 요청에서 제공됩니다. 명시적 모델 새로 고침은 항상 제공자에 연결하고 간격을 무시합니다.
제공자 플러그인 키
제공자 플러그인은 환경 키를 배포 전체 기본값으로 사용할 수 있습니다.
| 변수 | 제공자 |
|---|---|
OPENAI_API_KEY | OpenAI 및 OpenAI TTS |
ANTHROPIC_API_KEY | Anthropic |
GROQ_API_KEY | Groq |
GEMINI_API_KEY | Google Gemini |
MISTRAL_API_KEY | Mistral |
OPENROUTER_API_KEY | OpenRouter |
KIMI_API_KEY | Moonshot AI의 Kimi Code |
GITHUB_API_KEY | GitHub Models |
HUGGINGFACE_API_KEY | 설정된 Hugging Face API |
ELEVENLABS_API_KEY | ElevenLabs TTS |
COMFYUI_API_KEY | API 키가 필요한 ComfyUI 배포 |
사용자별 키를 선호하면 UI에 제공자 자격 증명을 저장할 수 있습니다. 환경 키는 shadow되지 않은 번들 정의의 라우팅 및 인증 투영에서만 사용됩니다. 가져온 정의, 번들 ID를 재사용한 쓰기 가능 정의, 관리자가 저장한 사용자 지정 경로에는 해당 계정이 저장한 자격 증명이 필요합니다. Libre WebUI는 해당 경로에 환경 키를 붙이거나 검색 및 가용성 검사로 노출하지 않습니다. 신뢰는 제공된 각 매니페스트의 컴파일된 해시에서 오므로 기존 및 번들 플러그인 디렉터리가 같은 경로인 컨테이너 레이아웃도 수정 매니페스트를 번들로 취급하지 않고 지원됩니다.
사용자 저장 키는 유효 제공자 정의, 소스, 인증 계약, 라우팅 값에 묶입니다. 관리자가 목적지를 바꾸면 다시 저장해야 합니다. 업그레이드 전 바인딩 없는 키는 번들 경로를 쓰는 정확한 제공 정의에서만 처음 사용 시 허용 및 바인딩됩니다.
소스 실행에서 상대 PLUGINS_DIR 값은 백엔드 디렉터리를 기준으로 해석됩니다. 패키지 실행기는 명시적 상대 값을 백엔드 시작 전 호출자 절대 경로로 변환합니다. 호환성을 위해 Libre는 결정적인 backend/plugins 디렉터리와 이전 설정에서 선택한 기존 위치도 읽습니다. 정의를 $DATA_DIR/plugins로 옮기세요. 복구는 기존 경로를 외부 상태로 보고하고 사용자 지정 정의가 남아 있으면 볼륨 전용 스냅샷을 차단합니다. 플러그인 디렉터리와 JSON 정의는 실제 일반 항목이어야 하며 Libre는 플러그인 심볼릭 링크를 따르지 않습니다.
프런트엔드
| 변수 | 기본값 | 용도 |
|---|---|---|
VITE_API_BASE_URL | 동일 출처 개발 프록시 또는 프로덕션 API | 프런트엔드 API 기본 URL |
VITE_WS_BASE_URL | API URL에서 추론 | Chat 및 Work 소켓의 절대 ws:/wss: 기본 URL |
VITE_APP_VERSION | Vite 설정에서 주입한 패키지 버전 | 표시되는 앱 버전 |
VITE_DEMO_MODE | false | true이면 데모 모드 모의 응답 활성화 |
VITE_API_TIMEOUT | 300000 | 프런트엔드 API 타임아웃(ms) |
VITE_BACKEND_URL | http://localhost:3001 | 일부 인증 도우미 구성 요소가 사용 |
VITE_DEBUG_VERBOSE | 미설정 | 개발 중 자세한 프런트엔드 디버그 로그 활성화 |
VITE_LOG_LEVEL | 미설정 | 프런트엔드 로그 수준 재정의 |
ELECTRON_BUILD | 미설정 | true이면 Electron 전용 Vite 동작 활성화 |
VITE_WS_BASE_URL은 Chat과 Work 터미널의 모든 WebSocket 대체값을 재정의합니다. 리버스 프록시 경로 접두사를 포함할 수 있지만 자격 증명, 쿼리, fragment가 없는 절대 ws: 또는 wss: URL이어야 합니다. 미설정이면 Electron file: 클라이언트는 ws://localhost:3001을 사용하고, 브라우저 클라이언트는 VITE_API_BASE_URL, 그다음 브라우저 출처 순으로 기본값을 도출합니다. Vite는 개발 출처를 포트 3001의 백엔드로 프록시합니다.
유지 관리 스크립트
| 변수 | 용도 |
|---|---|
CHANGELOG_AI | AI 지원 변경 로그 초안을 끄려면 0 설정 |
CHANGELOG_AI_MODEL | 릴리스/변경 로그 생성용 Ollama 모델 |
CHANGELOG_AI_TIMEOUT_MS | AI 변경 로그 생성 타임아웃(ms) |
예:
CHANGELOG_AI_MODEL=glm-5.2:cloud npm run changelog
CHANGELOG_AI=0 npm run release:minor
프로덕션 예
NODE_ENV=production
PORT=3001
SERVE_FRONTEND=true
DATA_DIR=/data/libre-webui
CORS_ORIGIN=https://librewebui.example
BASE_URL=https://librewebui.example
JWT_SECRET=replace-with-a-long-random-secret
ENCRYPTION_KEY=replace-with-64-hex-characters
ENABLE_SIGNUP=false
OLLAMA_BASE_URL=http://ollama:11434
OLLAMA_TIMEOUT=300000
OLLAMA_LONG_OPERATION_TIMEOUT=900000
OLLAMA_MAX_CONTEXT=32768
TURNSTILE_SITE_KEY=...
TURNSTILE_SECRET_KEY=...
TURNSTILE_EXPECTED_HOSTNAME=librewebui.example