# Open WebUI Docker 生产环境部署指南 本指南介绍如何在生产环境中部署 Open WebUI Docker 镜像,并连接到外部 MySQL 数据库。 ## 目录 - [镜像说明](#镜像说明) - [镜像获取方式](#镜像获取方式) - [前置准备](#前置准备) - [快速开始](#快速开始) - [MySQL 数据库配置](#mysql-数据库配置) - [环境变量完整列表](#环境变量完整列表) - [高级配置](#高级配置) - [故障排查](#故障排查) --- ## 镜像说明 ### 镜像仓库 ``` ghcr.io//open-webui-next:slim ``` ### 镜像特性 - **架构**: linux/amd64 (x86_64) - **变体**: Slim 精简版(不预装 AI 模型,首次运行时自动下载) - **包含**: 前端 (SvelteKit) + 后端 (FastAPI) - **不包含**: 数据库服务(需要外部 MySQL) ### 镜像标签规则 | 标签 | 说明 | 示例 | |------|------|------| | `slim` | 主分支最新精简版 | `ghcr.io/user/repo:slim` | | `main-slim` | 主分支最新构建 | `ghcr.io/user/repo:main-slim` | | `v1.2.3-slim` | 版本标签 | `ghcr.io/user/repo:v1.2.3-slim` | | `git-abc1234-slim` | Git commit SHA | `ghcr.io/user/repo:git-abc1234-slim` | --- ## 镜像获取方式 ### 从 GitHub Container Registry (GHCR) 拉取 #### 方式一:拉取公开镜像(推荐) 如果仓库是公开的,直接拉取即可: ```bash # 拉取最新 slim 版本 docker pull ghcr.io//open-webui-next:slim # 拉取特定版本标签 docker pull ghcr.io//open-webui-next:v1.2.3-slim # 拉取特定 Git commit docker pull ghcr.io//open-webui-next:git-abc1234-slim ``` 验证镜像拉取成功: ```bash # 查看本地镜像列表 docker images | grep open-webui-next # 查看镜像详细信息 docker inspect ghcr.io//open-webui-next:slim ``` #### 方式二:拉取私有镜像(需要认证) 如果仓库是私有的,需要先登录 GHCR: **步骤 1: 创建 GitHub Personal Access Token (PAT)** 1. 访问 GitHub Settings → Developer settings → Personal access tokens → Tokens (classic) 2. 点击 "Generate new token (classic)" 3. 设置以下权限: - `read:packages` - 读取容器镜像 - `write:packages` - (可选) 推送镜像 4. 生成并保存 Token (只显示一次) **步骤 2: 登录 GHCR** ```bash # 使用 PAT 登录 echo "YOUR_PERSONAL_ACCESS_TOKEN" | docker login ghcr.io -u YOUR_GITHUB_USERNAME --password-stdin # 或交互式输入密码 docker login ghcr.io -u YOUR_GITHUB_USERNAME # Password: [输入 PAT] ``` 登录成功后会显示: ``` Login Succeeded ``` **步骤 3: 拉取镜像** ```bash docker pull ghcr.io//open-webui-next:slim ``` **步骤 4: 退出登录(可选)** ```bash docker logout ghcr.io ``` ### 生产服务器部署流程 #### 场景一:单服务器部署 ```bash # 1. SSH 登录生产服务器 ssh user@production-server # 2. 登录 GHCR (如果是私有仓库) echo "YOUR_PAT" | docker login ghcr.io -u YOUR_USERNAME --password-stdin # 3. 拉取最新镜像 docker pull ghcr.io//open-webui-next:slim # 4. 停止旧容器 (如果存在) docker stop open-webui || true docker rm open-webui || true # 5. 启动新容器 docker run -d \ --name open-webui \ --restart unless-stopped \ -p 8080:8080 \ -e DATABASE_URL="mysql://..." \ -v /data/open-webui/data:/app/backend/data \ ghcr.io//open-webui-next:slim # 6. 验证部署 docker ps | grep open-webui curl -f http://localhost:8080/health || echo "Health check failed" ``` #### 场景二:CI/CD 自动化部署 **GitHub Actions 自动部署示例**: ```yaml # .github/workflows/deploy.yml name: Deploy to Production on: workflow_run: workflows: ["Build and Push Docker Image (Production)"] types: - completed jobs: deploy: runs-on: ubuntu-latest if: ${{ github.event.workflow_run.conclusion == 'success' }} steps: - name: Deploy to server uses: appleboy/ssh-action@v1.0.0 with: host: ${{ secrets.PROD_SERVER_HOST }} username: ${{ secrets.PROD_SERVER_USER }} key: ${{ secrets.PROD_SERVER_SSH_KEY }} script: | # 拉取最新镜像 docker pull ghcr.io/${{ github.repository }}:slim # 滚动更新 docker stop open-webui || true docker rm open-webui || true docker run -d \ --name open-webui \ --restart unless-stopped \ -p 8080:8080 \ --env-file /opt/openwebui/.env \ -v /data/open-webui/data:/app/backend/data \ ghcr.io/${{ github.repository }}:slim # 健康检查 sleep 10 docker ps | grep open-webui curl -f http://localhost:8080/health ``` #### 场景三:多服务器部署(使用镜像同步) 如果有多台服务器,可以先拉取到一台,然后导出/导入: ```bash # 服务器 A: 从 GHCR 拉取 docker pull ghcr.io//open-webui-next:slim # 导出镜像到文件 docker save ghcr.io//open-webui-next:slim | gzip > open-webui-slim.tar.gz # 传输到其他服务器 scp open-webui-slim.tar.gz user@server-b:/tmp/ scp open-webui-slim.tar.gz user@server-c:/tmp/ # 服务器 B/C: 导入镜像 gunzip -c /tmp/open-webui-slim.tar.gz | docker load ``` ### 镜像更新策略 #### 自动更新(使用 Watchtower) ```bash # 部署 Watchtower 容器监控镜像更新 docker run -d \ --name watchtower \ --restart unless-stopped \ -v /var/run/docker.sock:/var/run/docker.sock \ containrrr/watchtower \ --interval 3600 \ --cleanup \ open-webui ``` Watchtower 会每小时检查一次 `open-webui` 容器的镜像更新,如果有新版本会自动拉取并重启容器。 #### 手动更新(推荐生产环境) ```bash # 1. 拉取最新镜像 docker pull ghcr.io//open-webui-next:slim # 2. 检查镜像是否有更新 OLD_ID=$(docker inspect --format='{{.Image}}' open-webui) NEW_ID=$(docker inspect --format='{{.Id}}' ghcr.io//open-webui-next:slim) if [ "$OLD_ID" != "$NEW_ID" ]; then echo "New image available, updating..." # 3. 备份当前容器配置 docker inspect open-webui > /backup/open-webui-config-$(date +%Y%m%d).json # 4. 停止并删除旧容器 docker stop open-webui docker rm open-webui # 5. 启动新容器 docker run -d \ --name open-webui \ --restart unless-stopped \ -p 8080:8080 \ --env-file /opt/openwebui/.env \ -v /data/open-webui/data:/app/backend/data \ ghcr.io//open-webui-next:slim # 6. 清理旧镜像 docker image prune -f else echo "Already up to date" fi ``` ### 镜像访问故障排查 #### 问题 1: 拉取失败 - 认证错误 ``` Error response from daemon: unauthorized: authentication required ``` **解决方案**: - 检查是否已登录: `docker info | grep Username` - 重新登录: `docker login ghcr.io -u YOUR_USERNAME` - 确认 PAT 有 `read:packages` 权限 - 确认仓库可见性(公开/私有) #### 问题 2: 拉取失败 - 网络超时 ``` Error response from daemon: Get https://ghcr.io/v2/: dial tcp: i/o timeout ``` **解决方案**: ```bash # 检查 DNS 解析 nslookup ghcr.io # 检查网络连接 ping ghcr.io curl -I https://ghcr.io # 配置 Docker 镜像代理(如果在国内服务器) # /etc/docker/daemon.json { "registry-mirrors": [ "https://mirror.gcr.io" ] } # 重启 Docker sudo systemctl restart docker ``` #### 问题 3: 拉取失败 - 镜像不存在 ``` Error response from daemon: manifest for ghcr.io/user/repo:slim not found ``` **解决方案**: - 确认镜像名称和标签拼写正确 - 检查 GitHub Actions 构建是否成功 - 查看仓库 Packages 页面确认镜像已发布 - 使用 `docker search ghcr.io/` 搜索可用镜像 #### 问题 4: 权限不足 ``` Error response from daemon: pull access denied for ghcr.io/user/repo ``` **解决方案**: - 确认 GitHub 用户有仓库访问权限 - 如果是组织仓库,确认用户在组织中 - 管理员在仓库 Settings → Actions → General → Workflow permissions 中启用 "Read and write permissions" --- ## 前置准备 ### 1. MySQL 数据库准备 在您的 MySQL 服务器上创建数据库和用户: ```sql -- 创建数据库 CREATE DATABASE openwebui CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -- 创建用户并授权(替换密码) CREATE USER 'openwebui'@'%' IDENTIFIED BY 'your_secure_password'; GRANT ALL PRIVILEGES ON openwebui.* TO 'openwebui'@'%'; FLUSH PRIVILEGES; -- 验证创建 SHOW DATABASES LIKE 'openwebui'; SELECT User, Host FROM mysql.user WHERE User = 'openwebui'; ``` **安全建议**: - 生产环境使用强密码(至少 16 位,包含大小写字母、数字、特殊字符) - 如果 MySQL 和 Docker 在同一网络,限制 `Host` 为具体 IP 而非 `%` - 启用 MySQL SSL 连接(见高级配置) ### 2. 网络连通性检查 确保 Docker 容器可以访问 MySQL 服务器: ```bash # 在 Docker 宿主机测试 MySQL 连接 mysql -h -P 3306 -u openwebui -p # 或使用 telnet 测试端口 telnet 3306 ``` ### 3. 数据持久化目录 创建用于挂载的数据目录: ```bash mkdir -p /data/open-webui/data chmod 755 /data/open-webui/data ``` --- ## 快速开始 ### 方式一:使用环境变量(推荐) ```bash docker run -d \ --name open-webui \ --restart unless-stopped \ -p 8080:8080 \ -e DATABASE_URL="mysql://openwebui:your_secure_password@mysql.example.com:3306/openwebui" \ -v /data/open-webui/data:/app/backend/data \ ghcr.io//open-webui-next:slim ``` ### 方式二:使用分离的数据库环境变量 ```bash docker run -d \ --name open-webui \ --restart unless-stopped \ -p 8080:8080 \ -e DATABASE_TYPE="mysql" \ -e DATABASE_HOST="mysql.example.com" \ -e DATABASE_PORT="3306" \ -e DATABASE_NAME="openwebui" \ -e DATABASE_USER="openwebui" \ -e DATABASE_PASSWORD="your_secure_password" \ -v /data/open-webui/data:/app/backend/data \ ghcr.io//open-webui-next:slim ``` ### 方式三:使用 .env 文件(推荐生产环境) 创建 `.env` 文件: ```bash # .env DATABASE_URL=mysql://openwebui:your_secure_password@mysql.example.com:3306/openwebui WEBUI_NAME=Open WebUI Production WEBUI_SECRET_KEY=your_random_secret_key_here ``` 运行容器: ```bash docker run -d \ --name open-webui \ --restart unless-stopped \ -p 8080:8080 \ --env-file .env \ -v /data/open-webui/data:/app/backend/data \ ghcr.io//open-webui-next:slim ``` --- ## MySQL 数据库配置 ### 数据库连接方式 #### 选项 1: 使用完整 DATABASE_URL(推荐) ```bash # 标准 MySQL 连接 DATABASE_URL=mysql://username:password@host:port/database # 带参数的连接(UTF-8 编码) DATABASE_URL=mysql://username:password@host:port/database?charset=utf8mb4 # MySQL 8.0+ 使用 PyMySQL 驱动 DATABASE_URL=mysql+pymysql://username:password@host:port/database # SSL 连接 DATABASE_URL=mysql://username:password@host:port/database?ssl=true ``` #### 选项 2: 使用分离的环境变量 ```bash DATABASE_TYPE=mysql # 数据库类型 DATABASE_HOST=mysql.example.com # 主机地址 DATABASE_PORT=3306 # 端口 DATABASE_NAME=openwebui # 数据库名 DATABASE_USER=openwebui # 用户名 DATABASE_PASSWORD=password # 密码 ``` ### 支持的数据库类型 | 数据库 | DATABASE_TYPE | 驱动 | 示例 URL | |--------|---------------|------|----------| | MySQL 5.7+ | `mysql` | mysqlclient | `mysql://user:pass@host/db` | | MySQL 8.0+ | `mysql+pymysql` | pymysql | `mysql+pymysql://user:pass@host/db` | | PostgreSQL | `postgresql` | psycopg2 | `postgresql://user:pass@host/db` | | SQLite | `sqlite` | 内置 | `sqlite:///path/to/db.db` | ### 数据库性能优化 #### 连接池配置 ```bash # 连接池大小(默认:10) DATABASE_POOL_SIZE=20 # 最大溢出连接数(默认:0) DATABASE_POOL_MAX_OVERFLOW=10 # 连接回收时间(秒,防止断线) DATABASE_POOL_RECYCLE=3600 # 连接超时时间(秒) DATABASE_CONNECT_TIMEOUT=10 ``` #### MySQL 特定优化 在 MySQL 服务器配置文件 `my.cnf` 中: ```ini [mysqld] # 连接数限制 max_connections = 500 # InnoDB 缓冲池大小(推荐物理内存的 50-70%) innodb_buffer_pool_size = 2G # 字符集 character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci # 二进制日志(用于备份和恢复) log_bin = /var/log/mysql/mysql-bin.log expire_logs_days = 7 ``` --- ## 环境变量完整列表 ### 数据库配置 | 环境变量 | 说明 | 默认值 | 示例 | |---------|------|--------|------| | `DATABASE_URL` | 完整数据库连接 URL | `sqlite:///{DATA_DIR}/webui.db` | `mysql://user:pass@host/db` | | `DATABASE_TYPE` | 数据库类型 | - | `mysql`, `postgresql` | | `DATABASE_HOST` | 数据库主机 | - | `mysql.example.com` | | `DATABASE_PORT` | 数据库端口 | - | `3306` | | `DATABASE_NAME` | 数据库名称 | - | `openwebui` | | `DATABASE_USER` | 数据库用户名 | - | `openwebui` | | `DATABASE_PASSWORD` | 数据库密码 | - | `password` | | `DATABASE_SCHEMA` | 数据库 Schema | - | `public` | | `DATABASE_POOL_SIZE` | 连接池大小 | `10` | `20` | | `DATABASE_POOL_MAX_OVERFLOW` | 最大溢出连接 | `0` | `10` | ### 应用基础配置 | 环境变量 | 说明 | 默认值 | 示例 | |---------|------|--------|------| | `WEBUI_NAME` | 应用名称 | `Open WebUI` | `My AI Platform` | | `WEBUI_URL` | 外部访问 URL | `http://localhost:8080` | `https://ai.example.com` | | `WEBUI_SECRET_KEY` | JWT 密钥(必须设置) | 自动生成 | 随机字符串 | | `PORT` | 服务端口 | `8080` | `8080` | | `HOST` | 监听地址 | `0.0.0.0` | `0.0.0.0` | | `DATA_DIR` | 数据目录 | `/app/backend/data` | - | ### 认证与安全 | 环境变量 | 说明 | 默认值 | 示例 | |---------|------|--------|------| | `WEBUI_AUTH` | 启用认证 | `true` | `true`, `false` | | `WEBUI_AUTH_TRUSTED_EMAIL_HEADER` | 信任的邮箱 Header | - | `X-User-Email` | | `DEFAULT_USER_ROLE` | 默认用户角色 | `pending` | `user`, `admin` | | `ENABLE_SIGNUP` | 允许注册 | `true` | `true`, `false` | | `JWT_EXPIRES_IN` | JWT 过期时间 | `30d` | `7d`, `24h` | ### LLM 提供商配置 | 环境变量 | 说明 | 默认值 | |---------|------|--------| | `OPENAI_API_BASE_URL` | OpenAI API 基础 URL | `https://api.openai.com/v1` | | `OPENAI_API_KEY` | OpenAI API 密钥 | - | | `OLLAMA_BASE_URL` | Ollama 服务地址 | `http://localhost:11434` | | `ANTHROPIC_API_KEY` | Claude API 密钥 | - | | `GOOGLE_API_KEY` | Gemini API 密钥 | - | ### RAG(向量数据库)配置 | 环境变量 | 说明 | 默认值 | |---------|------|--------| | `VECTOR_DB` | 向量数据库类型 | `chroma` | | `CHROMA_DATA_PATH` | ChromaDB 数据路径 | `{DATA_DIR}/vector_db` | | `QDRANT_URI` | Qdrant 连接地址 | - | | `OPENSEARCH_URI` | OpenSearch 连接地址 | - | ### 日志配置 | 环境变量 | 说明 | 默认值 | |---------|------|--------| | `GLOBAL_LOG_LEVEL` | 全局日志级别 | `INFO` | | `LOG_LEVEL` | 应用日志级别 | `INFO` | | `UVICORN_LOG_LEVEL` | Uvicorn 日志级别 | `info` | --- ## 高级配置 ### 1. 使用 Docker Compose(推荐) 创建 `docker-compose.yml`: ```yaml version: '3.8' services: open-webui: image: ghcr.io//open-webui-next:slim container_name: open-webui restart: unless-stopped ports: - "8080:8080" environment: # 数据库配置 DATABASE_URL: mysql://openwebui:${DB_PASSWORD}@mysql.example.com:3306/openwebui # 应用配置 WEBUI_NAME: "Open WebUI Production" WEBUI_SECRET_KEY: ${WEBUI_SECRET_KEY} WEBUI_URL: https://ai.example.com # 认证配置 ENABLE_SIGNUP: "false" DEFAULT_USER_ROLE: "pending" # LLM 配置 OPENAI_API_KEY: ${OPENAI_API_KEY} OLLAMA_BASE_URL: http://ollama:11434 # 日志配置 GLOBAL_LOG_LEVEL: INFO volumes: - /data/open-webui/data:/app/backend/data # 健康检查 healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/health"] interval: 30s timeout: 10s retries: 3 start_period: 40s # 资源限制 deploy: resources: limits: cpus: '2' memory: 4G reservations: cpus: '1' memory: 2G # 可选:如果需要在同一网络部署 Ollama ollama: image: ollama/ollama:latest container_name: ollama restart: unless-stopped volumes: - /data/ollama:/root/.ollama deploy: resources: limits: memory: 8G ``` 创建 `.env` 文件(不要提交到 Git): ```bash # .env DB_PASSWORD=your_secure_mysql_password WEBUI_SECRET_KEY=your_random_secret_key_here OPENAI_API_KEY=sk-your-openai-key ``` 启动服务: ```bash docker-compose up -d ``` ### 2. MySQL SSL 连接 如果 MySQL 启用了 SSL,配置连接: ```bash # 方式 1: 在 DATABASE_URL 中指定 DATABASE_URL="mysql://user:pass@host/db?ssl=true&ssl_ca=/path/to/ca-cert.pem" # 方式 2: 使用环境变量 DATABASE_SSL=true DATABASE_SSL_CA=/path/to/ca-cert.pem DATABASE_SSL_CERT=/path/to/client-cert.pem DATABASE_SSL_KEY=/path/to/client-key.pem ``` 挂载证书到容器: ```bash docker run -d \ -v /path/to/certs:/certs:ro \ -e DATABASE_URL="mysql://user:pass@host/db?ssl_ca=/certs/ca-cert.pem" \ ghcr.io//open-webui-next:slim ``` ### 3. 反向代理(Nginx) 生产环境推荐在 Docker 前配置 Nginx 反向代理: ```nginx # /etc/nginx/sites-available/openwebui upstream open_webui { server 127.0.0.1:8080; } server { listen 80; server_name ai.example.com; # HTTPS 重定向 return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; server_name ai.example.com; # SSL 证书 ssl_certificate /etc/nginx/ssl/cert.pem; ssl_certificate_key /etc/nginx/ssl/key.pem; # SSL 配置 ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; # 日志 access_log /var/log/nginx/openwebui_access.log; error_log /var/log/nginx/openwebui_error.log; # 客户端最大请求体大小(上传文件) client_max_body_size 100M; location / { proxy_pass http://open_webui; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # WebSocket 支持(用于实时聊天) proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; # 超时配置 proxy_connect_timeout 60s; proxy_send_timeout 300s; proxy_read_timeout 300s; } } ``` 启用配置: ```bash sudo ln -s /etc/nginx/sites-available/openwebui /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl reload nginx ``` ### 4. 数据备份策略 #### MySQL 数据库备份 ```bash #!/bin/bash # backup-mysql.sh BACKUP_DIR="/backup/mysql" DATE=$(date +%Y%m%d_%H%M%S) BACKUP_FILE="$BACKUP_DIR/openwebui_$DATE.sql.gz" # 创建备份目录 mkdir -p $BACKUP_DIR # 备份数据库 mysqldump -h mysql.example.com -u openwebui -p openwebui | gzip > $BACKUP_FILE # 删除 7 天前的备份 find $BACKUP_DIR -name "openwebui_*.sql.gz" -mtime +7 -delete echo "Backup completed: $BACKUP_FILE" ``` 设置 cron 定时任务: ```bash # 每天凌晨 2 点备份 0 2 * * * /path/to/backup-mysql.sh ``` #### 数据目录备份 ```bash #!/bin/bash # backup-data.sh BACKUP_DIR="/backup/openwebui" DATE=$(date +%Y%m%d_%H%M%S) DATA_DIR="/data/open-webui/data" mkdir -p $BACKUP_DIR # 备份数据目录(包含上传的文件、模型等) tar -czf "$BACKUP_DIR/data_$DATE.tar.gz" -C "$DATA_DIR" . # 删除 30 天前的备份 find $BACKUP_DIR -name "data_*.tar.gz" -mtime +30 -delete echo "Data backup completed: $BACKUP_DIR/data_$DATE.tar.gz" ``` ### 5. 监控与告警 #### 健康检查脚本 ```bash #!/bin/bash # healthcheck.sh HEALTH_URL="http://localhost:8080/health" MAX_RETRIES=3 RETRY_COUNT=0 while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" $HEALTH_URL) if [ $HTTP_CODE -eq 200 ]; then echo "Health check passed" exit 0 fi RETRY_COUNT=$((RETRY_COUNT + 1)) sleep 5 done echo "Health check failed after $MAX_RETRIES retries" exit 1 ``` #### Docker 健康检查 在 `docker-compose.yml` 中已配置健康检查: ```bash # 查看健康状态 docker ps | grep open-webui # 查看健康检查日志 docker inspect --format='{{json .State.Health}}' open-webui | jq ``` --- ## 故障排查 ### 1. 数据库连接失败 **症状**: 容器启动后立即退出,日志显示数据库连接错误 **排查步骤**: ```bash # 查看容器日志 docker logs open-webui # 进入容器测试数据库连接 docker exec -it open-webui bash apt-get update && apt-get install -y mysql-client mysql -h mysql.example.com -u openwebui -p ``` **常见问题**: - ✅ 确认 MySQL 用户权限:`GRANT ALL PRIVILEGES ON openwebui.* TO 'openwebui'@'%'` - ✅ 确认防火墙规则:允许 Docker 容器 IP 访问 MySQL 3306 端口 - ✅ 确认 `DATABASE_URL` 格式正确 - ✅ 如果使用 MySQL 8.0,尝试 `mysql+pymysql://` 驱动 ### 2. 模型下载失败(Slim 镜像首次运行) **症状**: 应用启动缓慢,日志显示模型下载错误 **解决方案**: ```bash # 方式 1: 预先下载模型到挂载目录 # 在宿主机上执行 mkdir -p /data/open-webui/data/cache cd /data/open-webui/data/cache # 下载 sentence-transformers 模型 wget https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2/resolve/main/pytorch_model.bin # 方式 2: 设置 HuggingFace 镜像 docker run -d \ -e HF_ENDPOINT=https://hf-mirror.com \ ... ``` ### 3. 容器内存不足 **症状**: 容器频繁重启,日志显示 OOM (Out of Memory) **解决方案**: ```bash # 限制容器内存使用 docker run -d \ --memory="4g" \ --memory-swap="4g" \ ... # 或在 docker-compose.yml 中配置资源限制(见高级配置) ``` ### 4. 文件上传失败 **症状**: 上传大文件时出现 413 错误 **解决方案**: ```bash # 如果使用 Nginx 反向代理,增加上传大小限制 # /etc/nginx/nginx.conf http { client_max_body_size 100M; } # 重启 Nginx sudo systemctl reload nginx ``` ### 5. WebSocket 连接断开 **症状**: 实时聊天功能不工作,日志显示 WebSocket 错误 **解决方案**: 检查 Nginx 配置是否支持 WebSocket: ```nginx location / { proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; ... } ``` ### 6. 数据库迁移错误 **症状**: 从 SQLite 迁移到 MySQL 后数据丢失 **解决方案**: Open WebUI 不支持自动数据迁移,需要手动导出导入: ```bash # 1. 从旧容器导出数据(使用 SQLite) docker exec old-container python -m open_webui.utils.export_data > data.json # 2. 启动新容器(使用 MySQL) docker run -d \ -e DATABASE_URL=mysql://... \ --name new-container \ ghcr.io//open-webui-next:slim # 3. 导入数据 docker exec -i new-container python -m open_webui.utils.import_data < data.json ``` --- ## 维护操作 ### 更新镜像 ```bash # 拉取最新镜像 docker pull ghcr.io//open-webui-next:slim # 停止并删除旧容器 docker stop open-webui docker rm open-webui # 启动新容器(数据卷保留) docker run -d \ --name open-webui \ ... # 相同参数 ghcr.io//open-webui-next:slim ``` ### 查看日志 ```bash # 实时查看日志 docker logs -f open-webui # 查看最近 100 行日志 docker logs --tail 100 open-webui # 查看特定时间范围日志 docker logs --since "2024-01-01T00:00:00" open-webui ``` ### 进入容器调试 ```bash # 进入容器 bash docker exec -it open-webui bash # 查看环境变量 docker exec open-webui env # 查看进程 docker exec open-webui ps aux ``` --- ## 安全建议 1. **不要在 DATABASE_URL 中明文暴露密码** - 使用 Docker secrets 或环境变量文件 - `.env` 文件添加到 `.gitignore` 2. **定期更新镜像** - 订阅 GitHub 仓库 Release 通知 - 定期执行 `docker pull` 更新 3. **限制容器权限** ```bash docker run -d \ --security-opt=no-new-privileges \ --cap-drop=ALL \ --read-only \ --tmpfs /tmp \ ... ``` 4. **使用 HTTPS** - 生产环境必须使用 HTTPS(Nginx + Let's Encrypt) - 设置 `WEBUI_URL=https://...` 5. **禁用不必要的功能** ```bash -e ENABLE_SIGNUP=false # 禁止公开注册 -e ENABLE_API_KEY=true # 启用 API Key 认证 ``` --- ## 性能优化建议 ### 1. 数据库优化 - 使用 MySQL 8.0+ 以获得更好性能 - 启用 InnoDB 缓冲池:`innodb_buffer_pool_size = 2G` - 定期执行 `OPTIMIZE TABLE` 优化表 ### 2. 应用优化 ```bash # 增加 Worker 数量(根据 CPU 核心数) -e UVICORN_WORKERS=4 # 增加数据库连接池 -e DATABASE_POOL_SIZE=20 -e DATABASE_POOL_MAX_OVERFLOW=10 ``` ### 3. 缓存优化 ```bash # 启用 Redis 缓存(可选) -e REDIS_URL=redis://redis:6379/0 # 增加 AI 模型缓存 -v /data/open-webui/cache:/root/.cache ``` --- ## 联系与支持 - **文档**: 项目 README.md 和 CLAUDE.md - **问题反馈**: GitHub Issues - **社区讨论**: GitHub Discussions --- **最后更新**: 2024-11-14