Skip to main content
 首页 » 编程设计

nginx 仅将 base '/' url 传递给 gunicorn

2025年12月25日30yxwkf

我正在使用 nginx 将请求传递给我的 flask 应用程序的 gunicorn。出于某种原因,我的站点 example.com 路由正确,但没有其他内容,包括 example.com/index 或 example.com/bot/callback 两者都在我的 views.py 中设置。除了 example.com 之外的所有路由都返回 404。

我认为这是我的 nginx 设置的问题,因为 nginx 访问日志记录了我的请求,但 gunicorns 访问日志仅显示对“/”的请求。
/etc/nginx/sites-available/example.com (基于 gunicorn 的例子)

worker_processes 1; 
 
user www-data www-data; 
# 'user nobody nobody;' for systems with 'nobody' as a group instead 
pid /tmp/nginx.pid; 
access_log  /var/www/example.com/logs/nginx_access combined; 
error_log   /var/www/example.com/logs/nginx_error; 
 
events { 
  worker_connections 1024; # increase if you have lots of clients 
  accept_mutex off; # set to 'on' if nginx worker_processes > 1 
  # 'use epoll;' to enable for Linux 2.6+ 
  # 'use kqueue;' to enable for FreeBSD, OSX 
} 
 
http { 
  include mime.types; 
  # fallback in case we can't determine a type 
  default_type application/octet-stream; 
  sendfile on; 
 
  upstream app_server { 
    # fail_timeout=0 means we always retry an upstream even if it failed 
    # to return a good HTTP response 
 
    # for UNIX domain socket setups 
    server unix:/tmp/gunicorn.sock fail_timeout=0; 
 
    # for a TCP configuration 
    # server 192.168.0.7:8000 fail_timeout=0; 
  } 
 
  server { 
    # if no Host match, close the connection to prevent host spoofing 
    listen 80 default_server; 
    return 444; 
  } 
 
  server { 
    # use 'listen 80 deferred;' for Linux 
    # use 'listen 80 accept_filter=httpready;' for FreeBSD 
    listen 80; 
    client_max_body_size 4G; 
 
    # set the correct host(s) for your site 
    server_name example.com www.example.com; 
 
    keepalive_timeout 5; 
 
    # path for static files 
    root /var/www/example.com/public_html/app/static; 
 
    location / { 
      # checks for static file, if not found proxy to app 
      try_files $uri @proxy_to_app; 
    } 
 
    location @proxy_to_app { 
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
      # enable this if and only if you use HTTPS 
      # proxy_set_header X-Forwarded-Proto https; 
      proxy_set_header Host $http_host; 
      # we don't want nginx trying to do something clever with 
      # redirects, we set the Host: header above already. 
      proxy_redirect off; 
      proxy_pass http://127.0.0.1:8001; 
    } 
 
    #error_page 500 502 503 504 /500.html; 
    #location = /500.html { 
    #  root /path/to/app/current/public; 
    #} 
  } 
} 
/var/www/example.com/gunicorn.conf (也基于 gunicorn 的例子)
# basic setup 
name = 'example.com' 
user = 'www-data' 
group = 'www-data' 
bind = '127.0.0.1:8001' 
backlog = 2048 
pythonpath = '/var/www/example.com' 
 
# workers 
workers = 3 
worker_class = 'sync' 
worker_connections = 1000 
timeout = 30 
keepalive = 2 
backlog = 2048 
 
# logging 
loglevel = 'info' 
accesslog = '/var/www/example.com/logs/gunicorn_access' 
errorlog = '/var/www/example.com/logs/gunicorn_error' 
spew = 'False' 
 
# functions 
def post_fork(server, worker): 
    server.log.info("Worker spawned (pid: %s)", worker.pid) 
 
def pre_fork(server, worker): 
    pass 
 
def pre_exec(server): 
    server.log.info("Forked child, re-executing.") 
 
def when_ready(server): 
    server.log.info("Server is ready. Spawning workers") 
 
def worker_int(worker): 
    worker.log.info("worker received INT or QUIT signal") 
 
    ## get traceback info 
    import threading, sys, traceback 
    id2name = dict([(th.ident, th.name) for th in threading.enumerate()]) 
    code = [] 
    for threadId, stack in sys._current_frames().items(): 
        code.append("\n# Thread: %s(%d)" % (id2name.get(threadId,""), 
            threadId)) 
        for filename, lineno, name, line in traceback.extract_stack(stack): 
            code.append('File: "%s", line %d, in %s' % (filename, 
                lineno, name)) 
            if line: 
                code.append("  %s" % (line.strip())) 
    worker.log.debug("\n".join(code)) 
 
def worker_abort(worker): 
    worker.log.info("worker received SIGABRT signal") 
/var/www/example.com/public_html/app/__init__.py
from flask import Flask 
import logging 
from werkzeug.contrib.fixers import ProxyFix 
 
 
app = Flask(__name__) 
app.config.from_pyfile('config.py') 
app.wsgi_app = ProxyFix(app.wsgi_app) 
 
logging.basicConfig(filename='../../logs/flask', level=logging.DEBUG) 
 
import views 
 
 
if __name__ == '__main__': 
    app.run() 
/var/www/example.com/public_html/app/views.py
from flask import abort, flash, jsonify, redirect, render_template, request, url_for 
 
from __init__ import app 
from automate import activate 
 
 
 
@app.route('/') 
@app.route('/index') 
def index(): 
    return 'Example Index' 
 
 
@app.route('/bot/callback', methods=['GET', 'POST']) 
def bot_callback(): 
    #callback = get_callback(request.json) 
    activate(request.json) 
    return 'SuccessBot' 

不确定这是否重要,但我有主管开始 gunicorn。
/etc/supervisor/conf.d/example.com.conf
[program:example.com] 
command=/home/user/.virtualenvs/example.com/bin/gunicorn -c /var/www/example.com/gunicorn.conf __init__:app 
directory=/var/www/example.com/public_html/app 
user=www-data 
group=www-data 
stdout_logfile=/var/www/example.com/logs/supervisor 
autostart=true 
autorestart=true 
redirect_stderr=true 
stopsignal=INT 

我在这里想念什么?谢谢你的帮助。

更新 1:

'/var/www/example.com/logs/nginx_access'
216.248.228.41 - - [17/Dec/2015:11:43:06 -0700] "GET / HTTP/1.1" 200 51 "-" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36" 
216.248.228.41 - - [17/Dec/2015:11:43:11 -0700] "GET /index HTTP/1.1" 404 208 "-" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36" 
216.248.228.41 - - [17/Dec/2015:11:43:16 -0700] "GET /bot/callback HTTP/1.1" 404 208 "-" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36" 
216.248.228.41 - - [17/Dec/2015:11:43:19 -0700] "GET / HTTP/1.1" 200 51 "-" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36" 
216.248.228.41 - - [17/Dec/2015:12:04:12 -0700] "GET / HTTP/1.1" 200 51 "-" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36" 
216.248.228.41 - - [17/Dec/2015:12:04:18 -0700] "GET /bot/callback HTTP/1.1" 404 208 "-" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36" 
216.248.228.41 - - [17/Dec/2015:12:04:22 -0700] "GET / HTTP/1.1" 200 51 "-" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36" 
216.248.228.41 - - [17/Dec/2015:12:14:45 -0700] "GET /index HTTP/1.1" 404 208 "-" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36" 
216.248.228.41 - - [17/Dec/2015:12:14:58 -0700] "GET / HTTP/1.1" 200 51 "-" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36" 
216.248.228.41 - - [17/Dec/2015:12:57:21 -0700] "GET / HTTP/1.1" 200 51 "-" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36" 
216.248.228.41 - - [17/Dec/2015:12:57:21 -0700] "GET /favicon.ico HTTP/1.1" 404 208 "http://www.example.com/" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36" 
216.248.228.41 - - [17/Dec/2015:12:57:26 -0700] "GET /index HTTP/1.1" 404 208 "-" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36" 
216.248.228.41 - - [17/Dec/2015:12:57:30 -0700] "GET /bot/callback HTTP/1.1" 404 208 "-" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36" 

'/var/www/example.com/logs/gunicorn_access'
216.248.228.41 - - [17/Dec/2015:11:43:06 -0700] "GET / HTTP/1.0" 200 20 "-" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36" 
216.248.228.41 - - [17/Dec/2015:11:43:19 -0700] "GET / HTTP/1.0" 200 20 "-" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36" 
216.248.228.41 - - [17/Dec/2015:12:04:12 -0700] "GET / HTTP/1.0" 200 20 "-" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36" 
216.248.228.41 - - [17/Dec/2015:12:04:22 -0700] "GET / HTTP/1.0" 200 20 "-" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36" 
216.248.228.41 - - [17/Dec/2015:12:14:58 -0700] "GET / HTTP/1.0" 200 20 "-" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36" 
216.248.228.41 - - [17/Dec/2015:12:57:21 -0700] "GET / HTTP/1.0" 200 20 "-" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36" 

'/var/www/example.com/logs/gunicorn_error'
[2015-12-17 11:41:42 -0700] [13894] [INFO] Starting gunicorn 19.4.1 
[2015-12-17 11:41:42 -0700] [13894] [INFO] Listening at: http://127.0.0.1:8001 (13894) 
[2015-12-17 11:41:42 -0700] [13894] [INFO] Using worker: sync 
[2015-12-17 11:41:42 -0700] [13894] [INFO] Server is ready. Spawning workers 
[2015-12-17 11:41:42 -0700] [13906] [INFO] Booting worker with pid: 13906 
[2015-12-17 11:41:42 -0700] [13906] [INFO] Worker spawned (pid: 13906) 
[2015-12-17 11:41:42 -0700] [13908] [INFO] Booting worker with pid: 13908 
[2015-12-17 11:41:42 -0700] [13908] [INFO] Worker spawned (pid: 13908) 
[2015-12-17 11:41:42 -0700] [13910] [INFO] Booting worker with pid: 13910 
[2015-12-17 11:41:42 -0700] [13910] [INFO] Worker spawned (pid: 13910) 
[2015-12-17 12:03:04 -0700] [13894] [INFO] Handling signal: int 
[2015-12-17 12:03:04 -0700] [13906] [INFO] worker received INT or QUIT signal 
[2015-12-17 12:03:04 -0700] [13908] [INFO] worker received INT or QUIT signal 
[2015-12-17 12:03:04 -0700] [13910] [INFO] worker received INT or QUIT signal 
[2015-12-17 12:03:04 -0700] [13908] [INFO] Worker exiting (pid: 13908) 
[2015-12-17 12:03:04 -0700] [13906] [INFO] Worker exiting (pid: 13906) 
[2015-12-17 12:03:04 -0700] [13910] [INFO] Worker exiting (pid: 13910) 
[2015-12-17 12:03:04 -0700] [13894] [INFO] Shutting down: Master 
[2015-12-17 12:03:10 -0700] [14034] [INFO] Starting gunicorn 19.4.1 
[2015-12-17 12:03:10 -0700] [14034] [INFO] Listening at: http://127.0.0.1:8001 (14034) 
[2015-12-17 12:03:10 -0700] [14034] [INFO] Using worker: sync 
[2015-12-17 12:03:10 -0700] [14034] [INFO] Server is ready. Spawning workers 
[2015-12-17 12:03:10 -0700] [14040] [INFO] Booting worker with pid: 14040 
[2015-12-17 12:03:10 -0700] [14040] [INFO] Worker spawned (pid: 14040) 
[2015-12-17 12:03:10 -0700] [14043] [INFO] Booting worker with pid: 14043 
[2015-12-17 12:03:10 -0700] [14043] [INFO] Worker spawned (pid: 14043) 
[2015-12-17 12:03:10 -0700] [14044] [INFO] Booting worker with pid: 14044 
[2015-12-17 12:03:10 -0700] [14044] [INFO] Worker spawned (pid: 14044) 
[2015-12-17 12:57:03 -0700] [14034] [INFO] Handling signal: int 
[2015-12-17 12:57:03 -0700] [14040] [INFO] worker received INT or QUIT signal 
[2015-12-17 12:57:03 -0700] [14043] [INFO] worker received INT or QUIT signal 
[2015-12-17 12:57:03 -0700] [14044] [INFO] worker received INT or QUIT signal 
[2015-12-17 12:57:03 -0700] [14040] [INFO] Worker exiting (pid: 14040) 
[2015-12-17 12:57:03 -0700] [14044] [INFO] Worker exiting (pid: 14044) 
[2015-12-17 12:57:03 -0700] [14043] [INFO] Worker exiting (pid: 14043) 
[2015-12-17 12:57:03 -0700] [14034] [INFO] Shutting down: Master 
[2015-12-17 12:57:09 -0700] [14420] [INFO] Starting gunicorn 19.4.1 
[2015-12-17 12:57:09 -0700] [14420] [INFO] Listening at: http://127.0.0.1:8001 (14420) 
[2015-12-17 12:57:09 -0700] [14420] [INFO] Using worker: sync 
[2015-12-17 12:57:09 -0700] [14420] [INFO] Server is ready. Spawning workers 
[2015-12-17 12:57:09 -0700] [14426] [INFO] Booting worker with pid: 14426 
[2015-12-17 12:57:09 -0700] [14426] [INFO] Worker spawned (pid: 14426) 
[2015-12-17 12:57:09 -0700] [14429] [INFO] Booting worker with pid: 14429 
[2015-12-17 12:57:09 -0700] [14429] [INFO] Worker spawned (pid: 14429) 
[2015-12-17 12:57:09 -0700] [14431] [INFO] Booting worker with pid: 14431 
[2015-12-17 12:57:09 -0700] [14431] [INFO] Worker spawned (pid: 14431) 

所有其他日志都是空的,包括 nginx_error。
所有 worker 退出都是因为我重新启动或停止并启动了服务。

更新 2

显然我的网站仍然以某种方式将 nginx 错误发送到/var/log/nginx/error.log
/var/log/nginx/error.log
2015/12/17 12:56:57 [emerg] 14404#0: "worker_processes" directive is not allowed here in /etc/nginx/sites-enabled/example.com:1 

请您参考如下方法:

除非您在 nginx 或 gunicorn 日志中提供任何日志消息,否则这些问题总是很难弄清楚。您可能会很快找到那里的问题。

听起来 nginx 正在工作,但没有正确地将请求代理到您的 gunicorn 服务器。我想问题出在 upstream_app_server nginx 指令...看起来它没有正确连接到 gunicorn。尝试将其更改为:

upstream app_server { 
    server 127.0.0.1:8001 fail_timeout=0; 
} 

如果不是这种情况,请根据对您的应用的评论提供这些文件的内容:
/var/www/example.com/logs/nginx_error 
/var/www/example.com/logs/gunicorn_error 

您很可能有不止一个配置错误。该过程是检查错误日志,修复错误,然后尝试应用程序,然后如果应用程序不工作,请检查错误日志以查找下一个错误:)。