docker-compose 中的快速 api 和 nginx 在连接到上游时显示 connect() 失败(111:连接被拒绝),客户端:172.27.0.1,服务器:

ryo*_*ake 2 nginx docker dockerfile docker-compose fastapi

fastapi nginx 模板

\n

源代码

\n

它是快速的 api 和 nginx 模板,但目前它不能按我的预期工作。\n当你卷曲本地主机时,它响应 502 bad gateway instaed of hello world 这是在 main.py 中定义的...

\n

docker 日志 web 显示connect() failed (111: Connection refused) while connecting to upstream, client: 172.27.0.1, server:在 nginx 容器中。

\n

但为什么 ??你如何修复这个错误?

\n

文件树

\n
.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 Dockerfile\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 README.md\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 docker-compose.yml\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 main.py\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 nginx\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 Dockerfile\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 nginx.conf\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 requirements.txt\n
Run Code Online (Sandbox Code Playgroud)\n

构建并启动

\n
    \n
  1. docker-compose up -d --build

    \n
  2. \n
  3. docker logs ps -a

    \n
  4. \n
\n
CONTAINER ID   IMAGE                         COMMAND                  CREATED         STATUS         PORTS                                       NAMES\ncb79d9efaf75   fast-api-nginx-template_web   "/docker-entrypoint.\xe2\x80\xa6"   4 minutes ago   Up 4 minutes   0.0.0.0:80->80/tcp, :::80->80/tcp           web\n6b049c395508   fast-api-nginx-template_api   "uvicorn main:app --\xe2\x80\xa6"   4 minutes ago   Up 4 minutes   0.0.0.0:8000->8000/tcp, :::8000->8000/tcp   api\n
Run Code Online (Sandbox Code Playgroud)\n
    \n
  1. curl localhost
  2. \n
\n
<html>\n<head><title>502 Bad Gateway</title></head>\n<body>\n<center><h1>502 Bad Gateway</h1></center>\n<hr><center>nginx/1.21.1</center>\n</body>\n</html>\n
Run Code Online (Sandbox Code Playgroud)\n
    \n
  1. docker logs web
  2. \n
\n
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration\n/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/\n/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh\n10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf\n10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf\n/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh\n/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh\n/docker-entrypoint.sh: Configuration complete; ready for start up\n2021/08/28 13:58:37 [error] 31#31: *8 connect() failed (111: Connection refused) while connecting to upstream, client: 172.27.0.1, server: 127.0.0.1, request: "GET / HTTP/1.1", upstream: "http://172.27.0.3:8000/", host: "localhost"\n172.27.0.1 - - [28/Aug/2021:13:58:37 +0000] "GET / HTTP/1.1" 502 157 "-" "curl/7.64.1"\n
Run Code Online (Sandbox Code Playgroud)\n
    \n
  1. docker logs api
  2. \n
\n
INFO:     Started server process [1]\nINFO:     Waiting for application startup.\nINFO:     Application startup complete.\nINFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)\n
Run Code Online (Sandbox Code Playgroud)\n

docker 撰写

\n

docker 撰写

\n
version: "3.9"\nservices:\n    web:\n        container_name: web\n        build: nginx\n        ports:\n          - 80:80\n        depends_on:\n          - api\n        networks:\n          - local-net\n    api:\n        container_name: api\n        build: .\n        ports:\n          - 8000:8000\n        networks:\n          - local-net\n        expose:\n          - 8000\nnetworks:\n  local-net:\n    driver: bridge\n
Run Code Online (Sandbox Code Playgroud)\n

网络

\n

nginx/Dockerfile

\n
FROM nginx\nRUN apt-get update \nCOPY nginx.conf /etc/nginx/nginx.conf\n
Run Code Online (Sandbox Code Playgroud)\n

nginx/nginx.conf

\n
worker_processes 1;\n\nevents {\n  worker_connections 1024; \n  accept_mutex off; \n  use epoll;\n}\n\nhttp {\n    include mime.types;\n    upstream app_serve {\n        server web:8000;\n    }\n    access_log /var/log/nginx/access.log;\n    error_log /var/log/nginx/error.log;\n    server {\n        listen 80 ipv6only=on;\n        server_name 127.0.0.1;   \n        location / {\n            proxy_pass http://app_serve; \n            proxy_set_header Host               $host;\n            proxy_set_header X-Real-IP          $remote_addr;\n            proxy_set_header X-Forwarded-For    $proxy_add_x_forwarded_for;\n            proxy_set_header X-Forwarded-Proto  $scheme;\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

应用程序编程接口

\n

Dockerfile

\n
ARG BASE_IMAGE=python:3.8-buster                                                                                \nFROM $BASE_IMAGE                                                                                                     \n\nRUN apt-get -y update && \\                                                                                           \n    apt-get install -y --no-install-recommends \\                                                                     \n    build-essential \\                                                                                                \n    openssl libssl-dev \\                                                                                             \n    && apt-get clean \\                                                                                               \n    && rm -rf /var/lib/apt/lists/*                                                                                   \n\nARG USER_NAME=app\nARG USER_UID=1000\nARG PASSWD=password\n\nRUN useradd -m -s /bin/bash -u $USER_UID $USER_NAME && \\\n    gpasswd -a $USER_NAME sudo && \\\n    echo "${USER_NAME}:${PASSWD}" | chpasswd && \\\n    echo "${USER_NAME} ALL=(ALL) ALL" >> /etc/sudoers\n\nCOPY ./ /app\nRUN chown -R ${USER_NAME}:${USER_NAME} /app\n\nUSER $USER_NAME\nWORKDIR /app\nENV PATH $PATH:/home/${USER_NAME}/.local/bin\n\nRUN pip3 install --user --upgrade pip \nRUN pip3 install --user -r requirements.txt\nRUN rm -rf ~/.cache/pip/* \n\nEXPOSE 8000\n\n# Execute\nCMD ["uvicorn", "main:app", "--host", "127.0.0.1" ,"--port" ,"8000"]\n
Run Code Online (Sandbox Code Playgroud)\n

主要.py

\n
from typing import Optional\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get("/")\ndef load_root():\n    return {"Hello": "World"}\n\n@app.get("/items/{item_id}")\ndef load_item(item_id: int, q: Optional[str] = None):\n    return {"item_id": item_id, "q": q}\n\n
Run Code Online (Sandbox Code Playgroud)\n

Rao*_*zur 7

乍一看,我认为这是因为你已经将 uvicorn 绑定到了127.0.0.1,因此,你需要在 api 容器中添加一个反向代理,以便在外部提供服务(除非你的容器在主机网络中运行,但默认情况下它是一个桥接器) )。

绑定 uvicorn 应该0.0.0.0可以解决这个问题。更具体地说:

CMD ["uvicorn", "main:app", "--host", "0.0.0.0" ,"--port" ,"8000"]

为了确认这一点,我在 和 中运行了我的 fastapi0.0.0.0容器127.0.0.1

$ podman ps --no-trunc
CONTAINER ID                                                      IMAGE                                 COMMAND                                  CREATED        STATUS            PORTS                   NAMES
7121420b401ee1803474ff156280a5b5b154c55ae0fd47e1976d8fe9e5331c72  localhost/fastapi-mvc-template:test   /usr/bin/fastapi serve --host 127.0.0.1  4 minutes ago  Up 4 minutes ago  0.0.0.0:8000->8000/tcp  test
dd35d89f161f818e5b34c138bd3d42bdb4d84100b76999d4fc2444c7d0d1a1d9  localhost/fastapi-mvc-template:0.1.0  /usr/bin/fastapi serve --host 0.0.0.0    2 minutes ago  Up 2 minutes ago  0.0.0.0:9000->8000/tcp  test_ok
$ curl localhost:8000/api/ready
curl: (56) Recv failure: Connection reset by peer
$ curl localhost:9000/api/ready
{"status":"ok"}
Run Code Online (Sandbox Code Playgroud)