I've been doing Flask microblog tutorial by Miguel Grinberg and have got stuck on trying to deploy to my linux VPS.(http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-xvii-deployment-on-linux-even-on-the-raspberry-pi)
I'm getting a 500 internal server error produced by apache, not flask, and I can't figure it out. It works when running it using the interpreter, but I can't launch it with apache. I've read through so many google searches and SO questions and I'm lost. I'm relatively new to linux/python/flask but I'm willing to learn if someone can point me in the right direction.
Setup:
I'm running a fresh CentOS 6.6 install with Python 2.6.6 and Apache 2.2.15. I'm running it off sqlite. I'm using these flask modules if you're interested: http://pastebin.com/bPnH83bs
Basic App Structure: (left out things for brevity)
Located in: /home/apps/portal
I have the whole directory chown'd to: chown -R apps:apache
User 'apps' is a member of the apache group
flask\ (virtualenv)
app\
static\
templates\
__init__.py
models.py
views.py
forms.py
decorators.py
db_repository\
search.db\
tmp\
app.db
config.py
run.py
runp.py
runp-sqlite.fcgi
Apache conf file setup:
FcgidIPCDir /tmp
AddHandler fcgid-script .fcgi
<VirtualHost *:80>
DocumentRoot /home/apps/portal/app/static
Alias /static /home/apps/portal/app/static
ScriptAlias / /home/apps/portal/runp-sqlite.fcgi/
ErrorLog /var/log/httpd/error_log
CustomLog /var/log/httpd/access_log combined
</VirtualHost>
runp-sqlite.fcgi Contents:
#!flask/bin/python
from flipflop import WSGIServer
from app import app
if __name__ == '__main__':
WSGIServer(app).run()
Error from apache logs when trying to access page and getting 500 error:
[Mon Dec 15 22:21:44 2014] [warn] [client *.*.*.*] mod_fcgid: read data timeout in 40 seconds
[Mon Dec 15 22:21:44 2014] [error] [client *.*.*.*] Premature end of script headers: runp-sqlite.fcgi
Error when I run "runp-sqlite.fcgi" from the console:
[root#**** portal]# sudo -u apache ./runp-sqlite.fcgi
Traceback (most recent call last):
File "./runp-sqlite.fcgi", line 6, in <module>
WSGIServer(app).run()
File "/home/apps/portal/flask/lib/python2.6/site-packages/flipflop.py", line 938, in run
sock.getpeername()
socket.error: [Errno 88] Socket operation on non-socket
Things I've checked:
I've disabled SELinux as it was causing a different problem, didn't fix this issue.
Checked that folders were chown'd to the correct user/group.
Checked that '/etc/httpd/conf/httpd.conf' and '/etc/sysconfig/httpd' PIDFILE locations are correct
Checked that iptables is accepting traffic to ports 80 and 5000(for testing). If I remove the apache configuration I've added I am successfully serving from /var/www/html
Lots and lots of googling and playing around
Sorry for the wall of text, I just don't know what you'll need to see. If anyone can help with this I'll be really greatful. If it's something dumb, I apologise. :)
Update 1:
Changed runp-sqlite.fcgi to call virtualenv:
#!flask/bin/python
activate_this = '/home/apps/portal/flask/bin/activate_this.py')
execfile(activate_this, dict(__file__=activate_this))
from flipflop import WSGIServer
from app import app
if __name__ == '__main__':
WSGIServer(app).run()
Now apache errors_log has a new error message:
[Fri Dec 19 13:43:03 2014] [notice] Apache/2.2.15 (Unix) DAV/2 mod_fcgid/2.3.9 PHP/5.3.3 mod_wsgi/3.2 Python/2.6.6 configured -- resuming normal operations
[Fri Dec 19 13:43:05 2014] [warn] [client 110.143.38.80] (104)Connection reset by peer: mod_fcgid: error reading data from FastCGI server
[Fri Dec 19 13:43:05 2014] [error] [client 110.143.38.80] Premature end of script headers: runp-sqlite.fcgi
Do you have Flask installed in a virtuelenv? If so, the problem may be that your WSGI file isn't activating it. This causes an ImportError or something similar when Apache tries to serve the site, which results in a not-very-helpful 500 Error.
The fix is to activate the virtualenv in your WSGI file before importing the app like this:
#!/bin/python
VENV_DIR = 'your_app/your_venv'
activate_this = os.path.join(VENV_DIR, 'bin', 'activate_this.py')
execfile(activate_this, dict(__file__=activate_this))
from flipflop import WSGIServer
from app import app
if __name__ == '__main__':
WSGIServer(app).run()
See also this previous SO question: Running Python from a virtualenv with Apache/mod_wsgi, on Windows
Related
I'm trying to run a very simple flask app on a port on a network machine. My current server code looks like this:
from flask import Flask
import json
app = Flask(__name__)
#app.route('/my_route')
def my_route():
return json.dumps({'data': 'this is an example'})
Say that the IP of the machine on my network was 123.123.123.123, and I wanted to run my app on port 5000. I want to be able to either navigate in a browser or make a simple HTTP request to 123.123.123.123:5000/my_route and get a JSON response.
I unsuccessfully tried to follow the mod_wsgi Flask documentation. I was getting 500 Internal Server errors show after editing httpd.conf with a directive like this:
Listen 5000
NameVirtualHost *:5000
<VirtualHost *:5000>
ServerName gcr_app
WSGIDaemonProcess gcr_app user=apache threads=5
WSGIScriptAlias / /var/www/gcr_app/gcr_app.wsgi
<Directory /var/www/gcr_app>
WSGIProcessGroup gcr_app
WSGIApplicationGroup %{GLOBAL}
Order deny,allow
Allow from all
</Directory>
</VirtualHost>
and restarting the httpd service.
What am I doing wrong here? Other information:
RHEL 6.7
Python 3.4.4
Flask 0.12
Apache version:
$ /usr/sbin/httpd -v
Server version: Apache/2.2.15 (Unix)
Server built: Feb 4 2016 08:22:15
Let me know if there's other helpful information I could provide.
Error Log Info
[Mon Jan 30 17:55:22 2017] [error] [client x.x.x.x] (13)Permission denied: mod_wsgi (pid=2118): Unable to connect to WSGI daemon process 'gcr_app' on '/etc/httpd/logs/wsgi.2109.0.1.sock' after multiple attempts.
[Mon Jan 30 17:55:26 2017] [error] [client x.x.x.x] (13)Permission denied: mod_wsgi (pid=2114): Unable to connect to WSGI daemon process 'gcr_app' on '/etc/httpd/logs/wsgi.2109.0.1.sock' after multiple attempts.
[Mon Jan 30 17:55:27 2017] [error] [client x.x.x.x] (13)Permission denied: mod_wsgi (pid=2115): Unable to connect to WSGI daemon process 'gcr_app' on '/etc/httpd/logs/wsgi.2109.0.1.sock' after multiple attempts.
[Mon Jan 30 17:55:46 2017] [error] [client x.x.x.x] (13)Permission denied: mod_wsgi (pid=2113): Unable to connect to WSGI daemon process 'gcr_app' on '/etc/httpd/logs/wsgi.2109.0.1.sock' after multiple attempts.
[Mon Jan 30 17:57:48 2017] [error] [client x.x.x.x] File does not exist: /var/www/html/gcr_distance
[Mon Jan 30 17:57:48 2017] [error] [client x.x.x.x] File does not exist: /var/www/html/favicon.ico, referer: http://x.x.x.x/my_route
[Mon Jan 30 18:43:49 2017] [error] [client x.x.x.x] (13)Permission denied: mod_wsgi (pid=2116): Unable to connect to WSGI daemon process 'gcr_app' on '/etc/httpd/logs/wsgi.2109.0.1.sock' after multiple attempts.
Thanks
Thanks to everyone who commented on this question. It turns out that I had an issue with the Python version that I was using to run Flask with and the Python version that mod_wsgi. Since I'm using RHEL 6.7, mod_wsgi had been installed with Python 2.7, whereas I had written my application using Python 3.4. This meant that mod_wsgi was having trouble importing the modules that I was using.
On top of this, I hadn't imported my Flask app properly. I had this in my .wsgi file:
import my_app as application
instead of:
from my_app import app as application
after changing some of the Python code to be 2.7 compatible and fixing my .wsgi file, I was able to run the Flask app on the port that I wanted.
I'll update this answer if installing mod_wsgi with the pip of my Python 3.4 version works for running the Flask app with Python 3.4.
I am developing a Flask application on CentOS 6.6 on Apache and Mysql. It is modified from The Flask Megatutorial. I am able to create normally the database, however when I try to access it from my browser I get 500 internal server error and this in the error_log file:
content type: text/html
<h1>Hello world!</h1>
[Sun May 03 18:39:53 2015] [error] [client my.ip.add.res] (104)Connection reset by peer: mod_fcgid: error reading data from FastCGI server
[Sun May 03 18:39:53 2015] [error] [client my.ip.add.res] Premature end of script headers: runp-mysql.fcgi
This is after I've edited down the runp-mysql.fcgi file to this:
#!flask/bin/python
#encoding=UTF-8
#import os
print "content type: text/html\n\n"
print ""
print "<h1>Hello world!</h1>"
Running this from the command line completes correctly.
My httpd.conf file ends with this:
FcgidIPCDir /tmp
AddHandler fcgid-script .fcgi
<VirtualHost *:80>
DocumentRoot /home/apps/my_app/app/static
Alias /static /home/apps/my_app/app/static
ScriptAlias / /home/apps/my_app/runp-mysql.fcgi/
</VirtualHost>
I was doing the same and a major issue was the permissions on the file. make sure it is executable and not read only.
Also I do not think that the runp-mysql.fcgi is where you want to do your printing. It should be in the views file. This is where you should have the connection to the your mysql database then start the wscgi server.
This is a very loose answer based on my actual problem and I am only uploading it in case someone else follows the same tutorial and also has a problem with deployment.
The gist of it is that under the python version I used (2.7) for deployment the flipflop module did not work and I had to use flup instead. For anyone getting the same error - try it, it might work.
I'm having an issue deploying my Flask app with Apache (mod_wsgi)
and gevent on a shared hosting (Webfaction).
The application works fine in the development server provided by Flask, but when I
try to deploy it I get the following error in log file:
[Tue Mar 13 15:48:24 2012] [error] Traceback (most recent call last):
[Tue Mar 13 15:48:24 2012] [error] File "evdns.pxi", line 78, in gevent.core.__evdns_callback (gevent/core.c:6300)
[Tue Mar 13 15:48:24 2012] [error] File "/home/username/.virtualenvs/staging/lib/python2.7/site-packages/gevent/hub.py", line 297, in switch_args
[Tue Mar 13 15:48:24 2012] [error] File "/home/username/.virtualenvs/staging/lib/python2.7/site-packages/gevent/hub.py", line 290, in switch
[Tue Mar 13 15:48:24 2012] [error] File "/home/username/.virtualenvs/staging/lib/python2.7/site-packages/gevent/hub.py", line 135, in get_hub
[Tue Mar 13 15:48:24 2012] [error] NotImplementedError: gevent is only usable from a single thread
I need gevent because I'm using the python-requests' async module to
make concurrent HTTP requests.
I tried to Google around but the only advice I found is to to call
from gevent import monkey
monkey.patch_all()
something that I already do in my code.
The value of WSGIDaemonProcess is:
WSGIDaemonProcess myapp processes=5 python-path=/home/myusername/webapps/myapp/lib/python2.7 threads=1
Here is my httpd.conf: http://pastebin.com/eWygicJH
Anybody has any advice to solve this issue?
It seems like i found the solution myself. The following directive solved my issue:
WSGIApplicationGroup %{GLOBAL}
The idea comes from another answer where it is suggested to set WSGIApplicationGroup to GLOBAL to solve a problem with a WSGI process that keep crashing. From WSGI documentation:
To force a specific WSGI application to be run within the very first
Python sub interpreter created when Python is initialised, the
WSGIApplicationGroup directive should be used and the group set to
'%{GLOBAL}'.
Cannot fully understand why this directive solve my issue but it does. I will be more than happy if someone is able to explain this to me in plain English ;-)
Try replacing monkey.patch_all() with monkey.patch_all(thread=False). If it's really the threading module which is causing the trouble when patched, this should solve it. request does not use threading.
I posted below answer on https://serverfault.com/a/869625/355861
apache mod_wsgi is not currently compatible with gevent. For AWS elastic beanstalk with Apache, I used async_mode="threading" for Flask and it works well. Note, threading has less performance than gevent.
https://flask-socketio.readthedocs.io/en/latest/#deployment
app = Flask(__name__,static_folder='static')
socketio = SocketIO(app, async_mode="threading")
Note that Flask can run standalone with gevent.
app = Flask(__name__,static_folder='static')
socketio = SocketIO(app, async_mode="gevent")
if __name__ == '__main__':
HOST = '127.0.0.1'
PORT = 5055
socketio.run(app, port=PORT, host=HOST)
However, you really want an HTTP server in front of it such as Gunicorn.
i'm trying to setup mod_wsgi to serve my django media files (i want to use this also in a developement env)
I followed this guide to correctly setup mod_wsgi.
This is my wsgi file ("django.wsgi")
import os, sys
path = '/home/smau/Workspace/Maynard/tothego_frontend/'
if path not in sys.path:
sys.path.append(path)
#Calculate the path based on the location of the WSGI script.
apache_configuration= os.path.dirname(__file__)
project = os.path.dirname(apache_configuration)
workspace = os.path.dirname(project)
sys.path.append(workspace)
os.environ['DJANGO_SETTINGS_MODULE'] = 'tothego_frontend.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
This is my conf file ("django.conf")
Alias /site_media/ "/home/smau/Workspace/Maynard/tothego_frontend/site_media/"
<Directory "/home/smau/Workspace/Maynard/tothego_frontend/site_media">
Order allow,deny
Options Indexes
Allow from all
IndexOptions FancyIndexing
</Directory>
WSGIScriptAlias / "/home/smau/Workspace/Maynard/tothego_frontend/srv/mod_wsgi/django.wsgi"
<Directory "/home/smau/Workspace/Maynard/tothego_frontend/srv/mod_wsgi">
Allow from all
</Directory>
This is my "httpd.conf"
Include /home/smau/Workspace/Maynard/tothego_frontend/srv/mod_wsgi/django.wsgi
Everything seems to be like the guide, however, when i try to start/restart apache i get this error
root#archimedes:/etc/apache2# /etc/init.d/apache2 restart
Syntax error on line 1 of /home/smau/Workspace/Maynard/tothego_frontend/srv/mod_wsgi/django.wsgi:
Invalid command 'import', perhaps misspelled or defined by a module not included in the server configuration
Action 'configtest' failed.
The Apache error log may have more information.
...fail!
This is /var/log/apache2.log
[Thu Jul 14 11:39:31 2011] [notice] Apache/2.2.17 (Ubuntu) PHP/5.3.5-1ubuntu7.2
with Suhosin-Patch mod_wsgi/3.3 Python/2.7.1+ configured -- resuming normal operations
[Thu Jul 14 11:44:28 2011] [notice] caught SIGTERM, shutting down
PHP Warning: PHP Startup: Unable to load dynamic library
'/usr/lib/php5/20090626/gd.so'- /usr/lib/php5/20090626/gd.so: cannot open shared object file:
No such file or directory in Unknown on line 0
The log doesn't seem (to me...) anyhow related to my problem. Why do i keep getting the "import" error? Did i give you enought information or do you need something else? I guess my pythonpath is correct:
You're supposed to include the configuration file (django.conf), not the WSGI script (django.wsgi).
I'm working with my hosting provider to get a Django application up and running, but neither of us are very experienced and we've basically hit a complete dead end.
I don't have direct access to the conf file but here's how its contents have been described to me:
<IfModule mod_wsgi.c>
WSGIScriptAlias /fredapp/ /home/fred/public_html/cgi-bin/fredapp/apache/django.wsgi
WSGIDaemonProcess fred threads=15 display-name=%{GROUP} python-path=/home/fred/public_html/cgi-bin/fredapp/apache/
WSGIProcessGroup fred
WSGIApplicationGroup %{GLOBAL}
</IfModule>
Alias /robots.txt /home/fred/public_html/fred-site/robots.txt
Alias /favicon.ico /home/fred/public_html/fred-site/favicon.ico
Alias /settings/media/ /home/fred/public_html/fred-site/media/
My "django.wsgi" script is nothing fancy:
import os, sys
sys.path.append('/home/fred/public_html/cgi-bin/')
sys.path.append('/home/fred/public_html/cgi-bin/fredapp/')
os.environ['DJANGO_SETTINGS_MODULE'] = 'fredapp.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
So my understanding is that all this means that if a request comes in for domain.com/fredapp/ that it should be turned over to the application via django.wsgi. However, the only response I get is:
[Fri Jan 22 18:46:08 2010] [error] [client xx.xxx.xx.xx] File does not exist: /home/fred/public_html/domain.com/500.shtml
[Fri Jan 22 18:46:08 2010] [error] [client xx.xxx.xx.xx] mod_wsgi (pid=26760): Exception occurred processing WSGI script '/home/fred/public_html/cgi-bin/fredapp/apache/django.wsgi'.
[Fri Jan 22 18:46:03 2010] [error] [client xx.xxx.xx.xx] File does not exist: /home/fred/public_html/domain.com/404.shtml
[Fri Jan 22 18:46:03 2010] [error] [client xx.xxx.xx.xx] File does not exist: /home/fred/public_html/domain
This is running under Apache on Linux. I have tried running each line of the .wsgi script in the Python interpreter on the server, and none of them return any errors. I also tried the sys.stdout = sys.stderr trick and got no further output than what is above. The File does not exist errors have to do with the rest of the site's set-up and occur on any request. I haven't finished setting all that up properly (error pages and index pages and so on) because I'm just trying to get the app itself to run.
I've gotten this app up and running under Apache on my own machine, though NOT in Daemon mode, but it's my first Django app, and I don't think my hosting provider has ever configured one before, so we're flying a little blind. If anyone has any suggestions, I'd be very grateful. Thank you!
If the quoted configuration about is what you are using, the error is rather obvious actually. You have:
WSGIDaemonProcess fred threads=15 display-name=%{GROUP} python-path=/home/fred/public_html/cgi-bin/fredapp/apache/
WSGIProcessGroup scratchf
It should be:
WSGIDaemonProcess fred threads=15 display-name=%{GROUP} python-path=/home/fred/public_html/cgi-bin/fredapp/apache/
WSGIProcessGroup fred
That is, the name of the process group must match.
You should though have seen an error message:
No WSGI daemon process called 'scratchf' has been configured
This would likely be before the logged error:
Exception occurred processing WSGI script
This is why it is important that you supply all the error log messages and don't assume that they aren't relevant.
Alternatively, you have quoted configuration different to what you are using or not all of the configuration.
UPDATE 1
It looks like you may have ErrorDocument directive enabled in Apache to redirect errors to a specific URL. Because however you have mounted Django at root of web server and not excluded those error URLs from being passed through to Django, then when an error is generated Django gets the redirect for the error document but it cannot resolve the URL and subsequently generates a 404. Because Apache saw a 404 for error page redirect, it then returns a 500 default error page. The end result is that true original error and any information is lost.
Thus, go into Apache configuration and comment out the ErrorDocument directives.
UPDATE 2
Change configuration to:
WSGIScriptAlias /fredapp /home/fred/public_html/cgi-bin/fredapp/apache/django.wsgi
You should not have trailing slash on the second value on line. Missed that you were actually trying to mount at sub URL and not at root of web server.
Is it possible that your starting directory is not the one project is in?
Today I was also setting up Apache+mod_wsgi+Django app and after adding to django.wsgi:
os.chdir('/home/user/my_django_project')
everything started to work like a charm.
We had the same error when the user running Apache had not the rights to read the files.