Problems using Flask on a shared hosting server - python

I'm trying to deploy a Flask application on a BlueHost shared hosting server. I have been following this guide. I have made one change, and that is in the .fcgi file. I'm not using flup. This is my .fcgi file (flask.fcgi):
#!/path/to/venv/bin/python
from wsgiref.handlers import CGIHandler
from server import app
CGIHandler().run(app)
I've made the file executable, and when I run ./flask.fcgi from the command line (via SSH) it returns the HTML page for the index route, which is what I expect. But if I navigate to mydomain.com/flask.fcgi I receive a 500 Internal Server error. Checking the server logs I can see this message:
/path/to/venv/bin/python: error while loading shared libraries: libssl.so.3: cannot open shared object file: No such file or directory
I encountered this error before while installing openssl and rectified it by setting the LD_LIBRARY_PATH environment variable to include the path to the location where the libraries were installed. This is my .htaccess file:
# For Flask
PassEnv LD_LIBRARY_PATH
PassEnv REQUEST_METHOD
Options +ExecCGI
AddHandler fcgid-script .fcgi
RewriteEngine On
# For Flask
RewriteCond %{REQUEST_FILENAME} !=/path/to/public_html/flask.fcgi
RewriteRule ^(.*)$ flask.fcgi/$1 [QSA,L]
RewriteOptions inherit
You can see that I try to pass in the LD_LIBRARY_PATH variable, but to no avail, I continue to receive the 500 Internal Server errors, regardless of whether I navigate to mydomain.com/page or to mydomain.com/flask.fcgi directly.
I'm entirely at a loss of where to go from here, any help would be greatly appreciated.

So I figured out what the problem was. I needed to set LD_LIBRARY_PATH and LD_RUN_PATH before compiling openssl and python. I set the paths and then ran ./Configure and make && make install for openssl, and the same for python.

Related

500 Server Error With Running Flask App With CGI Script

I keep receiving a 500 Internal Server Error with my Python Flask/CGI program.
I am running it on shared hosting, so I followed this tutorial:
https://medium.com/#dorukgezici/how-to-setup-python-flask-app-on-shared-hosting-without-root-access-e40f95ccc819
This is my main python script: (~/website/mainApp.py)
from flask import Flask
app = Flask(__name__)
#app.route("/")
def home():
return "123 :)"
if __name__ == "__main__":
app.run()
This is my CGI script (~/website/main.cgi)
#!/usr/bin/python
import sys
sys.path.insert(0, "~/.local/lib/python3.7/site-packages")
from wsgiref.handlers import CGIHandler
from mainApp import app
CGIHandler().run(app)
and this is my .htaccess file (~/website/.htaccess):
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /main.cgi/$1 [L]
This is basically a file tree of it:
This is the error I am getting:
Internal Server Error
The server encountered an internal error or misconfiguration and was unable to complete your request.
Please contact the server administrator at to inform them of the time this error occurred, and the actions you performed just before this error.
More information about this error may be available in the server error log.
Additionally, a 500 Internal Server Error error was encountered while trying to use an ErrorDocument to handle the request.
Does anyone see where an error may be?
Thanks!
Edit: It now has a weird .pyc file in it. I didn't add it though.?
The contents of your .cgi and .py files look fine.
The main problem is that the permissions on your .cgi file are not correct. Possibly also, the same goes for the website directory -- its permissions are not visible in the file view you posted.
You need execution (and read!) permission on the CGI file, and on any directories leading up to it.
In theory, the following, when run from inside the website directory, should be sufficient:
chmod a+rx . main.cgi
Notice the . to also apply the command to the current (website) directory. This adds read permission and execute permission to the owner, group and others.
If you don't want any permissions applied for the group, then this is sufficient:
chmod uo+rx . main.cgi
As for the .htaccess file, its also valid and would work -- assuming you have mod_rewrite enabled on your server. Check out this post for instructions on enabling that in case you haven't already.
I changed the shebang at the top of the main.cgi file, and it worked.
Before:
#!/usr/bin/python
After:
#!/usr/bin/python3.7

How to deploy Python Flask app to Apache (Httpd) running on Amazon Linux EC2 instance

I'm really struggling here. I have a simple Python Flask REST API that I've developed. The API runs fine in my local development environment (Mac OS X) and when directly executed via the console on my EC2 instance.
I want to move this service into production and as such would like to host it behind Apache running on the EC2 instance. This is where I keep hitting a wall and I can't seem to get past the configurations and errors. I've research several articles online and questions here, none seem to be able to help me.
I'm hoping someone here can please provide me with step-by-step directions on how to deploy my service to production behind Apache running on an Amazon Linux EC2 instance.
Here are the steps I've taken:
Launched a basic Amazon Linux EC2 instance.
Apply updates to the instance, sudo yum update
Install Apache and WSIG, sudo yum install httpd24 mod24_wsgi
Start Apache, sudo service httpd start
Configure Apache to start automatically, sudo chkconfig httpd on
Test by hitting the DNS of my EC2 box. I successfully get the Amazon Linux AMI test page.
Adjust permissions on /var/www as follows
sudo groupadd www
sudo usermod -a -G www ec2-user
Logon/off and confirm membership, groups
sudo chown -R root:www /var/www
sudo chmod 2775 /var/www
find /var/www -type d -exec sudo chmod 2775 {} \;
find /var/www -type f -exec sudo chmod 0664 {} \;
Test by hitting DNS of my EC2 box - still good so far.
Now that I know my instance is running, I would like to create two folders where I can test and run my Python Flask code. I do so as follows:
I create two folders, one for development and one for production.
/var/www/rest-dev/
/var/www/rest-prod/
I setup a virtual environment within each of the folders and install Flask.
virtualenv env
env/bin/pip install Flask
I then place a copy of my service in each folder.
Then I set permissions on app.py, chmod a+x app.py
I can successfully execute ./app.py and test the service by hitting the DNS name + port 5000. It works.
Now this is where I get tripped up. My goal is to be able to hit api.example.com and have my service's root load up. In the example code below, "Hello, World!" should simply display.
I've followed the tutorials found here with no luck.
http://peatiscoding.me/geek-stuff/mod_wsgi-apache-virtualenv/
http://webpy.org/cookbook/mod_wsgi-apache
http://www.jakowicz.com/flask-apache-wsgi/
After executing any of the steps in any of the articles above, I get an HTTP error page and nothing loads anymore, including the default Amazon Linux AMI test page. Below are the pieces of code and configurations that I've changed. I haven't changed my httpd.conf ... should I? There are probably several other things I'm missing.
Can someone please help me by providing me the necessary steps in detail to correct my mistakes?
Many thanks in advance!
When I view the error_log for HTTPD, it lists errors like this:
mod_wsgi (pid=8270): Target WSGI script '/var/www/rest-dev/deploy.wsgi' cannot be loaded as Python module.
mod_wsgi (pid=8270): Exception occurred processing WSGI script '/var/www/rest-dev/deploy.wsgi'.
Traceback (most recent call last):
File "/var/www/rest-dev/deploy.wsgi", line 16, in <module>
from app import app as application
File "/var/www/rest-dev/app.py", line 2, in <module>
from flask import Flask
ImportError: No module named flask
Here is my deploy.wsgi file, located in the rest-dev folder:
import os
import sys
import site
# Add virtualenv site packages
site.addsitedir(os.path.join(os.path.dirname(__file__), 'env/local/lib64/python2.7/site-packages'))
# Path of execution
sys.path.append('/var/www/rest-dev')
# Fired up virtualenv before include application
activate_env = os.path.expanduser(os.path.join(os.path.dirname(__file__), 'env/bin/activate_this.py'))
execfile(activate_env, dict(__file__=activate_env))
# import my_flask_app as application
from app import app as application
Here is my vhost.conf file located in /etc/httpd/conf.d/
<VirtualHost *:80>
ServerName api.example.com
WSGIDaemonProcess webtool user=ec2-user group=www threads=5 home=/var/www/rest-dev/
WSGIScriptAlias / /var/www/rest-dev/deploy.wsgi
<directory /var/www/rest-dev>
WSGIProcessGroup webtool
WSGIApplicationGroup %{GLOBAL}
WSGIScriptReloading On
Order deny,allow
Allow from all
</directory>
</VirtualHost>
Here is my app.py example service code for reference:
#!env/bin/python
from flask import Flask
app = Flask(__name__)
#app.route('/')
def index():
return "Hello, World!"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=True)
Turns out, in my deploy.wsgi file I'm referencing lib64 instead of just lib. All the site packages exist in lib.
After changing it and restarting Apache, I'm able to successfully hit my service from the URL.

django using fcgi in shared hosting

I'm trying to check if my host supports what is needed for my django site, so atm I'm trying to set up a basic django site.
What makes this even more complicated is that I need to have another joomla page running from the same server (see below).
I don't know if I'm doing something wrong (most probable) and what am I supposed to ask from the host. (I know I'm a little noob in this)
Here's what I have so far:
in the /home/username/
library-site/ <-- django files
lib/
manage.py
lib/
settings.py
...
public-html/
cgi-bin
folder_containing_joomla_site
library <-- folder_id_like_to_use_for_my_page
library <-- virtual_env
bin
...
(following a guide I've symlinked the site-packages of the virtualenv to library_site/lib)
I have to say that I've tried numerous guides so it's difficult to present the entire picture but here's what I have now
in public_html/library/dispatch.fcgi
#!/home/username/library/bin/python
import sys
import os
sys.path.insert(0, "/home/username/library/bin/python")
sys.path.append('/home/username/library/lib/python2.6/site-packages')
sys.path.insert(13, "/home/username/public_html/library")
open("/home/username/public_html/library/cgi.log", "w").write("Before try")
try:
os.environ['DJANGO_SETTINGS_MODULE'] = 'lib.settings'
from django.core.servers.fastcgi import runfastcgi
runfastcgi(method="threaded", daemonize="false")
except Exception:
open("/home/username/public_html/library/cgi.log", "w").write(format_exc())
raise
in public_html/library/.htaccess
AddHandler fcgid-script .fcgi
Options +FollowSymLinks
RewriteEngine On
RewriteBase /library/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(dispatch\.fcgi/.*)$ - [L]
RewriteRule ^(.*)$ dispatch.fcgi/$1 [L]
Navigating like this to http://example.com/library displays the contents of the folder. Clicking on the dispatch.fcgi just displays the python code.
Running ./dispatch.fcgi from the returns the correct django output but the first four lines read
WSGIServer: missing FastCGI param REQUEST_METHOD required by WSGI!
WSGIServer: missing FastCGI param SERVER_NAME required by WSGI!
WSGIServer: missing FastCGI param SERVER_PORT required by WSGI!
WSGIServer: missing FastCGI param SERVER_PROTOCOL required by WSGI!
These all tell me that I need to ask something from the host but I have no idea what at this point.
Also, running
python ~/library_site/lib/manage.py runfcgi daemonize=false host=127.0.0.1 port=3033 maxrequests=1
as recommended here: https://twiki.cern.ch/twiki/bin/view/ITCF/DjangoGeneral does not return any problems.
Finally, starting the django server:
python manage.py runserver 0.0.0.0:8000
works fine. Can anyone please help?
FCGI requires a conversion layer between it and WSGI. Make sure you have flup installed and that your FCGI file is executable
Here is a guide I was able to get working some two years ago or so.
I now feel a little stupid as the answer was really trivial. Following this guide http://joemaller.com/1467/django-via-cgi-on-shared-hosting/ I've put the .fcgi in cgi-bin and wrote the appropriate .htaccess file in public_html and...Voila!
As a point of interest to anyone who tries this in the future, regarding the static files (which are even more of a pain), I've put them in 'public_html/library/static/' (<-- STATIC ROOT) using the absolute path and then my STATIC_URL was '/lib_files/static/'.

Why is django using fcgi on a hostgator server behaving this way?

I am trying to deploy a simple static site on hostgator. I followed this tutorial and originally had in my .htaccess (where abc.com is the website):
AddHandler fcgid-script .fcgi
Options +FollowSymLinks
RewriteEngine On
RewriteRule (media/.*)$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(admin/.*)$ index.fcgi/$1 [L]
RewriteCond %{HTTP_HOST} ^abc\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\.abc\.com$
RewriteRule ^/?$ "http\:\/\/abc\.com\/index\.fcgi" [R=301,L]
but this did not work and would only load the "home.html" from my template directory for some reason. When I tried to follow any links I would get a hostgator 404 error page. Then after doing some research and talking to the hostgator support people a few times I changed it to the much simpler:
AddHandler fcgid-script .fcgi
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.fcgi/$1 [QSA,L]
My index.fcgi file in the public_html directory looks like:
#!/usr/local/bin/python
import sys, os, user
from django.core.servers.fastcgi import runfastcgi
sys.path.insert(0, "/usr/lib/python2.6")
sys.path.insert(0, "/home/joeshmo/django")
sys.path.insert(0, "/home/joeshmo/django/Projects")
sys.path.insert(0, "/home/joeshmo/django/Projects/PersonalWebsite")
# Switch to the directory of your project.
os.chdir("home/joeshmo/django/Projects/PersonalWebsite/")
# Set the DJANGO_SETTINGS_MODULE environment variable.
os.environ['DJANGO_SETTINGS_MODULE'] = "PersonalWebsite.settings"
runfastcgi(method="threaded", daemonize="false")
This worked, but now I am very curious what is going on here. Despite doing some research on my own I am confused what fcgi does and, more importantly, how it is telling django to load the proper html files from my template directory as the hostgator tech person I talked to assured me that html files could ONLY ever be accessed from the public_html folder. I am familiar with the general concept of a url dispatcher, regexp, views, ect but I am a self-taught web developer so please bear that in mind.
It sounds like you may be used to things like PHP projects where there is a 1:1 correspondence between URLs and the path on the server. That's not the case in a Django project: you pass the request path you want to a script (usually a WSGI script but in your case a FCGI) that knows to pass the path on to the Django code. Once the path gets to the Django code it looks for a matching path pattern in the urls.py files and serves that back if it finds one. The path is question is sent in the $1 variable in your .htaccess file, which is why you only ever saw the home template when you were passing the literal string 'home.html' instead of the actual request path.
Is everything else working properly? I was once compelled to host a Django project on HostGator via FCGI so I know the pain of getting it set up. I may be able to dredge up some terrible memories if there are other issues, but I'd strongly suggest looking at Django-friendly host if you think you may continue with Django (I am happy with WebFaction who provides an installer to make getting Django set up via WSGI much easier).

Porting Django Project to 1&1 Shared Hosting Web-server

As a little background, I've been developing a django application for a 1&1 shared hosting website. When I tried to port the app to the web, I followed the tutorial from here: http://robhogg.me.uk/post/2. The servers have Python 2.6, and I installed django and flup through SSH.
Here is my .fsgi file...
#!/usr/bin/python
import sys, os
basepath = '/home/path/' # This isn't my actual homepath
sys.path.insert(0, basepath + '/.local/lib')
sys.path.insert(0, basepath + '/mysite')
os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'
from django.core.servers.fastcgi import runfastcgi
runfastcgi(method='threaded', daemonize='false')
...and here is my .htaccess file...
AddHandler fcgid-script .fcgi
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !(cgi-bin/mysite.fcgi)
RewriteRule ^(.*)$ cgi-bin/mysite.fcgi/$1 [QSA,L]
I also already gave the .fcgi script 755 permissions. When I run the .fcgi script, the homepage HTML prints on the console (which according to many sites means the script is good). But when I go to my website's domain, I was getting just an Index.html page that was sitting in my home directory. So I moved all the html files from the home directory, and tried again. But this time I get an error:
Forbidden
You don't have permission to access / on this server.
Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.
I tried one more thing, and that was in the .htaccess file, changing
AddHandler fcgid-script .fcgi
to
AddHandler fastcgi-script .fcgi
After searching everywhere, I couldn't find a solution, so I followed the directions on this site: https://help.asmallorange.com/index.php?/Knowledgebase/Article/View/140
Even though it was a different host, it was the same concept with similar steps. I followed all the steps, creating a new project and everything, and in the end, had the same issue.
I've been through a ton of posts like this one, but none have had a solution that worked yet. Maybe this is a 1&1 specific issue, but I would really appreciate the help if anyone has any suggestions.
I got the same error as you got. But after I moved the .htaccess file to the django project folder, it works.

Categories