Deploying a Django App - django

I'm very sorry for such a simple question-- I'm new at WSGI development, and I'm grateful for any patience you can afford.
I made a Django app; it works great in development mode. I run:
python manage.py runserver
and then direct my browser to 127.0.0.1:8000, and voila, there is my app.
From here I absolutely cannot figure out how to run my app in production mode. I've read several pages like this and this and several others on StackOverflow. But I have no idea of where to even direct my browser to see if my page is working.
I've installed apache2, mod_python, etc., but I think the problem is that my misunderstanding is at such a more basic level. When I've done CGI programs in the past, I direct my browser to webroot/file.html with a form that calls cgi-bin/file.cgi, which generates html output. I don't know if I am supposed to navigate to a .wsgi page, etc.
Under the assumption that I'm supposed to navigate to a .wsgi file, I've also tried making a file containing:
import os
import sys
os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
path = '/home/orserang/nonparametric-protein/src/www/mysite$'
if path not in sys.path:
sys.path.append(path)
and added
WSGIScriptAlias / /path/to/mysite/apache/django.wsgi
to my apache2/httpd.conf file, so that its contents are:
<Location "/mysite/">
SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
PythonOption django.root /mysite
PythonDebug On
PythonPath "['/home/orserang/nonparametric-protein/src/www/mysite'] + ['/home/orserang/nonparametric-protein/src/'] + sys.path"
WSGIScriptAlias /mysite /home/orserang/nonparametric-protein/src/www/mysite/django.wsgi
</Location>
But when I restart apache, it says:
Syntax error on line 8 of /etc/apache2/httpd.conf:
WSGIScriptAlias not allowed here
Given that I don't even know where I should point my browser to get to a Django wsgi page, I figured there is something easy that I'm doing quite wrong.
Perhaps Django WSGI apps require something to run in the background, which will listen for requests (rather than go through apache)?
The online Django documentation on views and databases alone are substantial compared to the documentation for deployment; therefore, my best guess is that this is such a simple thing to do.
Thanks a lot for your help!

The Django Book 2.0 has an overview about this. It's not typically linked to in the Django docs:
Chapter 12: Deploying Django
Look at the "Using Django with Apache and mod_python" section.

You're mixing up mod_python and mod_wsgi deployment methods. Get rid of everything inside the Location directive except for the WSGIScriptAlias line.

I wrote shell script that deploys a django project on apache for linux,
https://github.com/mukulu/shell-scripts/blob/master/deploy-django.sh
You only need to configure couple of variables in first lines of the code,
and it'll figure out the rest.
It pretty much checks and install dependencies for django, writes apache configurations that deploys your project and restart the server.
I'm planning to re-write it in python(I wrote it in a hurry)
Feel free to re-use.
Variables are:
SITE_PREFIX="/djangoproject"
MEDIA_URL="/media"
ADMIN_MEDIA_PREFIX="/static/admin/"
MEDIA_ROOT=""
DJANGO_VERSION="1.3.1"
APACHE2_CONFIG="/etc/apache2/conf.d" #Apache configurations directory in yoru system.

This might be not for a novice, but you can take a look - http://packages.python.org/django-fab-deploy/
It's the library for automating the deploying process. It supports servers based primarily on Debian Lenny or Squeeze.

Related

Python Falcon on Webfaction

I'm trying to get Falcon up and running on Webfaction. I'm not exactly a network guru, so I'm having a tough time wrapping my head around how these applications are served.
My Webfaction App is set up as mod_wsgi 4.5.3/Python 2.7
To my understanding, Falcon will run on any WSGI server. When I swet up my mod_wsgi server, is it automatically configured for something like Falcon to run on? Or do I still need to install something like Gunicorn?
When I set up my webfaction app, I received a directory structure like this:
app/htdocs/index.py
And inside the index.py file, I put the example found at Falcon Tutorial
import falcon
class ThingsResource(object):
def on_get(self, req, resp):
"""Handles GET requests"""
resp.status = falcon.HTTP_200
resp.body = 'Hello world!'
# falcon.API instances are callable WSGI apps
wsgi_app = api = falcon.API()
# Resources are represented by long-lived class instances
things = ThingsResource()
# things will handle all requests to the '/things' URL path
api.add_route('/things', things)
I understand there are also instructions for running WSGI, but that is where my confusion is at - is the webfaction server already running WSGI, or do I still need something like Gunicorn, and if so - what is the best way to configure? Do I need a cron to keep running Gunicorn?
Thanks!
Update:
I checked error logs and received a WSGI error about not having a variable named "application",
So I changed:
wsgi_app = api = falcon.API()
to:
application = falcon.API()
This cleared out the error, but now when I visit mydomain.com/things, I get an error 404 (Not found / Does not exist).
So, this brings me back to my original question of what the next steps are? It seems as if the url isn't being routed correctly, so it is most likely something to do with httpd.conf file or similar - again, this is my first go at getting something like this set up live.
Here is the answer (at least for the initial question, I'm willing to bet I'll mess up something else in the near future on the same project).
Essentially, I was able to put the tutorial code in the index.py file that Webfaction generates when setting up an app & mounting on a domain. So, my tutorial code looks something like this:
import falcon
class ThingsResource(object):
def on_get(self,req,resp):
resp.status = falcon.HTTP_200
resp.body = 'Hello World!'
api = application = falcon.API()
things = ThingsResource()
api.add_route('/things', things)
Since I couldn't find much info for launching a Falcon app on Webfaction, I looked at how similar applications run on Webfaction (Flask in this example). That being said, I found a snippet on the Flask docu showing how to get set up on webfaction. I'm not sure if this means my entire application will work, but I do know that the Falcon tutorial code at least works. Essentially, I just had to edit the httpd.conf file per the instructions found here: Flask Webfaction
WSGIPythonPath /home/yourusername/webapps/yourapp/htdocs/
#If you do not specify the following directive the app *will* work but you will
#see index.py in the path of all URLs
WSGIScriptAlias / /home/yourusername/webapps/yourapp/htdocs/index.py
<Directory /home/yourusername/webapps/yourapp/htdocs/>
AddHandler wsgi-script .py
RewriteEngine on
RewriteBase /
WSGIScriptReloading On
</Directory>
I hope this helps anybody with a similar issue.

Flask + mod_wsgi automatic reload on source code change

Does anyone know how to make a mod_wsgi automatically reload a Flask app when any of the modules changes? I've tried WSGIScriptReloading On, but no luck. The official documentation is kind of a bear ... I guess I'll give it a stab if no one knows. Thanks in advance!
Also, if it could not permanently crash on syntax errors (like the the Flask reloader), that'd be awesome.
With mod_wsgi, WSGIScriptReloading looks for changes to the .wsgi config file, rather than the code.
My workflow is to upload my code changes then just
$ touch MyWebApp.wsgi
which causes the last modified file timestamp to change and mod_wsgi to reload the code.
You can do this 'remotely' by saving the .wsgi file on your local machine and then uploading it again, or I just do it via SSH.
Not a lot you can do about syntax errors, the code is either running or it isn't, but a fix plus a touch will get it running again.
One gotcha to look out for if you're working via FTP: make sure you upload the 'touched' .wsgi file last otherwise it'll try and start with the wrong code.
I think it's a very realistic situation to want to reload source code automatically in production. Think of an environment where sources are deployed per version and a 'production' symlink points to one of those versions. Whenever you want release a newer version, you just point the symlink to another path. But apache and mod_wsgi still collect the files from the symlinked directory and therefor need to have a reloading mechanism in place based on timestamps, size or w/e. Sure, one application might not be a problem, but what about hosting 15-20 applications that are all undergoing active development? Not automatically reloading sources is a pure loss in such a situation compared to restarting apache every single time.
Back to the question: if the framework you're using (in this case flask) does not have a plugin or tool in place for automatic source code reloading, then the two options described by Graham and Malphas are your best options. Either trigger the wsgi process to restart or implement a monitoring system.
You're right about adding the WSGIScriptReloading directive. The Flask docs don't make it 100% clear, but Apache looks for changes to your .wsgi file. The recommended solution is to just execute a touch command on your your .wsgi file, as part of your release process.
For production I prefer apache mod_wsgi too, while for development I use the flask's built-in server. I separate prod and dev config files and I set the debug directive True in the dev config so that Flask can detect and reload code changes automatically.
The correct answer to this question is that the WSGIScriptReloading On needs to be added into 000-default.conf present under /etc/apache2/sites-enabled folder.
See below example
<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
ServerName sentiments.live
ServerAdmin admin#sentiments.live
DocumentRoot /var/www/html
WSGIDaemonProcess flaskapp threads=5
WSGIScriptAlias / /var/www/html/sentiments/flaskapp.wsgi
<Directory sentiments>
WSGIScriptReloading On
WSGIProcessGroup sentiments
WSGIApplicationGroup %{GLOBAL}
Order deny,allow
Allow from all
</Directory>
What do you mean 'the official documentation is kind of a bear'? What is wrong with the included recipe:
http://code.google.com/p/modwsgi/wiki/ReloadingSourceCode#Monitoring_For_Code_Changes
That document also explains why WSGIScriptReloading doesn't do what you expect.
And no it is not possible to permanently crash on syntax errors. It is embedded in Apache and the whole point of Apache is to keep stuff running.
Sounds like you should not be using Apache/mod_wsgi for development. Everyones knows one should not use automatic source code reloading in production so can't imagine you would want to do that.

How to setup Django/Apache for a designer's dev environment

I've been developing in my own django environment for a while now using the manage.py runserver with no problems, but now that we've got a designer and a front-end developer needing to work on the project, I find myself at a loss as to what is the Best Practise for their environments.
I could ask them to setup their own python environment, but that's asking an awful lot since they're not Python people and they're running Windows (my dev and the production environment are both Linux).
So instead, I've set them up on a remote server, the disk of which they can mount locally. However in this setup, I'm actually using different instances of manage.py runserver ip:port running in a screen instance. It doesn't handle things like constant reloads very well (common for our designer) and it hangs from time to time due to the single-threaded nature of the dev server. I'd like to know how to set this up with Apache.
The problem with this of course is the staticfiles. Every time either of the aforementioned parties want to add or change a static file, they'd have to run manage.py collectstatic which just isn't practical. I just don't know any other way to do it though. All of the documentation I've found for using Apache is for a production environment, so... that's why I'm here.
Source control? Have them check in changes and then set up a post commit hook to collectstatic and restart the server. With nice windows GUIs I've never had a designer who couldn't grasp the basic concepts. If you're using a dcvs you can always have them in their own fork so you have to merge into the main repos to prevent them from breaking other things by mistake.
The answer to this one was a lot simpler than I thought it would be and I apologise for confusing those who responded. Basically all I wanted was a way to host our designer's dev environment in something more stable than ./manage.py runserver ip:port in a screen session. I figured that there had to be a way to set something like this up for Apache but had no idea what it was.
Here's what I got to work:
In your settings.py set your STATIC_URL and MEDIA_URL variables to relative URLs. In my case I used /static/ and /media/.
MEDIA_ROOT = PROJECT_ROOT + "/htdocs/media/"
MEDIA_URL = "/media/"
SERVE_STATIC = True
STATIC_ROOT = PROJECT_ROOT + "/htdocs/public/"
STATIC_URL = "/static/"
Configure Apache as you would if you didn't have any static files at all. In other words, ignore the recommendations of the docs to use SetHandler None in a <Locaiton> block.
<VirtualHost *:80>
WSGIScriptReloading On
WSGIDaemonProcess someprocessname
WSGIProcessGroup somegroupname
WSGIApplicationGroup somegroupname
WSGIPassAuthorization On
WSGIScriptAlias / /path/to/config.wsgi
ServerName somewhere.awesome.ca
<Location "/">
Order Allow,Deny
Allow from all
</Location>
ErrorLog /var/log/apache2/somewhere.awesome.ca.err
CustomLog /var/log/apache2/somewhere.awesome.ca.log combined
</VirtualHost>
Lastly, you just have to follow the Django howto for serving staticfiles through Python at https://docs.djangoproject.com/en/1.3/howto/static-files/#serving-other-directories
I hope this helps to point someone in the right direction in the future.

Django tutorial on remote server: how to view in my browser?

I'm getting started with a Django tutorial, and I've run into a snag. Having created the sample "mysite" on my usual domain, I want to be able to display it in my browser. The tutorial points me to http://127.0.0.1:8000. However, that's not going to work, as I'm doing this remotely.
[background information]
What I have done, apparently successfully, is
django-admin.py startproject mysite
(created mysite directory containing four files)
python manage.py runserver
(Validating models... 0 errors found, etc.)
The absolute path is
/home/toewsweb/public_html/pythonlab/mysite
What URL should I be able to use to bring this up in my browser?
I also put mysite at
/home/toewsweb/mysite (since it's not supposed to go in a publicly accessible directory)
What URL should I be able to use in this case?
This is a virtual private server, so I have access to httpd.conf. I have downloaded and installed mod_wsgi and have added it to the Apache configuration. I actually did set a subdomain with a DocumentRoot of /home/toewsweb/public_html/pythonlab/mysite; however, when I point the browser to that subdomain, I just get the directory listing.
[/background information]
Right now, I just want to know how to view what I'm working on in my browser.
Thanks!
For development purposes, there's no need to mess about with configuring WSGI (although it's useful to know, as you will need to do it for production). Just start the dev server so that it listens to an external port:
./manage.py runserver 0:8000
This binds to the external IP address, so now you can access your Django site via port 8000 on that server:
http://whatever.my.ip.is:8000
You need to setup the apache WSGIScriptAlias directive in your VirtualHost to properly load python and your site. Django's docs have a great explanation on what you need to do.
Basic configuration
Once you’ve got mod_wsgi installed and activated, edit your httpd.conf file and add:
WSGIScriptAlias / /path/to/mysite/apache/django.wsgi
The first bit above is the url you want to be serving your application at (/ indicates the root url), and the second is the location of a "WSGI file" -- see below -- on your system, usually inside of your project. This tells Apache to serve any request below the given URL using the WSGI application defined by that file.
Next we'll need to actually create this WSGI application, so create the file mentioned in the second part of WSGIScriptAlias and add:
import os
import sys
os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
If your project is not on your PYTHONPATH by default you can add:
path = '/path/to/mysite'
if path not in sys.path:
sys.path.append(path)
just below the import sys line to place your project on the path. Remember to replace 'mysite.settings' with your correct settings file, and '/path/to/mysite' with your own project's location.
OR
The other option is to run the dev server so it's accesible externally like so:
python manage.py runserver 0.0.0.0:80
though please DO NOT use this in production. The dev server is single-threaded, and has not been auditing for security.

Django Import errors on production environment

i have a trouble with run django project on production server with Apache and mod_wsgi. This Error happened when i'm start apache and go to site first time or go from other:
ImportError at /
Exception Value: cannot import name MyName
Exception Location /var/www/projectname/appname/somemodule.py
When i'm reload page the error disappears and site work fine. Another point is that this error happened selectively and sometime not appear.
In project i'm use imports without project name prefix (i mean 'from accounts.models import Account' instead 'from projectname.accounts.models import Account').
On development (manage.py runserver) server all work fine without any troubles.
I have used many variations of my apache and wsgi script configurations but problem is not solved.
Here my current projectname.wsgi:
#!/usr/bin/env python
import os, sys, re
sys.path.append('/var/www/projectname')
sys.path.append('/var/www')
os.environ['PYTHON_EGG_CACHE'] = '/var/www/projectname/.python-egg'
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
Here is some parts from apache config:
<VirtualHost ip:80>
ServerAdmin admin#server.com
DocumentRoot /var/www
ServerName www.projectname.com
WSGIScriptAlias / "/var/www/projectname/projectname.wsgi"
WSGIDaemonProcess projectname threads=5 maximum-requests=5000
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /var/www/>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
....
Also i'm use a separate Virtual Host for SSL.
I hope somebody help me.
Thanks!
When I had this problem, this post https://stackoverflow.com/a/10601523/1782780 pointed me towards the answer: I had a bug in a module further up the chain.
As Michal explains in that post:
Python does not just select that one class from the administrative/models.py file. Instead the Python interpreter reads the entire file, creates the module object, executes the code from the imported file in the new modules namespace, and then copies the name Contract from the new module's namespace to the current namespace. So, although it seems that you are importing just one class from a module, an error anywhere in that module can prevent a successful import - in your case it is an error with class ContractForm. The rest of the traceback details what exactly went wrong with that class.
So look further back in your traceback and you might find your problem.
I add a similar problem and the cause was that the 'current directory' was 'www' and not root project dir.
In the django development server the server environment is set according to the current project you are working. Thats why the import errors occur while shifting to Apache.
While using import use " from projectname.appname.models import MyModel ". Be as specefic as you can.
Use sys.path.append('location/to/your_project_foler/') in your case "/var/www"
Just a suggestion:
Also try to set-up django in another url than root. I also had a similar problem while trying to run django on the site root, i.e. :
WSGIScriptAlias /< some url > "/var/www/projectname/projectname.wsgi"
In my case it was a leftover directory from the past (filled with only the pyc compiled files which possibly caused the directory to stuck without deletion) which matched a new python file's name.
In the past a directory tasks was created in a module acme. Within that directory there was the __init__.py and four other python files.
The uwsgi service compiled the the pyc file for each of those python files once a request touched them.
Much later the files in that directory and the directory was removed from the Git source.
However because the .pyc files were in place the directory actually stayed on the server. (The git pull is incremental, we don't pull a complete source from ground zero).
Even more later (recently, now) I committed a tasks.py to that folder where there's this leftover tasks directory.
That made the uwsgi engine not being able to import anything from that file without any detailed reason.
The struggle to realize this took me more than half of my work day.