docker中的Nginx,fastapi和streamlit - 反向代理不适用于streamlit

Posted

技术标签:

【中文标题】docker中的Nginx,fastapi和streamlit - 反向代理不适用于streamlit【英文标题】:Nginx, fastapi and streamlit in docker - reverse proxy does not work for streamlit 【发布时间】:2021-12-26 23:31:20 【问题描述】:

我想使用 docker 将 nginx、fastapi 和 2 个流式应用程序容器化。所有 3 个应用程序(fastapi、2streamlit 应用程序)不相互交互。 Nginx 应该作为这 3 个应用程序的反向代理。 对于 fastapi,它正在工作。我可以将 rest-api 请求发送到 http://ip:80/twxservices 。 “twxservices”作为端点被添加到 app.py 文件中,而不是在 nginxconfig 中。

streamlit 应用程序无法通过此 http://ip:80/stream1 和 http://ip:80/stream2 访问我收到错误:404:未找到

提前感谢您的帮助。在文件结构和配置文件下方找到。 这是文件结构以及反向代理应该如何工作:

docker-compose 文件:


services:
  web:
    build:
      context: ./nginxfolder
      dockerfile: Dockerfile
    container_name: web
   
    ports:
      - 80:80
    networks:
      - my-network
    depends_on:
      - app

  app:
    build:
      context: ./twxservicesfolder
      dockerfile: Dockerfile
    container_name: app
 
    networks:
      - my-network
      
  spectrum:
    build:
      context: ./spectrumfolder
      dockerfile: Dockerfile
    container_name: spectrum

    networks:
      - my-network
      
  dgraph:
    build:
      context: ./dgraphfolder
      dockerfile: Dockerfile
    container_name: dgraph

    networks:
      - my-network
       
networks:
  my-network:
    driver: bridge

nginx 配置(default.conf):

upstream fastapi-backend 
    server app:8000;




    server 
        listen 80;
     

        location /  
            proxy_pass http://fastapi-backend;
            
            proxy_set_header Host $http_host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            
       
            proxy_redirect off;
            proxy_buffering off;
            client_body_buffer_size 100M;
            client_max_body_size 100M;
        
        
        location /stream1 
            proxy_pass http://spectrum:8501/stream1;
        
        location ^~ /stream1/static 
            proxy_pass http://spectrum:8501/stream1/static/;
        
        location ^~ /stream1/healthz 
            proxy_pass http://spectrum:8501/stream1/healthz;
        
        location ^~ /stream1/vendor 
            proxy_pass http://spectrum:8501/stream1/vendor;
        
        location /stream1/spectrum 
            proxy_pass http://spectrum:8501/stream1/spectrum;
            proxy_http_version 1.1;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $host;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_read_timeout 86400;
        
        
        location /stream2 
            proxy_pass http://dgraph:8503/stream2;
        
        location ^~ /stream2/static 
            proxy_pass http://dgraph:8503/stream2/static/;
        
        location ^~ /stream2/healthz 
            proxy_pass http://dgraph:8503/stream2/healthz;
        
        location ^~ /stream2/vendor 
            proxy_pass http://dgraph:8503/stream2/vendor;
        
        location /stream2/dgraph 
            proxy_pass http://dgraph:8503/stream2/dgraph;
            proxy_http_version 1.1;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $host;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_read_timeout 86400;
        

    

Dockerfile nginx 容器:

FROM nginx:latest

RUN rm /etc/nginx/conf.d/default.conf
COPY default.conf /etc/nginx/conf.d

Dockerfile 流光应用 dgraph 容器:

FROM python:3.8

COPY requirements.txt requirements.txt
RUN pip3 install -r requirements.txt

EXPOSE 8503
COPY app2.py /var/dashboard/app2.py
CMD streamlit run /var/dashboard/app2.py --server.address="0.0.0.0"  --server.port="8503" 

Dockerfile 流光应用频谱容器:

FROM python:3.8

COPY requirements.txt requirements.txt
RUN pip3 install -r requirements.txt

EXPOSE 8501
COPY app1.py /var/dashboard/app1.py
CMD streamlit run /var/dashboard/app1.py --server.address="0.0.0.0" --server.port="8501" 

Dockerfile fastapi app twxservices 容器:

FROM python:3.8-slim-buster

COPY requirements.txt requirements.txt
RUN pip3 install -r requirements.txt
COPY . .

ENV PYTHONUNBUFFERED 1

EXPOSE 8000
CMD ["uvicorn","app:app","--proxy-headers","--host","0.0.0.0","--forwarded-allow-ips","*"]

【问题讨论】:

也许location / 应该是最后的规则。 你知道为什么会这样吗? 我不确定它是否必须是最后一个,但许多工具(即Apache 中的virtual_hostFlaskDjango 中的routing)获得第一个匹配的位置/路由.我不确定location / 是否与if / == http://ip:80/stream2:if / in http://ip:80/stream2: 比较,但in 的方法可以匹配所有URL,http://ip:80/stream1http://ip:80/stream2 可以匹配location /,它可能会运行错误的应用程序。我会添加最短的location 作为最后一个。并且开头最长。 我试过这个并将fastapi的位置/移动到最后,但它没有帮助。仍然收到错误 404:未找到 可以直接联系http://spectrum:8501/stream1吗?也许应该没有stream1 - http://spectrum:8501/ 【参考方案1】:

我让它与这些 nginx 配置一起工作

    location /spectrum 
            proxy_pass http://spectrum1:8501/spectrum;
            proxy_http_version 1.1;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $host;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_read_timeout 86400;
        

还有流光应用的 Dockerfile 配置:

FROM python:3.8
COPY requirements.txt requirements.txt
RUN pip3 install -r requirements.txt

EXPOSE 8501
COPY app1.py /var/dashboard/app1.py
CMD streamlit run /var/dashboard/app1.py --server.address="0.0.0.0" --server.port="8501" --server.baseUrlPath="spectrum" --server.enableCORS=false --server.enableXsrfProtection=false

【讨论】:

这对我也有用。谢谢!

以上是关于docker中的Nginx,fastapi和streamlit - 反向代理不适用于streamlit的主要内容,如果未能解决你的问题,请参考以下文章

在 docker (FastAPI) 中使用 Wea​​syPrint 导出的 PDF 中的字体

docker compose fullstack example -- keycloak web grant-type: password

FastAPI 官方文档解读 (二)

FastAPI上手指南(三):路径参数和查询参数

FastAPI之嵌套依赖注入

我在将 docker mysql 与 fastapi 连接时遇到问题