Reputation: 145
I'm using nginx to pass requests to gunicorn for my flask app. For some reason my site example.com routes correctly but nothing else will, including example.com/index or example.com/bot/callback both of which are set up in my views.py. All routes other that example.com return a 404.
I believe it's an issue with my nginx setup because the nginx access logs register my requests but gunicorns access logs only show requests to '/'.
/etc/nginx/sites-available/example.com
(based on gunicorn's example)
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
(also based on gunicorn's example)
# 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'
Not sure if it matters but I have supervisor starting 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
What am I missing here? Thanks for your help.
Update 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)
All other logs are empty, including nginx_error. All the workers exits are because I either restarted or stopped and started the services.
Update 2
Apparently my site is somehow still sending nginx errors to /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
Upvotes: 2
Views: 2095
Reputation: 145
All the junk at the top of my nginx config
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;
}
should have been in my nginx.conf not my specific site config.
this next part needed deletion
server {
# if no Host match, close the connection to prevent host spoofing
listen 80 default_server;
return 444;
}
now i'm just getting regular old flask errors! lol
Upvotes: 1
Reputation: 28712
These questions are always difficult to figure out unless you provide any log messages in your nginx or gunicorn log. You may quickly find the issue there.
It sounds like nginx is working, but isn't proxying requests properly to your gunicorn server. I imagine the issue is in the upstream_app_server
nginx directive...it doesn't look like it's properly connected to gunicorn. Try changing that to this:
upstream app_server {
server 127.0.0.1:8001 fail_timeout=0;
}
If that's not the case, please provide contents of these files, as per the comments to your app:
/var/www/example.com/logs/nginx_error
/var/www/example.com/logs/gunicorn_error
It's quite possible you have more than one configuration error. The process is check the error logs, fix the bug, then try the app, then if the app isn't working check the error logs for the next bug :).
Upvotes: 1