django using fcgi in shared hosting - python

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/'.

Related

Problems using Flask on a shared hosting server

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.

django deploy - ubuntu 14.04 and apache2

https://www.sitepoint.com/deploying-a-django-app-with-mod_wsgi-on-ubuntu-14-04/
and
https://www.youtube.com/watch?v=hBMVVruB9Vs
This was the first time I deploy a website.And these are the tutorials I followed.
Now I can access to the server(by typing 10.231.XX.XX) from other machine and see the Apache2 Ubuntu Default Page.
Then I tried to access my django project. I run:
python manage.py runserver 8000
Validating models...
0 errors found August 03, 2016 - 09:44:20 Django version 1.6.1, using
settings 'settings' Starting development server at
http://127.0.0.1:8000/ Quit the server with CONTROL-C.
Then I type 10.231.XX.XX:8000 to try to acess the django page. But I failed.
It said:
This site can’t be reached
10.231.XX.XX refused to connect. Search Google for 231 8000 ERR_CONNECTION_REFUSED
I have tried every thing I can but still can't figure why.
(as followed the website https://www.sitepoint.com/deploying-a-django-app-with-mod_wsgi-on-ubuntu-14-04/)
I have apache folder in mysite folder, and in override.py:
from mysite.settings import *
DEBUG = True
ALLOWED_HOSTS = ['10.231.XX.XX']
in wsgi.py:
import os, sys
# 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)
sys.path.append(project)
# Add the path to 3rd party django application and to django itself.
sys.path.append('/home/zhaojf1')
os.environ['DJANGO_SETTINGS_MODULE'] = '10.231.52.XX.apache.override'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
and __init__py is empty.
in /etc/apache2/sites-enabled/000-default.conf :
<VirtualHost *:80>
# The ServerName directive sets the request scheme, hostname and port that
# the server uses to identify itself. This is used when creating
# redirection URLs. In the context of virtual hosts, the ServerName
# specifies what hostname must appear in the request's Host: header to
# match this virtual host. For the default virtual host (this file) this
# value is not decisive as it is used as a last resort host regardless.
# However, you must set it for any further virtual host explicitly.
#ServerName www.example.com
ServerAdmin webmaster#localhost
DocumentRoot /var/www/html
# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the loglevel for particular
# modules, e.g.
#LogLevel info ssl:warn
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
# For most configuration files from conf-available/, which are
# enabled or disabled at a global level, it is possible to
# include a line for only one particular virtual host. For example the
# following line enables the CGI configuration for this host only
# after it has been globally disabled with "a2disconf".
WSGIScriptAlias /msa.html /home/zhaojf1/Web-Interaction/apache/wsgi.py
<Directory "/home/zhaojf1/Web-Interaction-APP">
<Files wsgi.py>
Require all granted
</Files>
</Directory>
I have also restart apache after I do everything.
Thanks for help
The connection refused error is likely going to come down to Apache being incorrectly configured for the VirtualHost or you accessing wrong port. You also have other basic mistakes in your wsgi.py file as well.
Starting with the wsgi.py file, the DJANGO_SETTINGS_MODULE value is wrong:
os.environ['DJANGO_SETTINGS_MODULE'] = '10.231.52.XX.apache.override'
The value is meant to be a Python module path. Having the IP address in there looks very wrong and is unlikely to yield what you need.
Next is changes to sys.path. The location of your project and activation of any Python virtual environment is better done through options for mod_wsgi in the Apache configuration file.
That you are adding a home directory into the path is also a flag to potential other issues you may encounter. Specifically, the user that Apache runs as often cannot read into home directories as the home directories are not readable/accessible to others. You may need to move the project out of your home directory.
As to the Apache configuration, your VirtualHost lacks a ServerName directive. If this was an additional VirtualHost you added and not the default (first one appearing in Apache configuration when parsed), it will be ignored, with all requests going to the first VirtualHost. You do show this as in the default site file, so may be you are okay.
Even so, that VirtualHost is set up to listed on port 80. You are trying to connect to port 8000, so there wouldn't be anything listening.
Next issue is the WSGIScriptAlias line.
WSGIScriptAlias /msa.html /home/zhaojf1/Web-Interaction/apache/wsgi.py
It is strange to have msg.html as the mount point as that makes it appear as if you are accessing a single HTML page, but you have it mapped to a whole Django project. If you were accessing the root of the host, it also wouldn't map through to the Django application as you have it mounted at a sub URL. Thus perhaps need to use:
WSGIScriptAlias / /home/zhaojf1/Web-Interaction/apache/wsgi.py
Next problem is that the directory specified in Directory directive doesn't match where you said the wsgi.py file existed in the WSGIScriptAlias. They should match. So maybe you meant:
<Directory /home/zhaojf1/Web-Interaction/apache>
Even then that doesn't look right as where is the apache directory coming from. That last directory in the path should normally be the name of the Django project.
One final thing, you may need to change ALLOWED_HOSTS as well. If you find you start getting bad request errors it probably doesn't match properly. Change it to ['*'] to see if that helps.
So lots of little things wrong.
Suggestions are:
Make sure you read the official Django documentation for setting up mod_wsgi. See https://docs.djangoproject.com/en/1.10/howto/deployment/wsgi/modwsgi/
If you are only wanting to do development at this point, use mod_wsgi-express instead. See http://blog.dscpl.com.au/2015/04/using-modwsgi-express-with-django.html and http://blog.dscpl.com.au/2015/04/integrating-modwsgi-express-as-django.html

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).

Making Django work with Apache

I have a test django project that I have been using the django development server for. I want to start using an actual apache server to properly simulate a production environment. I am using Mac OS X.
I have been using this tutorial here, but in the first set of instructions I am getting a 403 from localhost. The browser says I do not have permission to access / on the server.
When I comment out the apache config line from the tutorial, WSGIScriptAlias / /Users/username/Projects/django_books/django_books/django.wsgi I can access localhost.
This is the contents of my django.wsgi file:
import os
import sys
os.environ['DJANGO_SETTINGS_MODULE'] = 'django_books.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
path = '/Users/username/Projects/django_books/django_books'
if path not in sys.path:
sys.path.append(path)
What is causing the 403 and why can't I see my django application?
EDIT
Directory structure:
django_books
apache (empty directory right now)
random_book
__init__.py
models.py
views.py
django_books
__init__.py
django.wsgi
settings.py
urls.py
views.py
wsgi.py
media
static
css
style.css
manage.py
2ND EDIT
Permissions on all the directories:
/Users/username/Projects/django_books/django_books/django.wsgi
-rw-r--r--
/Users/username/Projects/django_books/django_books
drwxr-xr-x
/Users/username/Projects/django_books/
drwxr-xr-x
/Users/username/Projects/
drwxr-xr-x
/Users/username/
drwxr-xr-x+
/Users/
drwxr-xr-x
According to my small experience I think you must add the following lines "just below the import sys line to place your project on the path" (so juste under "import sys") like it's said in the tutorial you quote. Also, erase the second "django_books" in your path because you want to link to your site not the app in your site ;-) ("mysite" in the tutorial, not mysite/mysite)
import os
import sys
path = '/Users/username/Projects/django_books'
if path not in sys.path:
sys.path.append(path)
os.environ['DJANGO_SETTINGS_MODULE'] = 'django_books.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
Bye
It's likely an issue related either to your Apache installation, python library, or the filesystem's permissions.
Testing Apache
You don't say it in your question, but I assume from your link you are working with Apache2 and mod_wsgi.
You can test if Apache and mod_wsgi (or your wsgi module) are working properly by placing a dummy wsgi script in the place of django.wsgi . This script (stolen from mod_wsgi's docs) doesn't rely on Django and helps make sure that Apache can read and execute the wsgi script:
# test version of django.wsgi
def application(environ, start_response):
status = '200 OK'
output = 'Hello World!'
response_headers = [('Content-type', 'text/plain'),
('Content-Length', str(len(output)))]
start_response(status, response_headers)
return [output]
And restart apache
sudo service apache2 restart
Go ahead and test the page. Did it work? Great. Undo the changes to the django.wsgi script, restart Apache and test again. If the Django site still doesn't work, we need to keep looking. If the test script didn't work, there may be a problem with your Apache installation. Check apache's error log for more information about what happened. On linux it's commonly at /var/log/apache2/error.log . mod_wsgi could be improperly installed, the script's daemon may not have appropriate permission to the wsgi file.
Correcting permission errors
Apache may not be able to read and execute the wsgi file. Running ls -l in the wsgi file's directory as indicated in other answers will tell you the user and group a file belongs to (and if that user and group can read, write, or execute a given file). It's common for a default installation to have the wsgi permissions like so:
-rw------- 1 www-data www-data 1470 Aug 29 16:00 django.wsgi
If you want to use a different user for the daemon process, you need to make sure that the apache conf file defines WSGIDaemonProccess
WSGIScriptAlias / /Users/username/Projects/django_books/django_books/django.wsgi
WSGIDaemonProcess wsgi_user processes=2 threads=15 display-name=%{GROUP}
WSGIProcessGroup wsgi_group
Testing changes to these files and restarting Apache can help narrow down what's up. Keep checking the Apache log files.
Apache Configuration
Django's tutorial on setting up mod_wsgi is good, but read through mod_wsgi's wiki as well. There are a lot of helpful things to consider in your apache conf file besides WSGIScriptAlias. Make sure there is a tag pointing to the folder with your wsgi file. If there are non-public files (like django project files) in that directory, either use the apache directory (update your apache conf file) or add a tag under the node to keep those other files private. While you're in there, you may notice other things that look wrong, like an improperly configured servername, multiple virtual hosts, or other errors.
Testing Python
If you're using virtualenv (do it), make sure that
1. The WSGIDaemonProcess variable defines the appropriate site-packages and the wsgi script's location in the variable's python-path attribute
2. The daemon has rights to read the site packages in your virtualenv.
3. Your wsgi script properly imports django and your site's settings.
Logging Apache
You can increase the level of logging reported by Apache by adding a few lines to your Apache conf file. This setup gives you very verbose logging that you may want during deployment (make sure to make a log folder):
LogLevel info
ErrorLog /Users/username/Projects/django_books/logs/apache_error.log
CustomLog /Users/username/Projects/django_books/logs/apache_access.log combined
I would suspect that the www-data (or whatever user apache is running as) doesn't have access to /Users/username/Projects/django_books/django_books.
su to that user and try and access that directory and the wsgi file within it.
To print all the relevant permissions:
ls -ld /Users /Users/username /Users/username/Projects /Users/username/Projects/django_books /Users/username/Projects/django_books/django_books /Users/username/Projects/django_books/django_books/django.wsgi
You should also check the apache error logs, they might tell you what is going wrong.

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