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.
Related
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.
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/'.
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).
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.
I am a beginner programmer. I started using Python and Bottle for a small web app to print a form, so far so good. The real issue is configuring Apache and mod_wsgi, as my knowledge is almost none.
My problem: I keep getting this error:
Error 404: Not Found
Sorry, the requested URL /factura/ caused an error: Not found
In work they gave me and address redirecting to a IP:port; after some days of reading Apache docs and looking examples through the web I managed to set up the configuration so my VirtualHost doesn't breaks the others virtualhosts already running. The config looks like this (based on the bottle tutorial deployment section):
Listen port
NameVirtualHost IP:port
<VirtualHost IP:port>
ServerName IP:port
WSGIDaemonProcess factura processes=1 threads=5
WSGIScriptAlias / /var/www/factura/app.wsgi
<Directory /var/www/factura>
WSGIProcessGroup factura
WSGIApplicationGroup %{GLOBAL}
Order deny,allow
Allow from all
</Directory>
</VirtualHost>
My app.wsgi is almost the same as the one in the Bottle tutorial-deployment section. I only added the line sys.stdout = sys.stderr:
import sys, os, bottle
# Change working directory so relative paths (and template lookup) work again
sys.path = ['/var/www/factura'] + sys.path
os.chdir(os.path.dirname(__file__))
# Error output redirect
# Exception KeyError in 'threading' module
sys.stdout = sys.stderr
import factura
application = bottle.default_app()
Here is a bit of the python code which is related to Bottle:
from lib import bottle
app = bottle.Bottle()
#serves files in folder 'static'
#app.route('/static/:path#.+#', name='static')
def ...
#app.route("/factura")
#bottle.view("factura")
def ...
#app.route("/print_factura", method="POST")
def ...
I have read some of the others question similar to this, but I can't manage to see what I'mm missing. I suppose the problem is in app.wsgi?
UPDATE
file structure
/var/www/factura/ ## .py files
/views ## here is the web template
/static ## .css and .js of template
/lib ## package with bottle and peewee source files
/data ## inkscape file to play with
/bin ## backup stuff in repo, not used in code
Apache error log only shows
Exception KeyError: KeyError(-1211426160,) in <module 'threading' from '/usr/lib/python2.6/threading.pyc'> ignored
that is a warning from wsgi/python issues, harmless by wsgi issue 197
UPDATE 2 working
added #app.route("/factura/") notice the trail slash, that with the change in app import from factura import app as application those two together made it work
If you create your application explicitly:
app = bottle.Bottle()
then you should import it in your app.wsgi instead of application = bottle.default_app():
from factura import app as application
But what is far important is this. In your WSGI file, you do import bottle, yet in the app code file, you do from lib import bottle. As you have explained, you have two copies of Bottle: one installed server-wide, another under the lib directory.
That's why you were receiving 404 Not Found. You were actually working with one instance of the library (creating app), and then giving Apache a different (default_app) from a different instance of the library!
It started to work okay when you began to return the proper app.