Setting up a ChatGPT server
I used to use the method described in my other blog to set up a ChatGPT server. It worked fantastically until April 16th when OpenAI decided that even Plus users must go through Cloudflare. (then my reverse proxy instantly died.)
Now the latest trend to bypass Cloudflare is to use undetected_chromedriver.
So here is my configuration. (many thanks to @linweiyuan)
docker compose
services:
web:
container_name: web
image: kevinwang15/chatgpt-web:20230420
ports:
- 127.0.0.1:3055:3002
restart: unless-stopped
environment:
- OPENAI_API_MODEL=gpt-4
- API_REVERSE_PROXY=http://go-chatgpt-api:8080/chatgpt/backend-api/conversation
- OPENAI_ACCESS_TOKEN=<get your access token from https://ai.fakeopen.com/auth>
proxy:
container_name: proxy
image: kevinwang15/convert-subscription-to-http-proxy:latest
restart: unless-stopped
environment:
- SUB_URL=<give me an SS subscription URL here; alternatively, remove this container and do it your own way>
go-chatgpt-api:
container_name: go-chatgpt-api
image: linweiyuan/go-chatgpt-api
ports:
- 127.0.0.1:3056:8080
environment:
- TZ=Asia/Shanghai
- GIN_MODE=release
- PROXY=http://proxy:7890
- ARKOSE_TOKEN_URL=http://<public-ip-of-your-server>:8199/token
depends_on:
- proxy
- arkose
restart: unless-stopped
arkose:
image: xyhelper/xyhelper-arkose:latest
restart: always
ports:
- 8199:80
environment:
- PORT=80
depends_on:
- chrome
chrome:
image: kasmweb/chrome:1.10.0
depends_on:
- proxy
ports:
- "6901:6901"
environment:
- VNC_PW=<set up your arbitrary password here>
- URL=http://<public-ip-of-your-server>:8199
- http_proxy=http://proxy:7890
- https_proxy=http://proxy:7890
shm_size: 512m
Run with docker compose, and the ChatGPT server will listen on 127.0.0.1:3055
.
Configure nginx to add SSL
map $cookie_password $is_valid_password {
default 0;
"your-password-here" 1;
}
server {
listen 80;
server_name your-site-name.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
gzip on;
gzip_types text/plain application/javascript application/x-javascript text/javascript text/xml text/css;
ssl_certificate /etc/ssl/yoursite.crt;
ssl_certificate_key /etc/ssl/yoursite.key;
server_name yoursite.com;
location = /login {
if ($request_method != GET) {
return 405;
}
if ($arg_password = "") {
return 400;
}
if ($arg_redirect = "") {
return 400;
}
add_header Set-Cookie "password=$arg_password; Path=/; HttpOnly";
return 302 $arg_redirect;
}
location / {
if ($is_valid_password != 1) {
return 401;
}
proxy_pass http://127.0.0.1:3055/;
proxy_cache off;
proxy_buffering off;
chunked_transfer_encoding on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
}
}
Accessing the server
You will be able to access the service through
https://yoursite.com/login?password=your-password-here&redirect=/
Monitoring
You could set up a simple cron monitor like this:
*/30 * * * * curl --retry 3 --fail -H "Authorization: Bearer $(cat /path/to/your/docker-compose.yaml | grep OPENAI_ACCESS_TOKEN | cut -d "=" -f2)" 127.0.0.1:3056/chatgpt/backend-api/conversations && curl https://healthchecks.io/ping/...
(P.S. also consider self-hosting healthchecks.io. Self-hosted healthchecks.io + Gotify is really a great cron monitoring solution especially in Mainland China)
TODO
- Seems like Chanzhaoyu/chatgpt-web doesn’t support
conversation/gen_title
so the conversation title doesn’t look good. But I guess it’s not a big issue. (opened a feature request here)