Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docker无法正常使用代理 #188

Closed
water-root opened this issue Mar 31, 2023 · 23 comments
Closed

docker无法正常使用代理 #188

water-root opened this issue Mar 31, 2023 · 23 comments

Comments

@water-root
Copy link

不使用docker的本地部署可以正常使用代理。使用docker后无法正常使用代理,但curl google是可以的,python3 check_proxy.py 也能正常显示出代理
image

223

@binary-husky
Copy link
Owner

您好,确定本地代理协议是https吗?我头一次见本地代理用https协议的……

@binary-husky
Copy link
Owner

另外不是wsl吧?

@binary-husky
Copy link
Owner

如果是windows,--net=host就失效了,wiki里面有人给了别的方案

@water-root
Copy link
Author

用的是Ubuntu 20.04.1 服务器

@binary-husky
Copy link
Owner

binary-husky commented Mar 31, 2023

“python3 check_proxy.py 也能正常显示出代理”

这不对吧,main.py和check_proxy.py检查代理调用的是同一个函数,怎么会出不同的结果呢?/(ㄒoㄒ)/~~

@water-root
Copy link
Author

main.py和check_proxy.py都是可以使用代理,docker就无法使用

@water-root
Copy link
Author

这是main.py运行后的结果,代理可以使用
FireShot Cap

image

@binary-husky
Copy link
Owner

main.py和check_proxy.py都是可以使用代理,docker就无法使用

那我就有点蒙了,有没有可能docker设置了某种安全策略禁用了--net=host?
试试端口映射?把 --net=host 换成 -p 20231:20231

@binary-husky
Copy link
Owner

binary-husky commented Mar 31, 2023

或者你已经在docker内部了,你实际上在docker in docker嵌套?
我暂时只能想到这两种可能了

@AllenXiao95
Copy link

main.py和check_proxy.py都是可以使用代理,docker就无法使用

那我就有点蒙了,有没有可能docker设置了某种安全策略禁用了--net=host? 试试端口映射?把 --net=host 换成 -p 20231:20231

我也遇到了类似情况, 使用指定端口做expose就可以, --net=host就不行

@FR13ndSDP
Copy link

我在宿主机运行python3 check_proxy.py 输出:

网络代理状态:运行。
查询代理的地理位置,返回的结果是 ...
代理配置 http://127.0.0.1:7890, 代理所在地:Malaysia

然而使用docker运行 docker run --rm -it --net=host gpt-academic python3 check_proxy.py,却有:

网络代理状态:未配置。无代理状态下很可能无法访问。

尝试在.docker/config.json中指定代理仍然失败,究竟是为什么呢?

@FR13ndSDP
Copy link

我在宿主机运行python3 check_proxy.py 输出:

网络代理状态:运行。
查询代理的地理位置,返回的结果是 ...
代理配置 http://127.0.0.1:7890, 代理所在地:Malaysia

然而使用docker运行 docker run --rm -it --net=host gpt-academic python3 check_proxy.py,却有:

网络代理状态:未配置。无代理状态下很可能无法访问。

尝试在.docker/config.json中指定代理仍然失败,究竟是为什么呢?

此问题已解决,需要在build镜像之前修改config.py,在这之后docker run --rm -it --net=host gpt-academic正确运行

@binary-husky
Copy link
Owner

binary-husky commented Mar 31, 2023

这个dockerfile可以简化配置的流程,直接把秘钥和代理信息塞进Dockerfile里面 @AllenXiao95 @FR13ndSDP @water-root @SadPencil

# how to build: docker build -t gpt-academic --network=host .
# how to run: docker run --rm -it --net=host gpt-academic
FROM python:3.11
WORKDIR /gpt


ARG useProxyNetwork=''

# # # comment out below if you do not need proxy network | 翻墙 - 从此行向下删除
# RUN apt-get update
# RUN apt-get install -y curl proxychains curl 
# RUN $useProxyNetwork curl cip.cc
# RUN sed -i '$ d' /etc/proxychains.conf
# RUN sed -i '$ d' /etc/proxychains.conf
# RUN echo "socks5 127.0.0.1 10880" >> /etc/proxychains.conf
# ARG useProxyNetwork=proxychains
# # # comment out above if you do not need proxy network | 翻墙 - 从此行向上删除

RUN $useProxyNetwork git clone https://github.com/binary-husky/chatgpt_academic.git
WORKDIR /gpt/chatgpt_academic
RUN $useProxyNetwork pip3 install -r requirements.txt
RUN $useProxyNetwork git pull

# proxy and API Key (key below is invalid)
RUN echo ' \n\
API_KEY = "sk-8dllgEAW17uajxxxxxxxxxxxxxxxxxxxr" \n\
USE_PROXY = True \n\
proxies = { "http": "socks5h://localhost:10880", "https": "socks5h://localhost:10880", } ' >> config_private.py

CMD ["python3", "main.py"]


@SadPencil
Copy link
Contributor

密钥,不是秘……调一下输入法把错误的词删了吧

@SadPencil
Copy link
Contributor

从dockerfile里写死 API 密钥不是最佳做法(违反了参数变动不改动image的传统),跟docker配合的情况下更佳的做法是通过环境变量读取配置。编写entrypoint.sh文件获取设置的API密钥然后动态写入config文件。

@SadPencil
Copy link
Contributor

如果有需要我可以做个PR,把你这个dockerfile改成最通常的环境变量做法

@AllenXiao95
Copy link

通过args方式传递参数可能更好一点

@SadPencil
Copy link
Contributor

@AllenXiao95 主流的设计原则是,敏感参数要么从 tty 直接读要么环境变量要么文件,不能从命令行参数读入

@binary-husky
Copy link
Owner

@AllenXiao95 主流的设计原则是,敏感参数要么从 tty 直接读要么环境变量要么文件,不能从命令行参数读入

这样呀~

不过在windows上配置环境变量真的是很难受,而且在git bash和在cmd配置环境变量的命令还不一样……

@binary-husky
Copy link
Owner

binary-husky commented Apr 1, 2023

@AllenXiao95 主流的设计原则是,敏感参数要么从 tty 直接读要么环境变量要么文件,不能从命令行参数读入

这样呀~

不过在windows上配置环境变量真的是很难受,而且在git bash和在cmd配置环境变量的命令还不一样……

另外之后应该可以设计成按照一定的优先级,依次读取 argparse,环境变量,config_private 和 config

@lru_cache(maxsize=128)
def read_single_conf_with_lru_cache(arg):

    try:  parser = argparse.ArgumentParser(x..............)
    try:  os.env 
    try:        r = getattr(importlib.import_module('config_private'), arg)
    except: r = getattr(importlib.import_module('config'), arg)
    # 在读取API_KEY时,检查一下是不是忘了改config
    if arg=='API_KEY':
        # 正确的 API_KEY 是 "sk-" + 48 位大小写字母数字的组合
        API_MATCH = re.match(r"sk-[a-zA-Z0-9]{48}$", r)
        if API_MATCH:
            print(f"[API_KEY] 您的 API_KEY 是: {r[:15]}*** API_KEY 导入成功")
        else:
            assert False, "正确的 API_KEY 是 'sk-' + '48 位大小写字母数字' 的组合,请在config文件中修改API密钥, 添加海外代理之后再运行。" + \
                        "(如果您刚更新过代码,请确保旧版config_private文件中没有遗留任何新增键值)"
    if arg=='proxies':
        if r is None: 
            print('[PROXY] 网络代理状态:未配置。无代理状态下很可能无法访问。建议:检查USE_PROXY选项是否修改。')
        else: 
            print('[PROXY] 网络代理状态:已配置。配置信息如下:', r)
            assert isinstance(r, dict), 'proxies格式错误,请注意proxies选项的格式,不要遗漏括号。'
    return r

def get_conf(*args):
    # 建议您复制一个config_private.py放自己的秘密, 如API和代理网址, 避免不小心传github被别人看到
    res = []
    for arg in args:
        r = read_single_conf_with_lru_cache(arg)
        res.append(r)
    return res

@SadPencil
Copy link
Contributor

SadPencil commented Apr 2, 2023

@binary-husky 不应使用 argparse 读取敏感信息。就好比 mysql 的 client 可以通过 tty (指定 -p 参数后从 tty 读) 或环境变量读取密码,但绝不会提供命令行参数读取密码的功能一样。

@binary-husky binary-husky mentioned this issue Apr 2, 2023
@sfs999
Copy link

sfs999 commented Apr 30, 2023

docker初学者,我在使用docker构建时也发生了该问题,原因是在配置代理地址时使用的是localhost,此时无法跳出docker的网络连接到宿主机,应该将之改为host.docker.internal,此时docker内部程序可以访问宿主机的代理端口

@jasonliu222
Copy link

docker初学者,我在使用docker构建时也发生了该问题,原因是在配置代理地址时使用的是localhost,此时无法跳出docker的网络连接到宿主机,应该将之改为host.docker.internal,此时docker内部程序可以访问宿主机的代理端口

这个特殊的 DNS 名称目前仅适用于 Docker for Mac 和 Docker for Windows,并不适用于所有环境。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants