基于ChatGPT PLUS搭建Web共享服务:详细教程与优化方案

57

最近,我成功搭建了一个基于ChatGPT PLUS的Web共享服务,目的是为了方便团队成员共同使用。在众多开源项目中,我最终选择了chatgpt-web-share,主要是因为它支持API和PLUS账号两种共享方式,并且采用Python+JS+Docker架构,这对于我来说相对熟悉。虽然ChatGPT-Next-Web使用纯JS开发,操作简单,但在灵活性方面略有欠缺。

在这里插入图片描述

准备工作

运行环境

我的运行环境是Windows 11,借助WSL2运行Docker。同时,我还需要配置小猫咪以及无线网卡(连接互联网)和有线网卡(连接公司内网)。具体配置如下:

  • Windows 11
    • WSL2
      • Docker
    • 小猫咪
    • 无线网卡DHCP(互联网)
    • 有线网卡10.8.15.50(公司内网)

版本选择

我选择了chatgpt-web-share的最新版本0.4.0-alpha4.4,以确保使用最新的功能和修复。

配置文件详解

在开始之前,我们需要创建一系列配置文件。最终的目录结构如下图所示。需要手动创建docker-compose.yml、data目录、config目录以及config目录下的config.yaml和credentials.yaml。绿框中的目录和文件是后续自动生成的。

在这里插入图片描述

下面是各个配置文件的详细内容:

docker-compose.yml

services:
  chatgpt-web-share:
    image: ghcr.io/moeakwak/chatgpt-web-share:0.4.0-alpha4.4
    container_name: cws
    restart: always
    ports:
      - 8092:80  # 端口可调整
    volumes:
      - ./data:/app/backend/data
    environment:
      - TZ=Asia/Shanghai
      - CWS_CONFIG_DIR=/app/backend/data/config
      - CHATGPT_BASE_URL=http://go-chatgpt-api:8080/chatgpt/
    depends_on:
      - mongo
      - go-chatgpt-api

  mongo:
    image: mongo:6.0
    restart: always
    volumes:
      - ./mongo_data:/data/db
    environment:
      MONGO_INITDB_DATABASE: cws
      MONGO_INITDB_ROOT_USERNAME: cws
      MONGO_INITDB_ROOT_PASSWORD: password

  go-chatgpt-api:
    container_name: go-chatgpt-api
    image: linweiyuan/go-chatgpt-api:latest
    environment:
      - GIN_MODE=release
      - PROXY=http://10.30.48.245:7890 # 宿主机IP端口
    restart: unless-stopped

config.yaml

openai_web:
  is_plus_account: true
  chatgpt_base_url: http://go-chatgpt-api:8080/chatgpt/backend-api/
  proxy:
  common_timeout: 10
  ask_timeout: 600
openai_api:
  openai_base_url: https://api.openai.com/v1/
  proxy:
  connect_timeout: 10
  read_timeout: 20
common:
  print_sql: false
  create_initial_admin_user: true
  initial_admin_user_username: admin
  initial_admin_user_password: password
  sync_conversations_on_startup: true
  sync_conversations_regularly: false
http:
  host: 127.0.0.1
  port: 8000
  cors_allow_origins:
    - http://localhost
    - http://127.0.0.1
    - http://0.0.0.0
data:
  data_dir: ./data
  database_url: sqlite+aiosqlite:///data/database.db
  mongodb_url: mongodb://cws:password@mongo:27017
  run_migration: false
auth:
  jwt_secret: MODIFY_THIS_TO_RANDOM_SECRET
  jwt_lifetime_seconds: 86400
  cookie_max_age: 86400
  cookie_name: user_auth
  user_secret: MODIFY_THIS_TO_RANDOM_SECRET
stats:
  ask_stats_ttl: 7776000
  request_stats_ttl: 2592000
  request_stats_filter_keywords:
    - /status
log:
  console_log_level: INFO

credentials.yaml

openai_web_access_token: "eyJhbGcxxxxxxxxxxx"
openai_api_key: "sk-POxxxxxxxx"

其中,access_token的获取链接为:https://chat.openai.com/api/auth/session,api_key的生成链接为:https://platform.openai.com/account/api-keys

在这里插入图片描述

网络加速配置

由于网络原因,直接从Docker Hub拉取镜像速度较慢,需要配置镜像加速。此外,为了让容器内部也能正常访问ChatGPT,需要配置代理。我通过修改docker-compose.yml文件,使go-chatgpt-api服务使用宿主机的代理。

...
  go-chatgpt-api:
    container_name: go-chatgpt-api
    image: linweiyuan/go-chatgpt-api:latest
    environment:
      - GIN_MODE=release
      - PROXY=http://10.30.48.245:7890 # 宿主机IP端口
    restart: unless-stopped

部署步骤

完成配置后,使用以下命令启动服务:

docker compose up -d

如果部署成功,可以看到类似以下的日志信息:

在这里插入图片描述

此时,通过浏览器访问127.0.0.1:80920.0.0.0:8092172.23.192.1:8092即可看到登录页面。使用配置文件中设置的用户名(admin)和密码(password)即可登录。

实现外部访问

如果需要让其他用户从外部访问该服务,需要进行端口映射。直接使用本机IP地址加端口号(例如:本机ip:8092)可能无法访问,需要进行额外的端口映射配置。

不建议使用以下方式:

在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

完成上述步骤后,以管理员权限打开PowerShell,执行以下命令:

netsh interface portproxy add v4tov4 listenport=8092 listenaddress=0.0.0.0 connectport=8092 connectaddress=localhost

这条命令将0.0.0.0:8092映射到localhost:8092。这样,即使电脑有多块网卡,也可以通过任意网卡的IP地址加上端口号8092访问到localhost:8092,从而实现外部访问。更详细的解释可以参考https://zhuanlan.zhihu.com/p/425312804

20230801更新

上述方法存在一个问题:重启后,8092端口可能无法访问。需要执行以下命令删除映射:

netsh interface portproxy delete v4tov4 listenport=8092 listenaddress=0.0.0.0

因此,我更推荐使用wsl2-auto-portproxy

在/mnt/c/Users/microfat目录下创建.wslpp目录,并在该目录下创建config.json文件,内容如下:

{
  "onlyPredefined": true,
  "predefined": {
    "tcp": [
      "8092:8092"
    ]
  },
  "ignore": {
    "tcp": [
      445
    ]
  }
}

如果在使用过程中,发现无法通过ladder连接到WSL2,可以尝试打开小猫咪的TUN Mode。

在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

如果出现类似上图的错误,尝试重启服务:

docker compose down --rmi local
docker compose up -d

进一步优化

目前,服务已经可以实现重启后自动启动。但是,这依赖于无线网卡的IP地址不发生变化。因为代理地址被硬编码在/etc/systemd/system/docker.service.d/proxy.conf、/etc/default/docker和docker-compose.yml文件中。如果IP地址发生变化,就需要更新这些文件,并重启docker以及重新构建镜像。为了减少这部分工作量,可以考虑在WSL启动时自动更新这些文件。

首先需要解决的问题是在WSL中获取宿主机电脑的IP地址。可以使用以下命令:

NEW_IP=$(powershell.exe -Command 'Get-NetIPAddress -InterfaceAlias WLAN | Where-Object { $_.AddressFamily -match "IPv4" } | Select-Object -ExpandProperty IPAddress' | tr -d '\r')
echo $NEW_IP

然后,使用sed命令修改上述文件:

sudo sed -i -E "s/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/${NEW_IP}/g" /etc/default/docker

将修改命令添加到/etc/wsl.conf中,就可以实现在启动docker之前完成配置文件的修改。注意:不要将这些命令放在.bashrc中,因为.bashrc的执行在/etc/wsl.conf之后。