【问题标题】:How to combine nginx socket with gunicorn app using that socket inside docker?如何使用 docker 内的套接字将 nginx 套接字与 gunicorn 应用程序结合起来?
【发布时间】:2021-01-06 11:53:36
【问题描述】:

我使用flask/tensorflow 开发了一个小项目。它在应用服务器 - gunicorn 下运行。 我还必须将 nginx 包含到项目中以提供静态文件。没有 docker 应用程序运行良好。所有部分(gunicorn、nginx、flask)都按预期合作。现在是时候将这个项目移动到在线服务器了,我需要通过 docker 来完成。

Nginxgunicorn->flask 应用通过 unix 套接字 进行通信。在我的本地主机环境中,我在应用程序根文件夹中使用了套接字 - myapp/app.sock,一切都很好。

现在的问题是我不太明白如何告诉 docker 内的 nginx 使用相同的套接字文件并告诉 gunicorn 听它。我收到以下错误:

上游:http://unix:/var/run/app.sock 在连接到上游时失败(没有这样的文件或目录)

尝试使用不同的套接字文件路径,但没有运气 - 同样的错误。

docker-compose 文件:

version: '3'
services:
  nginx:
    image: nginx:latest
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./nginx/remote-app:/etc/nginx/sites-enabled/remote-app
      - /etc/nginx/proxy_params:/etc/nginx/proxy_params
    ports:
      - 8000:8000
    
    build: .
    command: gunicorn --bind unix:/var/run/app.sock wsgi:app --reload --workers 1 --timeout 60
    
    environment:
      - FLASK_APP=prediction_service.py
      - FLASK_DEBUG=1
      - PYTHONUNBUFFERED=True
    restart: on-failure

ma​​in Dockerfile(对于主应用程序,它可以很好地构建应用程序,一切正常):

FROM python:3.8-slim

RUN pip install flask gunicorn flask_wtf boto3 tqdm
RUN pip install numpy==1.18.5
RUN pip install tensorflow==2.2.0 onnxruntime==1.4.0

COPY *.ipynb /temp/
COPY *.hdf5 /temp/
COPY *.onnx /temp/
COPY *.json /temp/
COPY *.py /temp/

WORKDIR /temp

nginx.conf 与默认值 99% 相同,只是增加了上传到 8M 的文件大小 proxy-params 只是用于发出 nginx 代理请求的配置参数的预设 并且 remote-app 是我的应用程序的配置(简单的一个):

server {
    listen 8000;
    server_name localhost;

   location / {
      include proxy_params;
      proxy_pass htpp://unix:/var/run/app.sock; //**tried /temp/app.sock here same issue**
}
}

因此,如果我打开 localhost(即使没有端口 8000),我也可以获得 nginx 答案。如果我尝试打开 localhost:8000 我得到那个套接字错误(上面粘贴了强文本)。

【问题讨论】:

    标签: docker ubuntu nginx flask gunicorn


    【解决方案1】:

    我会避免为此使用套接字,因为容器/服务之间存在 IP 通信,并且您确实应该为应用服务器提供单独的服务。

    类似:

    version: '3'
    services:
    
      nginx:
        image: nginx:latest
        volumes:
          - ./nginx/nginx.conf:/etc/nginx/nginx.conf
          - ./nginx/remote-app:/etc/nginx/sites-enabled/remote-app
          - /etc/nginx/proxy_params:/etc/nginx/proxy_params
        ports:
          - 80:80
          - 143:143
    
      app_server:
        build: .
        command: gunicorn --bind '0.0.0.0:5000' wsgi:app --reload --workers 1 --timeout 60
        
        environment:
          - FLASK_APP=prediction_service.py
          - FLASK_DEBUG=1
          - PYTHONUNBUFFERED=True
        restart: on-failure
    

    注意gunicorn不是绑定到socket上,而是绑定到app_server容器的所有IP接口上的5000端口。

    使用单独的服务 app_server 和您当前的 nginx 服务,您可以简单地将这些值视为每个容器中的 DNS 别名。所以在 nginx 配置中:

    proxy_pass http://app_server:5000/
    

    所以如果我打开 localhost(即使没有端口 8000)我也可以得到 nginx 的答案。

    听起来你的意思是连接到端口 80 上的 localhost,这可能是在主机上运行的 nginx 服务器。您的撰写文件中的这一行也建议这样做:/etc/nginx/proxy_params:/etc/nginx/proxy_params

    这是从主机上本地安装的 nginx 加载文件。您可能应该意识到这一点,因为在调试时运行该服务器也会使您感到困惑,并且在某处启动此 compose 文件意味着主机上必须存在 /etc/nginx/proxy_params

    您可能应该将它存储在项目目录中,就像其他已挂载的文件一样,并将其挂载为:

      - ./nginx/proxy_params:/etc/nginx/proxy_params
    

    【讨论】:

    • 感谢您的回答。立即尝试您的解决方案。截至“你可能有本地 nginx 正在运行......” - 不,我三重检查了服务是否在本地停止。将 proxy_params 复制到项目是一个很好的评论 - 谢谢,已经应用了它
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-06
    • 2016-09-06
    • 1970-01-01
    • 2012-08-09
    • 1970-01-01
    • 2018-04-13
    • 2011-02-26
    相关资源
    最近更新 更多