revert useless dockfile change
|
|
@ -1,10 +1,7 @@
|
|||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(tree:*)",
|
||||
"Bash(node:*)",
|
||||
"Bash(npm --version:*)",
|
||||
"Bash(test:*)"
|
||||
"Bash(tree:*)"
|
||||
],
|
||||
"deny": [],
|
||||
"ask": []
|
||||
|
|
|
|||
137
.github/workflows/docker-image.yml
vendored
|
|
@ -1,137 +0,0 @@
|
|||
name: Docker Image CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
workflow_dispatch: # 允许手动触发
|
||||
|
||||
env:
|
||||
IMAGE_NAME: open-webui-next
|
||||
OUTPUT_DIR: /tmp/docker-images
|
||||
KEEP_VERSIONS: 2
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
steps:
|
||||
- name: 检出代码
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: 设置环境变量
|
||||
run: |
|
||||
echo "IMAGE_TAG=${{ github.run_number }}" >> $GITHUB_ENV
|
||||
echo "BUILD_NUMBER=${{ github.run_number }}" >> $GITHUB_ENV
|
||||
echo "✓ 代码检出完成"
|
||||
ls -la
|
||||
|
||||
- name: 验证 Dockerfile
|
||||
run: |
|
||||
if [ ! -f "Dockerfile" ]; then
|
||||
echo "❌ 找不到 Dockerfile"
|
||||
exit 1
|
||||
fi
|
||||
echo "✓ Dockerfile 存在"
|
||||
head -10 Dockerfile
|
||||
|
||||
- name: 设置 Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: 构建 Docker 镜像
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
load: true
|
||||
tags: |
|
||||
${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }}
|
||||
${{ env.IMAGE_NAME }}:latest
|
||||
build-args: |
|
||||
USE_SLIM=true
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
|
||||
- name: 验证镜像构建
|
||||
run: |
|
||||
echo "✓ 镜像构建完成"
|
||||
docker images | grep ${{ env.IMAGE_NAME }}
|
||||
|
||||
- name: 创建输出目录
|
||||
run: |
|
||||
mkdir -p ${{ env.OUTPUT_DIR }}
|
||||
echo "输出目录: ${{ env.OUTPUT_DIR }}"
|
||||
|
||||
- name: 导出镜像
|
||||
run: |
|
||||
echo "导出镜像..."
|
||||
docker save ${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }} | gzip > ${{ env.OUTPUT_DIR }}/${{ env.IMAGE_NAME }}-${{ env.IMAGE_TAG }}.tar.gz
|
||||
docker save ${{ env.IMAGE_NAME }}:latest | gzip > ${{ env.OUTPUT_DIR }}/${{ env.IMAGE_NAME }}-latest.tar.gz
|
||||
echo "✓ 镜像导出完成"
|
||||
ls -lh ${{ env.OUTPUT_DIR }}/${{ env.IMAGE_NAME }}*.tar.gz
|
||||
|
||||
- name: 上传镜像制品
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: docker-images-${{ env.IMAGE_TAG }}
|
||||
path: |
|
||||
${{ env.OUTPUT_DIR }}/${{ env.IMAGE_NAME }}-${{ env.IMAGE_TAG }}.tar.gz
|
||||
${{ env.OUTPUT_DIR }}/${{ env.IMAGE_NAME }}-latest.tar.gz
|
||||
retention-days: 30
|
||||
|
||||
- name: 清理本地资源
|
||||
if: always()
|
||||
run: |
|
||||
echo "========================================="
|
||||
echo "当前构建: ${{ env.BUILD_NUMBER }}"
|
||||
VERSION_TO_DELETE=$((BUILD_NUMBER - 2))
|
||||
echo "准备清理版本: ${VERSION_TO_DELETE}"
|
||||
echo "========================================="
|
||||
|
||||
# 清理旧版本的 Docker 镜像
|
||||
echo "清理 Docker 镜像..."
|
||||
docker rmi ${{ env.IMAGE_NAME }}:${VERSION_TO_DELETE} 2>/dev/null || echo "镜像 ${VERSION_TO_DELETE} 不存在或已清理"
|
||||
|
||||
# 清理旧版本的 tar.gz 文件
|
||||
echo "清理导出文件..."
|
||||
rm -f ${{ env.OUTPUT_DIR }}/${{ env.IMAGE_NAME }}-${VERSION_TO_DELETE}.tar.gz
|
||||
|
||||
# 清理未使用的 Docker 资源
|
||||
echo "清理未使用的 Docker 资源..."
|
||||
docker image prune -f
|
||||
|
||||
echo "✓ 清理完成"
|
||||
echo ""
|
||||
echo "剩余镜像:"
|
||||
docker images | grep ${{ env.IMAGE_NAME }} || echo "无相关镜像"
|
||||
echo ""
|
||||
echo "剩余文件:"
|
||||
ls -lh ${{ env.OUTPUT_DIR }}/${{ env.IMAGE_NAME }}*.tar.gz 2>/dev/null || echo "无相关文件"
|
||||
|
||||
- name: 显示磁盘使用情况
|
||||
if: always()
|
||||
run: |
|
||||
echo "最终磁盘使用情况:"
|
||||
df -h ${{ env.OUTPUT_DIR }}
|
||||
|
||||
- name: 构建摘要
|
||||
if: success()
|
||||
run: |
|
||||
echo "=========================================" >> $GITHUB_STEP_SUMMARY
|
||||
echo "✅ 构建成功!" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "**镜像信息:**" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- 镜像名称: \`${{ env.IMAGE_NAME }}\`" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- 镜像标签: \`${{ env.IMAGE_TAG }}\`, \`latest\`" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- 构建编号: \`${{ github.run_number }}\`" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "**导出文件:**" >> $GITHUB_STEP_SUMMARY
|
||||
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
||||
ls -lh ${{ env.OUTPUT_DIR }}/${{ env.IMAGE_NAME }}*.tar.gz >> $GITHUB_STEP_SUMMARY
|
||||
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
||||
echo "=========================================" >> $GITHUB_STEP_SUMMARY
|
||||
234
Dockerfile
|
|
@ -1,92 +1,45 @@
|
|||
# syntax=docker/dockerfile:1
|
||||
# Initialize device type args
|
||||
# use build args in the docker build command with --build-arg="BUILDARG=true"
|
||||
ARG USE_CUDA=false
|
||||
ARG USE_OLLAMA=false
|
||||
ARG USE_SLIM=false
|
||||
ARG USE_PERMISSION_HARDENING=false
|
||||
# Tested with cu117 for CUDA 11 and cu121 for CUDA 12 (default)
|
||||
ARG USE_CUDA_VER=cu128
|
||||
# any sentence transformer model; models to use can be found at https://huggingface.co/models?library=sentence-transformers
|
||||
# Leaderboard: https://huggingface.co/spaces/mteb/leaderboard
|
||||
# for better performance and multilangauge support use "intfloat/multilingual-e5-large" (~2.5GB) or "intfloat/multilingual-e5-base" (~1.5GB)
|
||||
# IMPORTANT: If you change the embedding model (sentence-transformers/all-MiniLM-L6-v2) and vice versa, you aren't able to use RAG Chat with your previous documents loaded in the WebUI! You need to re-embed them.
|
||||
ARG USE_EMBEDDING_MODEL=sentence-transformers/all-MiniLM-L6-v2
|
||||
ARG USE_RERANKING_MODEL=""
|
||||
|
||||
# Tiktoken encoding name; models to use can be found at https://huggingface.co/models?library=tiktoken
|
||||
ARG USE_TIKTOKEN_ENCODING_NAME="cl100k_base"
|
||||
|
||||
ARG BUILD_HASH=dev-build
|
||||
# Override at your own risk - non-root configurations are untested
|
||||
ARG UID=0
|
||||
ARG GID=0
|
||||
|
||||
######## WebUI frontend ########
|
||||
FROM --platform=$BUILDPLATFORM node:20-alpine3.20 AS build
|
||||
FROM --platform=$BUILDPLATFORM node:22-alpine3.20 AS build
|
||||
ARG BUILD_HASH
|
||||
|
||||
# ========== 配置 Alpine 镜像源 ==========
|
||||
RUN echo "https://mirrors.aliyun.com/alpine/v3.20/main" > /etc/apk/repositories && \
|
||||
echo "https://mirrors.aliyun.com/alpine/v3.20/community" >> /etc/apk/repositories && \
|
||||
apk update
|
||||
|
||||
# ========== 增加 Node.js 堆内存限制 ==========
|
||||
ENV NODE_OPTIONS="--max-old-space-size=4096"
|
||||
|
||||
# ========== 配置 npm 镜像源 ==========
|
||||
RUN npm config set registry https://registry.npmmirror.com && \
|
||||
npm config set fetch-timeout 120000 && \
|
||||
npm config set fetch-retries 5 && \
|
||||
npm config set fetch-retry-mintimeout 20000 && \
|
||||
npm config set fetch-retry-maxtimeout 120000 && \
|
||||
npm config set maxsockets 5
|
||||
|
||||
# ========== 配置二进制包镜像 ==========
|
||||
ENV ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/ \
|
||||
SASS_BINARY_SITE=https://npmmirror.com/mirrors/node-sass/ \
|
||||
PHANTOMJS_CDNURL=https://nppmirror.com/mirrors/phantomjs/ \
|
||||
CHROMEDRIVER_CDNURL=https://npmmirror.com/mirrors/chromedriver/ \
|
||||
OPERADRIVER_CDNURL=https://npmmirror.com/mirrors/operadriver/ \
|
||||
PYTHON_MIRROR=https://npmmirror.com/mirrors/python/
|
||||
|
||||
# ========== 配置代理(可选)==========
|
||||
ARG HTTP_PROXY
|
||||
ARG HTTPS_PROXY
|
||||
ENV HTTP_PROXY=${HTTP_PROXY}
|
||||
ENV HTTPS_PROXY=${HTTPS_PROXY}
|
||||
ENV NO_PROXY=localhost,127.0.0.1,mirrors.aliyun.com,registry.nppmirror.com,nppmirror.com
|
||||
|
||||
# ========== 安装必要工具 ==========
|
||||
RUN apk add --no-cache git python3 make g++ && \
|
||||
if [ -n "$HTTP_PROXY" ]; then \
|
||||
git config --global http.proxy ${HTTP_PROXY} && \
|
||||
git config --global https.proxy ${HTTPS_PROXY} && \
|
||||
git config --global http.sslVerify false; \
|
||||
fi
|
||||
# Set Node.js options (heap limit Allocation failed - JavaScript heap out of memory)
|
||||
# ENV NODE_OPTIONS="--max-old-space-size=4096"
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# ========== 安装依赖(不使用 --ignore-scripts)==========
|
||||
# to store git revision in build
|
||||
RUN apk add --no-cache git
|
||||
|
||||
COPY package.json package-lock.json ./
|
||||
RUN npm ci --force
|
||||
|
||||
RUN echo "==================================" && \
|
||||
echo "Starting npm install" && \
|
||||
echo "Time: $(date)" && \
|
||||
echo "==================================" && \
|
||||
npm cache clean --force && \
|
||||
npm install --legacy-peer-deps --no-audit --no-fund || \
|
||||
(echo "First attempt failed, retrying..." && \
|
||||
rm -rf node_modules package-lock.json && \
|
||||
npm install --legacy-peer-deps --no-audit --no-fund) && \
|
||||
echo "==================================" && \
|
||||
echo "npm install completed" && \
|
||||
echo "Time: $(date)" && \
|
||||
echo "=================================="
|
||||
|
||||
# ========== 构建前端 ==========
|
||||
COPY . .
|
||||
ENV APP_BUILD_HASH=${BUILD_HASH}
|
||||
|
||||
RUN echo "==================================" && \
|
||||
echo "Starting frontend build" && \
|
||||
echo "Time: $(date)" && \
|
||||
echo "==================================" && \
|
||||
npm run build && \
|
||||
echo "==================================" && \
|
||||
echo "Build completed" && \
|
||||
echo "Time: $(date)" && \
|
||||
echo "=================================="
|
||||
RUN npm run build
|
||||
|
||||
######## WebUI backend ########
|
||||
FROM python:3.11-slim-bookworm AS base
|
||||
|
|
@ -105,6 +58,7 @@ ARG GID
|
|||
## Basis ##
|
||||
ENV ENV=prod \
|
||||
PORT=8080 \
|
||||
# pass build args to the build
|
||||
USE_OLLAMA_DOCKER=${USE_OLLAMA} \
|
||||
USE_CUDA_DOCKER=${USE_CUDA} \
|
||||
USE_SLIM_DOCKER=${USE_SLIM} \
|
||||
|
|
@ -124,23 +78,31 @@ ENV OPENAI_API_KEY="" \
|
|||
ANONYMIZED_TELEMETRY=false
|
||||
|
||||
#### Other models #########################################################
|
||||
## whisper TTS model settings ##
|
||||
ENV WHISPER_MODEL="base" \
|
||||
WHISPER_MODEL_DIR="/app/backend/data/cache/whisper/models" \
|
||||
RAG_EMBEDDING_MODEL="$USE_EMBEDDING_MODEL_DOCKER" \
|
||||
RAG_RERANKING_MODEL="$USE_RERANKING_MODEL_DOCKER" \
|
||||
SENTENCE_TRANSFORMERS_HOME="/app/backend/data/cache/embedding/models" \
|
||||
TIKTOKEN_ENCODING_NAME="cl100k_base" \
|
||||
TIKTOKEN_CACHE_DIR="/app/backend/data/cache/tiktoken" \
|
||||
HF_HOME="/app/backend/data/cache/embedding/models"
|
||||
WHISPER_MODEL_DIR="/app/backend/data/cache/whisper/models"
|
||||
|
||||
# ========== 配置 Hugging Face 镜像 ==========
|
||||
ENV HF_ENDPOINT=https://hf-mirror.com
|
||||
## RAG Embedding model settings ##
|
||||
ENV RAG_EMBEDDING_MODEL="$USE_EMBEDDING_MODEL_DOCKER" \
|
||||
RAG_RERANKING_MODEL="$USE_RERANKING_MODEL_DOCKER" \
|
||||
SENTENCE_TRANSFORMERS_HOME="/app/backend/data/cache/embedding/models"
|
||||
|
||||
## Tiktoken model settings ##
|
||||
ENV TIKTOKEN_ENCODING_NAME="cl100k_base" \
|
||||
TIKTOKEN_CACHE_DIR="/app/backend/data/cache/tiktoken"
|
||||
|
||||
## Hugging Face download cache ##
|
||||
ENV HF_HOME="/app/backend/data/cache/embedding/models"
|
||||
|
||||
## Torch Extensions ##
|
||||
# ENV TORCH_EXTENSIONS_DIR="/.cache/torch_extensions"
|
||||
|
||||
#### Other models ##########################################################
|
||||
|
||||
WORKDIR /app/backend
|
||||
|
||||
ENV HOME=/root
|
||||
|
||||
# ========== 创建用户和组 ==========
|
||||
# Create user and group if not root
|
||||
RUN if [ $UID -ne 0 ]; then \
|
||||
if [ $GID -ne 0 ]; then \
|
||||
addgroup --gid $GID app; \
|
||||
|
|
@ -148,15 +110,13 @@ RUN if [ $UID -ne 0 ]; then \
|
|||
adduser --uid $UID --gid $GID --home $HOME --disabled-password --no-create-home app; \
|
||||
fi
|
||||
|
||||
RUN mkdir -p $HOME/.cache/chroma && \
|
||||
echo -n 00000000-0000-0000-0000-000000000000 > $HOME/.cache/chroma/telemetry_user_id && \
|
||||
chown -R $UID:$GID /app $HOME
|
||||
RUN mkdir -p $HOME/.cache/chroma
|
||||
RUN echo -n 00000000-0000-0000-0000-000000000000 > $HOME/.cache/chroma/telemetry_user_id
|
||||
|
||||
# ========== 配置 Debian 镜像源 ==========
|
||||
RUN sed -i 's@deb.debian.org@mirrors.aliyun.com@g' /etc/apt/sources.list.d/debian.sources && \
|
||||
sed -i 's@security.debian.org@mirrors.aliyun.com@g' /etc/apt/sources.list.d/debian.sources
|
||||
# Make sure the user has access to the app and root directory
|
||||
RUN chown -R $UID:$GID /app $HOME
|
||||
|
||||
# ========== 安装系统依赖 ==========
|
||||
# Install common system dependencies
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends \
|
||||
git build-essential pandoc gcc netcat-openbsd curl jq \
|
||||
|
|
@ -164,100 +124,56 @@ RUN apt-get update && \
|
|||
ffmpeg libsm6 libxext6 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# ========== 配置 pip 镜像源 ==========
|
||||
RUN pip3 config set global.index-url https://mirrors.aliyun.com/pypi/simple/ && \
|
||||
pip3 config set install.trusted-host mirrors.aliyun.com && \
|
||||
pip3 config set global.timeout 600
|
||||
|
||||
# ========== 配置 uv 使用镜像源 ==========
|
||||
ENV UV_INDEX_URL=https://mirrors.aliyun.com/pypi/simple/ \
|
||||
UV_EXTRA_INDEX_URL="" \
|
||||
UV_NO_CACHE=0
|
||||
|
||||
# ========== 安装 Python 依赖 ==========
|
||||
# install python dependencies
|
||||
COPY --chown=$UID:$GID ./backend/requirements.txt ./requirements.txt
|
||||
|
||||
RUN echo "==================================" && \
|
||||
echo "Installing Python dependencies" && \
|
||||
echo "Time: $(date)" && \
|
||||
echo "==================================" && \
|
||||
pip3 install uv && \
|
||||
RUN pip3 install --no-cache-dir uv && \
|
||||
if [ "$USE_CUDA" = "true" ]; then \
|
||||
echo "Installing PyTorch with CUDA support..." && \
|
||||
pip3 install torch torchvision torchaudio \
|
||||
--index-url https://mirrors.aliyun.com/pypi/simple/ \
|
||||
--trusted-host mirrors.aliyun.com || \
|
||||
(echo "Aliyun failed, trying Tsinghua mirror..." && \
|
||||
pip3 install torch torchvision torchaudio \
|
||||
--index-url https://pypi.tuna.tsinghua.edu.cn/simple/ \
|
||||
--trusted-host pypi.tuna.tsinghua.edu.cn) || \
|
||||
(echo "Mirrors failed, trying official PyTorch repo..." && \
|
||||
pip3 install torch torchvision torchaudio \
|
||||
--index-url https://download.pytorch.org/whl/$USE_CUDA_DOCKER_VER) && \
|
||||
echo "Installing other requirements with uv..." && \
|
||||
uv pip install --system -r requirements.txt \
|
||||
--index-url https://mirrors.aliyun.com/pypi/simple/ && \
|
||||
if [ "$USE_SLIM" != "true" ]; then \
|
||||
echo "Downloading models..." && \
|
||||
python -c "import os; from sentence_transformers import SentenceTransformer; SentenceTransformer(os.environ['RAG_EMBEDDING_MODEL'], device='cpu')" && \
|
||||
python -c "import os; from faster_whisper import WhisperModel; WhisperModel(os.environ['WHISPER_MODEL'], device='cpu', compute_type='int8', download_root=os.environ['WHISPER_MODEL_DIR'])" && \
|
||||
python -c "import os; import tiktoken; tiktoken.get_encoding(os.environ['TIKTOKEN_ENCODING_NAME'])"; \
|
||||
fi; \
|
||||
# If you use CUDA the whisper and embedding model will be downloaded on first use
|
||||
pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/$USE_CUDA_DOCKER_VER --no-cache-dir && \
|
||||
uv pip install --system -r requirements.txt --no-cache-dir && \
|
||||
python -c "import os; from sentence_transformers import SentenceTransformer; SentenceTransformer(os.environ['RAG_EMBEDDING_MODEL'], device='cpu')" && \
|
||||
python -c "import os; from faster_whisper import WhisperModel; WhisperModel(os.environ['WHISPER_MODEL'], device='cpu', compute_type='int8', download_root=os.environ['WHISPER_MODEL_DIR'])"; \
|
||||
python -c "import os; import tiktoken; tiktoken.get_encoding(os.environ['TIKTOKEN_ENCODING_NAME'])"; \
|
||||
else \
|
||||
echo "Installing PyTorch CPU version..." && \
|
||||
pip3 install torch torchvision torchaudio \
|
||||
--index-url https://mirrors.aliyun.com/pypi/simple/ \
|
||||
--trusted-host mirrors.aliyun.com || \
|
||||
(echo "Aliyun failed, trying Tsinghua mirror..." && \
|
||||
pip3 install torch torchvision torchaudio \
|
||||
--index-url https://pypi.tuna.tsinghua.edu.cn/simple/ \
|
||||
--trusted-host pypi.tuna.tsinghua.edu.cn) || \
|
||||
(echo "Tsinghua failed, trying USTC mirror..." && \
|
||||
pip3 install torch torchvision torchaudio \
|
||||
--index-url https://mirrors.ustc.edu.cn/pypi/web/simple/ \
|
||||
--trusted-host mirrors.ustc.edu.cn) || \
|
||||
(echo "All mirrors failed, trying official PyTorch CPU repo..." && \
|
||||
pip3 install torch torchvision torchaudio \
|
||||
--index-url https://download.pytorch.org/whl/cpu) && \
|
||||
echo "Installing other requirements with uv..." && \
|
||||
uv pip install --system -r requirements.txt \
|
||||
--index-url https://mirrors.aliyun.com/pypi/simple/ && \
|
||||
if [ "$USE_SLIM" != "true" ]; then \
|
||||
echo "Downloading models..." && \
|
||||
python -c "import os; from sentence_transformers import SentenceTransformer; SentenceTransformer(os.environ['RAG_EMBEDDING_MODEL'], device='cpu')" && \
|
||||
python -c "import os; from faster_whisper import WhisperModel; WhisperModel(os.environ['WHISPER_MODEL'], device='cpu', compute_type='int8', download_root=os.environ['WHISPER_MODEL_DIR'])" && \
|
||||
python -c "import os; import tiktoken; tiktoken.get_encoding(os.environ['TIKTOKEN_ENCODING_NAME'])"; \
|
||||
fi; \
|
||||
fi && \
|
||||
pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu --no-cache-dir && \
|
||||
uv pip install --system -r requirements.txt --no-cache-dir && \
|
||||
if [ "$USE_SLIM" != "true" ]; then \
|
||||
python -c "import os; from sentence_transformers import SentenceTransformer; SentenceTransformer(os.environ['RAG_EMBEDDING_MODEL'], device='cpu')" && \
|
||||
python -c "import os; from faster_whisper import WhisperModel; WhisperModel(os.environ['WHISPER_MODEL'], device='cpu', compute_type='int8', download_root=os.environ['WHISPER_MODEL_DIR'])"; \
|
||||
python -c "import os; import tiktoken; tiktoken.get_encoding(os.environ['TIKTOKEN_ENCODING_NAME'])"; \
|
||||
fi; \
|
||||
fi; \
|
||||
mkdir -p /app/backend/data && chown -R $UID:$GID /app/backend/data/ && \
|
||||
echo "==================================" && \
|
||||
echo "Python dependencies installed" && \
|
||||
echo "Time: $(date)" && \
|
||||
echo "=================================="
|
||||
rm -rf /var/lib/apt/lists/*;
|
||||
|
||||
# ========== 安装 Ollama ==========
|
||||
# Install Ollama if requested
|
||||
RUN if [ "$USE_OLLAMA" = "true" ]; then \
|
||||
date +%s > /tmp/ollama_build_hash && \
|
||||
echo "Installing Ollama..." && \
|
||||
export HF_ENDPOINT=https://hf-mirror.com && \
|
||||
curl -fsSL https://ollama.com/install.sh | sh || \
|
||||
(echo "Ollama installation failed, trying with proxy..." && \
|
||||
export http_proxy=http://host.docker.internal:7897 && \
|
||||
export https_proxy=http://host.docker.internal:7897 && \
|
||||
curl -fsSL https://ollama.com/install.sh | sh); \
|
||||
echo "Cache broken at timestamp: `cat /tmp/ollama_build_hash`" && \
|
||||
curl -fsSL https://ollama.com/install.sh | sh && \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
fi
|
||||
|
||||
# ========== 复制构建文件 ==========
|
||||
# copy embedding weight from build
|
||||
# RUN mkdir -p /root/.cache/chroma/onnx_models/all-MiniLM-L6-v2
|
||||
# COPY --from=build /app/onnx /root/.cache/chroma/onnx_models/all-MiniLM-L6-v2/onnx
|
||||
|
||||
# copy built frontend files
|
||||
COPY --chown=$UID:$GID --from=build /app/build /app/build
|
||||
COPY --chown=$UID:$GID --from=build /app/CHANGELOG.md /app/CHANGELOG.md
|
||||
COPY --chown=$UID:$GID --from=build /app/package.json /app/package.json
|
||||
|
||||
# copy backend files
|
||||
COPY --chown=$UID:$GID ./backend .
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
HEALTHCHECK CMD curl --silent --fail http://localhost:${PORT:-8080}/health | jq -ne 'input.status == true' || exit 1
|
||||
|
||||
# ========== 权限加固 ==========
|
||||
# Minimal, atomic permission hardening for OpenShift (arbitrary UID):
|
||||
# - Group 0 owns /app and /root
|
||||
# - Directories are group-writable and have SGID so new files inherit GID 0
|
||||
RUN if [ "$USE_PERMISSION_HARDENING" = "true" ]; then \
|
||||
set -eux; \
|
||||
chgrp -R 0 /app /root || true; \
|
||||
|
|
@ -272,4 +188,4 @@ ARG BUILD_HASH
|
|||
ENV WEBUI_BUILD_VERSION=${BUILD_HASH}
|
||||
ENV DOCKER=true
|
||||
|
||||
CMD [ "bash", "start.sh"]
|
||||
CMD [ "bash", "start.sh"]
|
||||
|
|
|
|||
168
Jenkinsfile
vendored
|
|
@ -1,168 +0,0 @@
|
|||
pipeline {
|
||||
agent any
|
||||
|
||||
environment {
|
||||
REPO_URL = 'git@github.com:ai-friend-coming/open-webui-next.git'
|
||||
IMAGE_NAME = 'open-webui-custom'
|
||||
IMAGE_TAG = "${BUILD_NUMBER}"
|
||||
OUTPUT_DIR = '/var/docker-images'
|
||||
DOCKER_FILE_PATH = 'Dockerfile'
|
||||
}
|
||||
|
||||
options {
|
||||
buildDiscarder(logRotator(numToKeepStr: '10'))
|
||||
timeout(time: 1, unit: 'HOURS')
|
||||
timestamps()
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('准备工作') {
|
||||
steps {
|
||||
script {
|
||||
echo "========================================="
|
||||
echo "开始构建 Build #${BUILD_NUMBER}"
|
||||
echo "仓库: ${REPO_URL}"
|
||||
echo "镜像: ${IMAGE_NAME}:${IMAGE_TAG}"
|
||||
echo "========================================="
|
||||
|
||||
// 检查Docker是否可用
|
||||
sh 'docker --version'
|
||||
sh 'docker info'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('检出代码') {
|
||||
steps {
|
||||
script {
|
||||
echo "从 ${REPO_URL} 检出代码..."
|
||||
}
|
||||
|
||||
// 使用更简单的checkout方式
|
||||
checkout([
|
||||
$class: 'GitSCM',
|
||||
branches: [[name: '*/main']],
|
||||
userRemoteConfigs: [[
|
||||
url: "${REPO_URL}",
|
||||
credentialsId: 'github-ssh' // 改成你实际创建的凭据ID
|
||||
]]
|
||||
])
|
||||
|
||||
script {
|
||||
echo "代码检出完成"
|
||||
sh 'ls -la'
|
||||
sh 'git log --oneline -1 || echo "无法获取git日志"'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('验证 Dockerfile') {
|
||||
steps {
|
||||
script {
|
||||
echo "检查 Dockerfile..."
|
||||
sh """
|
||||
if [ ! -f "${DOCKER_FILE_PATH}" ]; then
|
||||
echo "错误: 找不到 Dockerfile: ${DOCKER_FILE_PATH}"
|
||||
echo "当前目录内容:"
|
||||
ls -la
|
||||
exit 1
|
||||
fi
|
||||
echo "Dockerfile 存在"
|
||||
echo "--- Dockerfile 内容 (前20行) ---"
|
||||
head -20 "${DOCKER_FILE_PATH}"
|
||||
"""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('创建输出目录') {
|
||||
steps {
|
||||
script {
|
||||
echo "创建输出目录: ${OUTPUT_DIR}"
|
||||
sh """
|
||||
sudo mkdir -p ${OUTPUT_DIR}
|
||||
sudo chmod 777 ${OUTPUT_DIR}
|
||||
ls -ld ${OUTPUT_DIR}
|
||||
"""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('构建 Docker 镜像') {
|
||||
steps {
|
||||
script {
|
||||
echo "开始构建镜像: ${IMAGE_NAME}:${IMAGE_TAG}"
|
||||
sh """
|
||||
docker build \
|
||||
-t ${IMAGE_NAME}:${IMAGE_TAG} \
|
||||
-t ${IMAGE_NAME}:latest \
|
||||
-f ${DOCKER_FILE_PATH} \
|
||||
.
|
||||
|
||||
echo "镜像构建完成"
|
||||
docker images | grep ${IMAGE_NAME} || echo "未找到镜像"
|
||||
"""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('导出镜像') {
|
||||
steps {
|
||||
script {
|
||||
echo "导出镜像到 ${OUTPUT_DIR}"
|
||||
sh """
|
||||
echo "导出 ${IMAGE_NAME}:${IMAGE_TAG}..."
|
||||
docker save ${IMAGE_NAME}:${IMAGE_TAG} | gzip > ${OUTPUT_DIR}/${IMAGE_NAME}-${IMAGE_TAG}.tar.gz
|
||||
|
||||
echo "导出 ${IMAGE_NAME}:latest..."
|
||||
docker save ${IMAGE_NAME}:latest | gzip > ${OUTPUT_DIR}/${IMAGE_NAME}-latest.tar.gz
|
||||
|
||||
echo "导出完成"
|
||||
ls -lh ${OUTPUT_DIR}/${IMAGE_NAME}*.tar.gz
|
||||
"""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('清理旧镜像') {
|
||||
steps {
|
||||
script {
|
||||
echo "清理本地镜像..."
|
||||
sh """
|
||||
docker rmi ${IMAGE_NAME}:${IMAGE_TAG} 2>/dev/null || echo "镜像已删除或不存在"
|
||||
|
||||
# 保留latest标签,方便下次使用
|
||||
# docker rmi ${IMAGE_NAME}:latest 2>/dev/null || true
|
||||
|
||||
# 清理悬空镜像
|
||||
docker image prune -f --filter "dangling=true" || true
|
||||
|
||||
echo "清理完成"
|
||||
"""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
post {
|
||||
success {
|
||||
script {
|
||||
echo "========================================="
|
||||
echo "✅ 构建成功!"
|
||||
echo "镜像文件位置: ${OUTPUT_DIR}"
|
||||
sh "ls -lh ${OUTPUT_DIR}/${IMAGE_NAME}*.tar.gz || true"
|
||||
echo "========================================="
|
||||
}
|
||||
}
|
||||
failure {
|
||||
echo "❌ 构建失败,请检查上方日志"
|
||||
}
|
||||
always {
|
||||
script {
|
||||
echo "流水线执行完成"
|
||||
// 可选:清理工作空间(注释掉以便调试)
|
||||
// cleanWs()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
291
LOCAL_SETUP.md
|
|
@ -1,291 +0,0 @@
|
|||
# Open WebUI 本地开发环境搭建指南
|
||||
|
||||
本指南提供 Open WebUI 项目的本地开发环境配置和运行步骤。
|
||||
|
||||
## 系统要求
|
||||
|
||||
- **Node.js**: v20.19.5 或更高版本
|
||||
- **Python**: 3.12.x (推荐使用 pyenv 管理)
|
||||
- **npm**: 10.8.2 或更高版本
|
||||
- **操作系统**: macOS / Linux / Windows
|
||||
|
||||
## 技术栈
|
||||
|
||||
### 前端
|
||||
- **框架**: SvelteKit 4 + TypeScript
|
||||
- **构建工具**: Vite 5
|
||||
- **样式**: Tailwind CSS 4
|
||||
|
||||
### 后端
|
||||
- **语言**: Python 3.12
|
||||
- **框架**: FastAPI
|
||||
- **数据库**: SQLite (开发环境) / PostgreSQL (生产环境)
|
||||
- **ORM**: SQLAlchemy + Peewee
|
||||
|
||||
## 环境准备
|
||||
|
||||
### 1. 安装 pyenv (如果系统 Python 版本不是 3.12)
|
||||
|
||||
```bash
|
||||
# macOS (使用 Homebrew)
|
||||
brew install pyenv
|
||||
|
||||
# 配置 shell 环境变量 (添加到 ~/.zshrc 或 ~/.bash_profile)
|
||||
export PATH="$HOME/.pyenv/bin:$PATH"
|
||||
eval "$(pyenv init -)"
|
||||
```
|
||||
|
||||
### 2. 安装 Python 3.12
|
||||
|
||||
```bash
|
||||
# 使用 pyenv 安装 Python 3.12
|
||||
pyenv install 3.12
|
||||
|
||||
# 验证安装
|
||||
pyenv versions
|
||||
```
|
||||
|
||||
## 安装依赖
|
||||
|
||||
### 前端依赖
|
||||
|
||||
```bash
|
||||
# 在项目根目录执行
|
||||
npm install --legacy-peer-deps
|
||||
```
|
||||
|
||||
**注意**: 需要使用 `--legacy-peer-deps` 标志来解决 @tiptap 包的版本冲突问题。
|
||||
|
||||
### 后端依赖
|
||||
|
||||
```bash
|
||||
# 进入后端目录
|
||||
cd backend
|
||||
|
||||
# 创建 Python 3.12 虚拟环境
|
||||
/Users/你的用户名/.pyenv/versions/3.12.12/bin/python3 -m venv venv
|
||||
|
||||
# 或者,如果系统 Python 已是 3.12
|
||||
python3 -m venv venv
|
||||
|
||||
# 激活虚拟环境
|
||||
source venv/bin/activate # macOS/Linux
|
||||
# 或
|
||||
venv\Scripts\activate # Windows
|
||||
|
||||
# 升级 pip
|
||||
pip install --upgrade pip
|
||||
|
||||
# 安装依赖
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
## 运行开发服务器
|
||||
|
||||
### 启动后端服务 (端口 8080)
|
||||
|
||||
```bash
|
||||
# 在 backend 目录下,激活虚拟环境后
|
||||
cd backend
|
||||
source venv/bin/activate
|
||||
python -m uvicorn open_webui.main:app --reload --port 8080 --host 0.0.0.0
|
||||
```
|
||||
|
||||
后端服务将运行在: **http://localhost:8080**
|
||||
|
||||
后端启动时会自动:
|
||||
- 运行数据库迁移 (Alembic)
|
||||
- 初始化 SQLite 数据库
|
||||
- 配置向量数据库 (ChromaDB)
|
||||
|
||||
### 启动前端服务 (端口 5050)
|
||||
|
||||
```bash
|
||||
# 在项目根目录
|
||||
npm run dev:5050
|
||||
```
|
||||
|
||||
前端服务将运行在: **http://localhost:5050**
|
||||
|
||||
首次启动时会自动:
|
||||
- 下载 Pyodide 包 (浏览器内 Python 运行时)
|
||||
- 预加载常用 Python 包 (numpy, pandas, matplotlib 等)
|
||||
|
||||
## 访问应用
|
||||
|
||||
打开浏览器访问: **http://localhost:5050**
|
||||
|
||||
前端会通过 Vite 代理将 API 请求转发到后端 (8080 端口)。
|
||||
|
||||
## 开发工作流
|
||||
|
||||
### 目录结构
|
||||
|
||||
```
|
||||
open-webui-next/
|
||||
├── src/ # 前端源码
|
||||
│ ├── routes/ # SvelteKit 路由
|
||||
│ ├── lib/
|
||||
│ │ ├── apis/ # API 客户端
|
||||
│ │ ├── components/ # Svelte 组件
|
||||
│ │ ├── stores/ # 全局状态管理
|
||||
│ │ └── i18n/ # 国际化
|
||||
├── backend/ # 后端源码
|
||||
│ ├── open_webui/
|
||||
│ │ ├── main.py # FastAPI 入口
|
||||
│ │ ├── routers/ # API 路由
|
||||
│ │ ├── models/ # 数据模型
|
||||
│ │ ├── utils/ # 工具函数
|
||||
│ │ └── migrations/ # 数据库迁移
|
||||
│ ├── requirements.txt
|
||||
│ └── venv/ # Python 虚拟环境
|
||||
└── package.json
|
||||
```
|
||||
|
||||
### 常用开发命令
|
||||
|
||||
#### 前端
|
||||
|
||||
```bash
|
||||
npm run dev # 启动开发服务器 (默认端口 5173)
|
||||
npm run dev:5050 # 启动开发服务器 (端口 5050)
|
||||
npm run build # 构建生产版本
|
||||
npm run lint # 代码检查
|
||||
npm run format # 代码格式化
|
||||
npm run test:frontend # 运行单元测试
|
||||
npm run i18n:parse # 解析并更新翻译文件
|
||||
```
|
||||
|
||||
#### 后端
|
||||
|
||||
```bash
|
||||
# 在 backend 目录下,激活虚拟环境后
|
||||
|
||||
# 启动开发服务器 (自动重载)
|
||||
python -m uvicorn open_webui.main:app --reload --port 8080
|
||||
|
||||
# 代码格式化
|
||||
black .
|
||||
|
||||
# 数据库迁移
|
||||
cd backend
|
||||
alembic revision --autogenerate -m "描述" # 生成迁移脚本
|
||||
alembic upgrade head # 执行迁移
|
||||
```
|
||||
|
||||
### 热重载
|
||||
|
||||
- **前端**: Vite 自动检测文件变化并热重载
|
||||
- **后端**: uvicorn 的 `--reload` 参数自动检测 Python 代码变化并重启
|
||||
|
||||
## 常见问题
|
||||
|
||||
### 1. npm install 失败
|
||||
|
||||
**问题**: 依赖版本冲突
|
||||
|
||||
**解决方案**:
|
||||
```bash
|
||||
npm install --legacy-peer-deps
|
||||
```
|
||||
|
||||
### 2. 后端 Python 版本不兼容
|
||||
|
||||
**问题**: `unstructured` 包不支持 Python 3.13+
|
||||
|
||||
**解决方案**: 使用 Python 3.12:
|
||||
```bash
|
||||
pyenv install 3.12
|
||||
cd backend
|
||||
rm -rf venv
|
||||
/Users/你的用户名/.pyenv/versions/3.12.12/bin/python3 -m venv venv
|
||||
source venv/bin/activate
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
### 3. 端口被占用
|
||||
|
||||
**问题**: 8080 或 5050 端口已被使用
|
||||
|
||||
**解决方案**:
|
||||
```bash
|
||||
# 查找占用端口的进程
|
||||
lsof -i :8080
|
||||
lsof -i :5050
|
||||
|
||||
# 终止进程
|
||||
kill -9 <PID>
|
||||
|
||||
# 或者使用不同端口
|
||||
# 前端:
|
||||
npm run dev -- --port 3000
|
||||
|
||||
# 后端:
|
||||
python -m uvicorn open_webui.main:app --reload --port 8000
|
||||
```
|
||||
|
||||
### 4. 前端 Pyodide 下载慢
|
||||
|
||||
**问题**: 首次启动下载 Pyodide 包较慢
|
||||
|
||||
**解决方案**: 耐心等待,包会缓存在 `node_modules` 中,后续启动会很快。
|
||||
|
||||
### 5. 数据库迁移错误
|
||||
|
||||
**问题**: Alembic 迁移失败
|
||||
|
||||
**解决方案**:
|
||||
```bash
|
||||
# 删除数据库重新初始化 (仅开发环境)
|
||||
rm backend/data/webui.db
|
||||
python -m uvicorn open_webui.main:app --reload --port 8080
|
||||
```
|
||||
|
||||
## 环境变量配置
|
||||
|
||||
后端可通过环境变量配置,创建 `backend/.env` 文件:
|
||||
|
||||
```bash
|
||||
# 数据库
|
||||
DATABASE_URL=sqlite:///data/webui.db
|
||||
|
||||
# 向量数据库
|
||||
VECTOR_DB=chroma
|
||||
EMBEDDING_MODEL=sentence-transformers/all-MiniLM-L6-v2
|
||||
|
||||
# CORS (开发环境)
|
||||
CORS_ALLOW_ORIGIN=*
|
||||
|
||||
# 日志级别
|
||||
LOG_LEVEL=INFO
|
||||
```
|
||||
|
||||
## 生产部署
|
||||
|
||||
生产环境使用 Docker 部署,详见项目根目录的 `Dockerfile` 和 `docker-compose.yaml`。
|
||||
|
||||
```bash
|
||||
# 构建镜像
|
||||
docker build -t open-webui .
|
||||
|
||||
# 运行容器
|
||||
docker run -d -p 8080:8080 -v open-webui:/app/backend/data open-webui
|
||||
```
|
||||
|
||||
## 更多资源
|
||||
|
||||
- **项目文档**: [CLAUDE.md](./CLAUDE.md)
|
||||
- **API 文档**: http://localhost:8080/docs (启动后端后访问)
|
||||
- **官方仓库**: https://github.com/open-webui/open-webui
|
||||
|
||||
## 贡献指南
|
||||
|
||||
1. Fork 项目
|
||||
2. 创建功能分支 (`git checkout -b feature/AmazingFeature`)
|
||||
3. 提交更改 (`git commit -m 'Add some AmazingFeature'`)
|
||||
4. 推送到分支 (`git push origin feature/AmazingFeature`)
|
||||
5. 创建 Pull Request
|
||||
|
||||
---
|
||||
|
||||
**最后更新**: 2025-11-08
|
||||
|
|
@ -1,88 +1,36 @@
|
|||
# 本地开发故障排除
|
||||
# Open WebUI Troubleshooting Guide
|
||||
|
||||
## 问题: "Open WebUI 需要后端服务" 错误
|
||||
## Understanding the Open WebUI Architecture
|
||||
|
||||
### 🔧 快速解决方案
|
||||
The Open WebUI system is designed to streamline interactions between the client (your browser) and the Ollama API. At the heart of this design is a backend reverse proxy, enhancing security and resolving CORS issues.
|
||||
|
||||
**请在浏览器中进行硬刷新:**
|
||||
- **How it Works**: The Open WebUI is designed to interact with the Ollama API through a specific route. When a request is made from the WebUI to Ollama, it is not directly sent to the Ollama API. Initially, the request is sent to the Open WebUI backend via `/ollama` route. From there, the backend is responsible for forwarding the request to the Ollama API. This forwarding is accomplished by using the route specified in the `OLLAMA_BASE_URL` environment variable. Therefore, a request made to `/ollama` in the WebUI is effectively the same as making a request to `OLLAMA_BASE_URL` in the backend. For instance, a request to `/ollama/api/tags` in the WebUI is equivalent to `OLLAMA_BASE_URL/api/tags` in the backend.
|
||||
|
||||
- **macOS**: `Cmd + Shift + R`
|
||||
- **Windows/Linux**: `Ctrl + Shift + R`
|
||||
- **Security Benefits**: This design prevents direct exposure of the Ollama API to the frontend, safeguarding against potential CORS (Cross-Origin Resource Sharing) issues and unauthorized access. Requiring authentication to access the Ollama API further enhances this security layer.
|
||||
|
||||
然后检查是否解决问题。
|
||||
## Open WebUI: Server Connection Error
|
||||
|
||||
### 📋 详细排查步骤
|
||||
If you're experiencing connection issues, it’s often due to the WebUI docker container not being able to reach the Ollama server at 127.0.0.1:11434 (host.docker.internal:11434) inside the container . Use the `--network=host` flag in your docker command to resolve this. Note that the port changes from 3000 to 8080, resulting in the link: `http://localhost:8080`.
|
||||
|
||||
#### 1. 打开浏览器开发者工具
|
||||
|
||||
- **macOS**: `Cmd + Option + I`
|
||||
- **Windows/Linux**: `F12`
|
||||
|
||||
#### 2. 检查 Console (控制台)
|
||||
|
||||
查找是否有错误消息,特别是:
|
||||
- 红色的错误信息
|
||||
- 网络请求失败
|
||||
- CORS 相关错误
|
||||
|
||||
#### 3. 检查 Network (网络) 标签
|
||||
|
||||
1. 切换到 Network 标签
|
||||
2. 刷新页面
|
||||
3. 查找对 `http://localhost:8080/api/config` 的请求
|
||||
4. 如果找到,点击查看:
|
||||
- **Status** 应该是 `200`
|
||||
- **Response** 应该包含 JSON 配置
|
||||
|
||||
#### 4. 清除本地存储
|
||||
|
||||
1. 在开发者工具中,转到 **Application** 标签
|
||||
2. 左侧找到 **Local Storage**
|
||||
3. 展开并点击 `http://localhost:5050`
|
||||
4. 点击右键 → **Clear**
|
||||
5. 刷新页面
|
||||
|
||||
### ✅ 验证服务状态
|
||||
|
||||
在终端运行:
|
||||
**Example Docker Command**:
|
||||
|
||||
```bash
|
||||
# 测试后端 API
|
||||
curl http://localhost:8080/api/config
|
||||
|
||||
# 检查端口占用
|
||||
lsof -i :8080 -i :5050 | grep LISTEN
|
||||
docker run -d --network=host -v open-webui:/app/backend/data -e OLLAMA_BASE_URL=http://127.0.0.1:11434 --name open-webui --restart always ghcr.io/open-webui/open-webui:main
|
||||
```
|
||||
|
||||
如果 curl 命令返回 JSON 配置,说明后端正常运行。
|
||||
### Error on Slow Responses for Ollama
|
||||
|
||||
### 🔄 重启服务 (如果需要)
|
||||
Open WebUI has a default timeout of 5 minutes for Ollama to finish generating the response. If needed, this can be adjusted via the environment variable AIOHTTP_CLIENT_TIMEOUT, which sets the timeout in seconds.
|
||||
|
||||
如果上述方法无效,停止当前服务 (`Ctrl + C`) 并重新启动:
|
||||
### General Connection Errors
|
||||
|
||||
**后端:**
|
||||
```bash
|
||||
cd backend
|
||||
source venv/bin/activate
|
||||
python -m uvicorn open_webui.main:app --reload --port 8080 --host 0.0.0.0
|
||||
```
|
||||
**Ensure Ollama Version is Up-to-Date**: Always start by checking that you have the latest version of Ollama. Visit [Ollama's official site](https://ollama.com/) for the latest updates.
|
||||
|
||||
**前端:**
|
||||
```bash
|
||||
npm run dev:5050
|
||||
```
|
||||
**Troubleshooting Steps**:
|
||||
|
||||
### 🌐 尝试不同端口
|
||||
1. **Verify Ollama URL Format**:
|
||||
- When running the Web UI container, ensure the `OLLAMA_BASE_URL` is correctly set. (e.g., `http://192.168.1.1:11434` for different host setups).
|
||||
- In the Open WebUI, navigate to "Settings" > "General".
|
||||
- Confirm that the Ollama Server URL is correctly set to `[OLLAMA URL]` (e.g., `http://localhost:11434`).
|
||||
|
||||
如果端口冲突,可以使用不同端口:
|
||||
|
||||
**前端:**
|
||||
```bash
|
||||
npm run dev -- --port 3000
|
||||
```
|
||||
|
||||
然后访问 `http://localhost:3000`
|
||||
|
||||
---
|
||||
|
||||
**还有问题?** 查看 `/Users/sylar/my_ws/open-webui-next/LOCAL_SETUP.md` 获取完整设置指南。
|
||||
By following these enhanced troubleshooting steps, connection issues should be effectively resolved. For further assistance or queries, feel free to reach out to us on our community Discord.
|
||||
|
|
|
|||
BIN
backend/open_webui/static/apple-touch-icon.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
0
backend/open_webui/static/custom.css
Normal file
BIN
backend/open_webui/static/favicon-96x96.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
backend/open_webui/static/favicon-dark.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
backend/open_webui/static/favicon.ico
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
backend/open_webui/static/favicon.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
3
backend/open_webui/static/favicon.svg
Normal file
|
After Width: | Height: | Size: 14 KiB |
0
backend/open_webui/static/loader.js
Normal file
BIN
backend/open_webui/static/logo.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
21
backend/open_webui/static/site.webmanifest
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"name": "Open WebUI",
|
||||
"short_name": "WebUI",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/static/web-app-manifest-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png",
|
||||
"purpose": "maskable"
|
||||
},
|
||||
{
|
||||
"src": "/static/web-app-manifest-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png",
|
||||
"purpose": "maskable"
|
||||
}
|
||||
],
|
||||
"theme_color": "#ffffff",
|
||||
"background_color": "#ffffff",
|
||||
"display": "standalone"
|
||||
}
|
||||
BIN
backend/open_webui/static/splash-dark.png
Normal file
|
After Width: | Height: | Size: 5.3 KiB |
BIN
backend/open_webui/static/splash.png
Normal file
|
After Width: | Height: | Size: 5.1 KiB |
1
backend/open_webui/static/user-import.csv
Normal file
|
|
@ -0,0 +1 @@
|
|||
Name,Email,Password,Role
|
||||
|
BIN
backend/open_webui/static/user.png
Normal file
|
After Width: | Height: | Size: 7.7 KiB |
BIN
backend/open_webui/static/web-app-manifest-192x192.png
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
BIN
backend/open_webui/static/web-app-manifest-512x512.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
646
package-lock.json
generated
|
|
@ -141,7 +141,6 @@
|
|||
"vega-lite": "^6.4.1",
|
||||
"vite-plugin-static-copy": "^2.2.0",
|
||||
"y-prosemirror": "^1.3.7",
|
||||
"y-protocols": "^1.0.6",
|
||||
"yaml": "^2.7.1",
|
||||
"yjs": "^13.6.27"
|
||||
},
|
||||
|
|
|
|||