From a45d3a23cf4efdaf03cbc1d38d056dff80382343 Mon Sep 17 00:00:00 2001 From: okxlin Date: Fri, 7 Jul 2023 23:05:54 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E6=B7=BB=E5=8A=A0chatgpt-next-web?= =?UTF-8?q?=E5=88=B0=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/chatgpt-next-web/2.8.8/data.yml | 40 ++++ .../chatgpt-next-web/2.8.8/docker-compose.yml | 21 ++ apps/chatgpt-next-web/README.md | 186 ++++++++++++++++++ apps/chatgpt-next-web/data.yml.bak | 20 ++ apps/chatgpt-next-web/latest/data.yml | 40 ++++ .../latest/docker-compose.yml | 21 ++ apps/chatgpt-next-web/logo.png | Bin 0 -> 10358 bytes 7 files changed, 328 insertions(+) create mode 100644 apps/chatgpt-next-web/2.8.8/data.yml create mode 100644 apps/chatgpt-next-web/2.8.8/docker-compose.yml create mode 100644 apps/chatgpt-next-web/README.md create mode 100644 apps/chatgpt-next-web/data.yml.bak create mode 100644 apps/chatgpt-next-web/latest/data.yml create mode 100644 apps/chatgpt-next-web/latest/docker-compose.yml create mode 100644 apps/chatgpt-next-web/logo.png diff --git a/apps/chatgpt-next-web/2.8.8/data.yml b/apps/chatgpt-next-web/2.8.8/data.yml new file mode 100644 index 00000000..6048214e --- /dev/null +++ b/apps/chatgpt-next-web/2.8.8/data.yml @@ -0,0 +1,40 @@ +additionalProperties: + formFields: + - default: 40042 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: Port + labelZh: 端口 + required: true + rule: paramPort + type: number + - default: 'sk-xxx' + edit: true + envKey: API_KEY + labelEn: OPENAI API KEY + labelZh: OPENAI API KEY + required: ture + type: text + - default: chatgptnextweb + edit: true + envKey: SECRET_KEY + labelEn: Access rights key, optional (recommended) + labelZh: 访问权限密钥,可选(强烈建议填写) + random: true + required: false + rule: paramComplexity + type: password + - default: 'http://127.0.0.1:7890 user password' + edit: true + envKey: PROXY + labelEn: Proxy + labelZh: 代理地址 + required: false + type: text + - default: https://api.openai.com + edit: true + envKey: API_BASE_URL + labelEn: API interface address + labelZh: API接口地址 + required: true + type: text \ No newline at end of file diff --git a/apps/chatgpt-next-web/2.8.8/docker-compose.yml b/apps/chatgpt-next-web/2.8.8/docker-compose.yml new file mode 100644 index 00000000..2ffb130b --- /dev/null +++ b/apps/chatgpt-next-web/2.8.8/docker-compose.yml @@ -0,0 +1,21 @@ +version: '3' +services: + chatgpt-next-web: + container_name: ${CONTAINER_NAME} + restart: always + networks: + - 1panel-network + ports: + - "${PANEL_APP_PORT_HTTP}:3000" + environment: + - "OPENAI_API_KEY=${API_KEY}" + - "CODE=${SECRET_KEY}" + - "PROXY_URL=${PROXY}" + - "BASE_URL=${API_BASE_URL}" + image: yidadaa/chatgpt-next-web:v2.8.8 + labels: + createdBy: "Apps" + +networks: + 1panel-network: + external: true diff --git a/apps/chatgpt-next-web/README.md b/apps/chatgpt-next-web/README.md new file mode 100644 index 00000000..f8d5693e --- /dev/null +++ b/apps/chatgpt-next-web/README.md @@ -0,0 +1,186 @@ +
+预览 + +

ChatGPT Next Web

+ +一键免费部署你的私人 ChatGPT 网页应用。 + +[演示 Demo](https://chat-gpt-next-web.vercel.app/) / [反馈 Issues](https://github.com/Yidadaa/ChatGPT-Next-Web/issues) / [加入 Discord](https://discord.gg/zrhvHCr79N) / [QQ 群](https://user-images.githubusercontent.com/16968934/228190818-7dd00845-e9b9-4363-97e5-44c507ac76da.jpeg) / [打赏开发者](https://user-images.githubusercontent.com/16968934/227772541-5bcd52d8-61b7-488c-a203-0330d8006e2b.jpg) / [Donate](#捐赠-donate-usdt) + +[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2FYidadaa%2FChatGPT-Next-Web&env=OPENAI_API_KEY&env=CODE&project-name=chatgpt-next-web&repository-name=ChatGPT-Next-Web) + +[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/Yidadaa/ChatGPT-Next-Web) + +![主界面](https://github.com/Yidadaa/ChatGPT-Next-Web/raw/main/docs/images/cover.png) + +
+ +## 开始使用 + +1. 准备好你的 [OpenAI API Key](https://platform.openai.com/account/api-keys); +2. 点击右侧按钮开始部署: + [![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2FYidadaa%2FChatGPT-Next-Web&env=OPENAI_API_KEY&env=CODE&project-name=chatgpt-next-web&repository-name=ChatGPT-Next-Web),直接使用 Github 账号登录即可,记得在环境变量页填入 API Key 和[页面访问密码](#配置页面访问密码) CODE; +3. 部署完毕后,即可开始使用; +4. (可选)[绑定自定义域名](https://vercel.com/docs/concepts/projects/domains/add-a-domain):Vercel 分配的域名 DNS 在某些区域被污染了,绑定自定义域名即可直连。 + +## 保持更新 + +如果你按照上述步骤一键部署了自己的项目,可能会发现总是提示“存在更新”的问题,这是由于 Vercel 会默认为你创建一个新项目而不是 fork 本项目,这会导致无法正确地检测更新。 +推荐你按照下列步骤重新部署: + +- 删除掉原先的仓库; +- 使用页面右上角的 fork 按钮,fork 本项目; +- 在 Vercel 重新选择并部署,[请查看详细教程](https://github.com/Yidadaa/ChatGPT-Next-Web/raw/main/docs/vercel-cn.md#如何新建项目)。 + +### 打开自动更新 + +> 如果你遇到了 Upstream Sync 执行错误,请手动 Sync Fork 一次! + +当你 fork 项目之后,由于 Github 的限制,需要手动去你 fork 后的项目的 Actions 页面启用 Workflows,并启用 Upstream Sync Action,启用之后即可开启每小时定时自动更新: + +![自动更新](https://github.com/Yidadaa/ChatGPT-Next-Web/raw/main/docs/images/enable-actions.jpg) + +![启用自动更新](https://github.com/Yidadaa/ChatGPT-Next-Web/raw/main/docs/images/enable-actions-sync.jpg) + +### 手动更新代码 + +如果你想让手动立即更新,可以查看 [Github 的文档](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork) 了解如何让 fork 的项目与上游代码同步。 + +你可以 star/watch 本项目或者 follow 作者来及时获得新功能更新通知。 + +## 配置页面访问密码 + +> 配置密码后,用户需要在设置页手动填写访问码才可以正常聊天,否则会通过消息提示未授权状态。 + +> **警告**:请务必将密码的位数设置得足够长,最好 7 位以上,否则[会被爆破](https://github.com/Yidadaa/ChatGPT-Next-Web/issues/518)。 + +本项目提供有限的权限控制功能,请在 Vercel 项目控制面板的环境变量页增加名为 `CODE` 的环境变量,值为用英文逗号分隔的自定义密码: + +``` +code1,code2,code3 +``` + +增加或修改该环境变量后,请**重新部署**项目使改动生效。 + +## 环境变量 + +> 本项目大多数配置项都通过环境变量来设置,教程:[如何修改 Vercel 环境变量](https://github.com/Yidadaa/ChatGPT-Next-Web/raw/main/docs/vercel-cn.md)。 + +### `OPENAI_API_KEY` (必填项) + +OpanAI 密钥,你在 openai 账户页面申请的 api key。 + +### `CODE` (可选) + +访问密码,可选,可以使用逗号隔开多个密码。 + +**警告**:如果不填写此项,则任何人都可以直接使用你部署后的网站,可能会导致你的 token 被急速消耗完毕,建议填写此选项。 + +### `BASE_URL` (可选) + +> Default: `https://api.openai.com` + +> Examples: `http://your-openai-proxy.com` + +OpenAI 接口代理 URL,如果你手动配置了 openai 接口代理,请填写此选项。 + +> 如果遇到 ssl 证书问题,请将 `BASE_URL` 的协议设置为 http。 + +### `OPENAI_ORG_ID` (可选) + +指定 OpenAI 中的组织 ID。 + +### `HIDE_USER_API_KEY` (可选) + +如果你不想让用户自行填入 API Key,将此环境变量设置为 1 即可。 + +### `DISABLE_GPT4` (可选) + +如果你不想让用户使用 GPT-4,将此环境变量设置为 1 即可。 + +### `HIDE_BALANCE_QUERY` (可选) + +如果你不想让用户查询余额,将此环境变量设置为 1 即可。 + +## 开发 + +点击下方按钮,开始二次开发: + +[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/Yidadaa/ChatGPT-Next-Web) + +在开始写代码之前,需要在项目根目录新建一个 `.env.local` 文件,里面填入环境变量: + +``` +OPENAI_API_KEY= + +# 中国大陆用户,可以使用本项目自带的代理进行开发,你也可以自由选择其他代理地址 +BASE_URL=https://chatgpt1.nextweb.fun/api/proxy +``` + +### 本地开发 + +1. 安装 nodejs 18 和 yarn,具体细节请询问 ChatGPT; +2. 执行 `yarn install && yarn dev` 即可。⚠️ 注意:此命令仅用于本地开发,不要用于部署! +3. 如果你想本地部署,请使用 `yarn install && yarn build && yarn start` 命令,你可以配合 pm2 来守护进程,防止被杀死,详情询问 ChatGPT。 + +## 部署 + +### 容器部署 (推荐) + +> Docker 版本需要在 20 及其以上,否则会提示找不到镜像。 + +> ⚠️ 注意:docker 版本在大多数时间都会落后最新的版本 1 到 2 天,所以部署后会持续出现“存在更新”的提示,属于正常现象。 + +```shell +docker pull yidadaa/chatgpt-next-web + +docker run -d -p 3000:3000 \ + -e OPENAI_API_KEY="sk-xxxx" \ + -e CODE="页面访问密码" \ + yidadaa/chatgpt-next-web +``` + +你也可以指定 proxy: + +```shell +docker run -d -p 3000:3000 \ + -e OPENAI_API_KEY="sk-xxxx" \ + -e CODE="页面访问密码" \ + --net=host \ + -e PROXY_URL="http://127.0.0.1:7890" \ + yidadaa/chatgpt-next-web +``` + +如果你的本地代理需要账号密码,可以使用: + +```shell +-e PROXY_URL="http://127.0.0.1:7890 user password" +``` + +如果你需要指定其他环境变量,请自行在上述命令中增加 `-e 环境变量=环境变量值` 来指定。 + +### 本地部署 + +在控制台运行下方命令: + +```shell +bash <(curl -s https://raw.githubusercontent.com/Yidadaa/ChatGPT-Next-Web/main/scripts/setup.sh) +``` + +⚠️ 注意:如果你安装过程中遇到了问题,请使用 docker 部署。 + +## 鸣谢 + +### 捐赠者 + +> 见英文版。 + +### 贡献者 + +[见项目贡献者列表](https://github.com/Yidadaa/ChatGPT-Next-Web/graphs/contributors) + +## 开源协议 + +> 反对 996,从我开始。 + +[Anti 996 License](https://github.com/kattgu7/Anti-996-License/blob/master/LICENSE_CN_EN) diff --git a/apps/chatgpt-next-web/data.yml.bak b/apps/chatgpt-next-web/data.yml.bak new file mode 100644 index 00000000..cacde37f --- /dev/null +++ b/apps/chatgpt-next-web/data.yml.bak @@ -0,0 +1,20 @@ +name: ChatGPT-Next-Web +tags: + - 工具 +title: 一键免费部署你的跨平台私人 ChatGPT 应用 +type: 工具 +description: 一键免费部署你的跨平台私人 ChatGPT 应用 +additionalProperties: + key: chatgpt-next-web + name: ChatGPT-Next-Web + tags: + - Tool + shortDescZh: 一键免费部署你的跨平台私人 ChatGPT 应用 + shortDescEn: One-Click to get well-designed cross-platform ChatGPT web UI + type: tool + crossVersionUpdate: true + limit: 0 + recommend: 0 + website: https://github.com/Yidadaa/ChatGPT-Next-Web + github: https://github.com/Yidadaa/ChatGPT-Next-Web + document: https://github.com/Yidadaa/ChatGPT-Next-Web diff --git a/apps/chatgpt-next-web/latest/data.yml b/apps/chatgpt-next-web/latest/data.yml new file mode 100644 index 00000000..6048214e --- /dev/null +++ b/apps/chatgpt-next-web/latest/data.yml @@ -0,0 +1,40 @@ +additionalProperties: + formFields: + - default: 40042 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: Port + labelZh: 端口 + required: true + rule: paramPort + type: number + - default: 'sk-xxx' + edit: true + envKey: API_KEY + labelEn: OPENAI API KEY + labelZh: OPENAI API KEY + required: ture + type: text + - default: chatgptnextweb + edit: true + envKey: SECRET_KEY + labelEn: Access rights key, optional (recommended) + labelZh: 访问权限密钥,可选(强烈建议填写) + random: true + required: false + rule: paramComplexity + type: password + - default: 'http://127.0.0.1:7890 user password' + edit: true + envKey: PROXY + labelEn: Proxy + labelZh: 代理地址 + required: false + type: text + - default: https://api.openai.com + edit: true + envKey: API_BASE_URL + labelEn: API interface address + labelZh: API接口地址 + required: true + type: text \ No newline at end of file diff --git a/apps/chatgpt-next-web/latest/docker-compose.yml b/apps/chatgpt-next-web/latest/docker-compose.yml new file mode 100644 index 00000000..c27417db --- /dev/null +++ b/apps/chatgpt-next-web/latest/docker-compose.yml @@ -0,0 +1,21 @@ +version: '3' +services: + chatgpt-next-web: + container_name: ${CONTAINER_NAME} + restart: always + networks: + - 1panel-network + ports: + - "${PANEL_APP_PORT_HTTP}:3000" + environment: + - "OPENAI_API_KEY=${API_KEY}" + - "CODE=${SECRET_KEY}" + - "PROXY_URL=${PROXY}" + - "BASE_URL=${API_BASE_URL}" + image: yidadaa/chatgpt-next-web:latest + labels: + createdBy: "Apps" + +networks: + 1panel-network: + external: true diff --git a/apps/chatgpt-next-web/logo.png b/apps/chatgpt-next-web/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..7bc29549c9530cfc5dd493cf598925532b9bf88a GIT binary patch literal 10358 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 ~v1YNITZ-WjS^C<(4~^eT!cgiS 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