nginx 仅将基本 '/' url 传递给gunicorn

标签 nginx flask gunicorn supervisord

我正在使用 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。 所有工作人员退出都是因为我重新启动或停止并启动了服务。


更新2

显然我的网站仍然在向/var/log/nginx/error.log 发送 nginx 错误

/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

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

关于nginx 仅将基本 '/' url 传递给gunicorn,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34342997/

相关文章:

NGINX 有条件地打开/关闭 proxy_intercept_errors

node.js - Nginx 配置 : Two domain names for one nodeJS app

python - flask ,mod_wsgi,apache : Importerror:

python - 导入时模拟模块全局变量

django - Nginx 不支持 Django 管理静态文件

django - AWS 上的 nginx 和 Gunicorn 出现 504 超时

wordpress - 从Apache到Nginx : wordpress rewrite rule

php - Nginx 不会在 WSL 上执行 php 文件。我怎样才能解决这个问题?

javascript - 从 JS 文件将 Chart.js 折线图添加到 Jinja2/Flask html 页面

python - 改进在 Python 3.7 标准环境中运行 Django 的 Google App Engine 的冷启动时间