docker - 如何配置 NGINX 以从 UNIX 套接字服务 ASGI?

标签 docker nginx gunicorn supervisord asgi

我无法通过 docker 容器通过本地主机上 NGINX 上的 Unix 套接字连接在 ASGI + Gunicorn 上运行的应用程序。
假设我在 docker 容器中并运行 NGINX:

/usr/sbin/nginx
我可以打开http://localhost/api/v1/items并从 NGINX 获得 404,这意味着它至少正在运行。
执行正在运行的 docker 服务,我可以使用以下命令启动 Gunicorn:
gunicorn app.main:app --name asgi --workers 3 --user=root --group=root --bind=unix:///tmp/asgi.sock --log-level=debug --log-file=- -k uvicorn.workers.UvicornWorker -c /gunicorn_conf.py
Gunicorn 正确启动,并且与另一个 exec 一起,我可以 curl 我已经绑定(bind)到的 UNIX 套接字并收到 200 响应。
curl --unix-socket ///tmp/asgi.sock http://localhost/api/v1/items
我认为这意味着我在将流量定向到 http://localhost/api/v1/items 的 NGINX 配置中存在一些差异。
nginx.conf
daemon off;
user  nginx;
worker_processes 1;
pid        /var/run/nginx.pid;
events {
    worker_connections 1024;
}

http {
  access_log /dev/stdout;
  upstream asgi {
    server unix:/tmp/asgi.sock fail_timeout=0;
  }

  server {
    listen   80;
    server_name localhost;
    client_max_body_size 4G;
    location / {
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      proxy_redirect off;
      proxy_pass http://asgi;
    }

  }
}
gunicorn_conf.py
import json
import multiprocessing
import os

workers_per_core_str = os.getenv("WORKERS_PER_CORE", "1")
web_concurrency_str = os.getenv("WEB_CONCURRENCY", None)
host = os.getenv("HOST", "unix")
port = os.getenv("PORT", "///tmp/asgi.sock")
bind_env = os.getenv("BIND", None)
use_loglevel = os.getenv("LOG_LEVEL", "info")
if bind_env:
    use_bind = bind_env
else:
    use_bind = f"{host}:{port}"

cores = multiprocessing.cpu_count()
workers_per_core = float(workers_per_core_str)
default_web_concurrency = workers_per_core * cores
if web_concurrency_str:
    web_concurrency = int(web_concurrency_str)
    assert web_concurrency > 0
else:
    web_concurrency = max(int(default_web_concurrency), 2)

# Gunicorn config variables
loglevel = use_loglevel
workers = web_concurrency
bind = use_bind
keepalive = 120
errorlog = "-"

# For debugging and testing
log_data = {
    "loglevel": loglevel,
    "workers": workers,
    "bind": bind,
    # Additional, non-gunicorn variables
    "workers_per_core": workers_per_core,
    "host": host,
    "port": port,
}
print(json.dumps(log_data))

最佳答案

解决了我的问题并使用更改的文件更新了原始问题。主要问题是为 supervisord 使用守护进程关闭以允许 NGINX 和 Gunicorn 运行,并将 NGINX 的服务器配置放在 html block 中。

在我原来的帖子中,我的 NGINX 配置在 http block 中没有服务器,我更新了我的日志以写入控制台,尽管假设文件位置存在,这没什么区别。
我还通过 Supervisord 启动 NGINX 和 Gunicorn,因为我觉得这超出了问题的范围。但是,我现在可以使用 Supervisord 启动这两个进程,但我必须 daemon off;到 NGINX 配置以使其正常工作;没有它,进程会说端口已经在使用中。
我用我最新版本的配置更新了我的帖子,包括 supervisor.ini
主管.ini

[supervisord]
nodaemon=true

[program:asgi]
command=gunicorn app.main:app --name asgi --workers 3 --user=root --group=root --bind=unix:/tmp/asgi.sock --log-level=debug --log-file=- -k uvicorn.workers.UvicornWorker -c /gunicorn_conf.py
user = root ; User to run as
autostart=true
autorestart=true
stdout_logfile=/dev/stdout ; Where to write log messages
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
environment=LANG=en_US.UTF-8,LC_ALL=en_US.UTF-8 ; Set UTF-8 as default encoding

[program:nginx]
command=/usr/sbin/nginx -c /etc/nginx/conf.d/nginx.conf
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
# Graceful stop, see http://nginx.org/en/docs/control.html
stopsignal=QUIT
运行 supervisord:/usr/bin/supervisord -c /etc/supervisor.d/supervisord.ini要自己尝试一下,请参阅我为此创建的 github 存储库 application .

关于docker - 如何配置 NGINX 以从 UNIX 套接字服务 ASGI?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57532987/

相关文章:

node.js - 可以在 docker 容器中运行 npm/node,但不能在 dockerfile 中运行

linux - 301重定向DNS问题

reactjs - Nextjs getInitialProps无法与NGINX一起使用

api - nginx proxy_pass for get request api call with parameters

Gunicorn、Flask 和 SQLAlchemy : Concurrent Requests

docker - 使用 docker-compose 和多阶段 Dockerfile 共享构建逻辑

nginx - 具有相同域的 80 端口上的多个 Docker 容器

docker - Docker-客户端版本比服务器更新

ruby-on-rails - 将 JRuby 与 Rails 3.2 结合使用

python - 将 Gunicorn 部署到 Heroku 后 Django 的性能下降