Showing posts with label Apache. Show all posts
Showing posts with label Apache. Show all posts

Saturday, 31 July 2010

Production Flask app on CENTOS and Apache via mod_wsgi

Flask is a Python web framework which embraces simplicity and seems to work. It is based on Werkzeug so it is a WSGI application.

I've had some luck in the past using mod_wsgi to run Django apps, so I suspect getting a Flask app to run will be similar.

Using Google, I found the following in the Werkzeug Docs, which I reviewed for the following steps:

1. Install python2.7, mod_wsgi and Flask on production server.

Using Centos 5.4 (unbranded RHEL) comes with with python 2.4 and apache 2.2. Centos (and RHEL) use Python extensively under the hood (for Yum, among other things). I want to use a later version of Python, but one may not simply "upgrade" the version of Python- without breaking the OS - you need to install an additional version. I followed the steps in this guide, under the head "Install Python":
I chose to use Python 2.7 as its the last stable release of Python 2, and I don't intend going Python 3.* for a while. I hope I don't regret that. I needed to change a few things in obvious places as the guide covers Python 2.6.


Next I carried out the steps labelled "Install Setuptools" as this is necessary.

Next I carried out the steps labelled "Install mod_wsgi", restarted httpd and it started!

To install Flask I ran SetupTools explicitly from the location inside of /opt/python2.7/ to install 'pip' into the 2.7 Python distribution. Next I added an alias to pip to the ~/.bash_profile in the same way this was done for the python binary in the VenkysBlog page. Finally I used the source command to load the alias and ran:

pip install Flask

2. Create an appropriate wsgi file.


WSGI uses a file with the extension .wsgi as the interface between the wsgi container (in this case Apache / mod_wsgi) and the app. Flask has excellent documentation:

Steps are as follows:

  1. Place Flask application in a subfolder of the webroot (for testing I just used the "Flask is Fun" example: http://flask.pocoo.org/).
  2. Make a file called 'yourapp.wsgi' in the same structure - this is written in Python syntax - here you need to import your app and bind it to the name 'application'. mod_wsgi will then call this object in the appropriate way.

3. Edit apache configuration to invoke wsgi application.


Finally some directives need adding to httpd.conf. The LoadModule statement was added as part of step 1, however the wsgi file need to be referenced vs. the appropriate virtual root.



Great so everything worked! Wasn't that easy?

Friday, 2 April 2010

Apache SSL configuration and Django

https://help.ubuntu.com/9.10/serverguide/C/httpd.html

Using mod_wsgi to support Django development via Apache

I'm building a Django shop which integrates PHP components in the form of a blog (Wordpress) and needs testing with SSL. As discussed in the last blog entry- that means I can't well test holistically using only the Django dev server. On production I am using mod_python at the moment, which is inappropriate for development as I would need to restart the server each time I make a change.

I'm looking to follow a recipe, using mod_wsgi for two purposes:
  • To have a dev server running via apache, to integrate PHP and SSL components, as well as having "hot code replacement" to support development.
  • To evaluate mod_wsgi on the basis of the claim: "for hosting WSGI applications in conjunction with Apache it has a lower memory overhead and performs better than mod_python".

Step 1 will be to deploying using mod_wsgi on my dev laptop per the mod_wsgi docs.
  • sudo apt-get install libapache2-mod-wsgi [ubuntu]
  • restart apache
Step 2 is a standard integration with Apache. Per http://code.google.com/p/modwsgi/wiki/IntegrationWithDjango
  • create appropriate .wsgi file
  • edit apache.conf with directive (see below)
Step 3 is getting it to then run in daemon mode. This is a little like what mod_jk or ruby passenger / mod_rails does. It brokers requests off to a separate sub process which forks and brokers off to individual Python Django scripts.

Step 4, finally per: http://blog.dscpl.com.au/2008/12/using-modwsgi-when-developing-django.html, is to add a monitor.py (the source of which is here) and reference it in the .wsgi file.

Here are example apache / httpd.conf:


And dev.wsgi (based of putting a monitor.py in the root of the django app):

Apache Virtual Hosts

In putting together this online shop, I'm going to integrate a Wordpress Blog, and need SSL in addition to my Django app. The Django development server is not going to cut it.

In order to build out my Dev laptop I'm going to setup Apache with virtual hosts, and setup Django to run in a dev mode but behind Apache. This is a hit in time upfront, but should sharpen a few skills on the sysadmin side, make development testing and deployment more straightforward on an ongoing basis. I should consider future project also, so I need to specify the clients as well as the sub-project in the URL.


http://onlamp.com/pub/a/apache/2003/07/24/vhosts.html

So, I'm going to add a few hosts into my laptops host file based name resolver. So using "sudo vi /etc/hosts" I add these as aliases for the IP Apache is listening on.

127.0.1.1 hostname blog.client1.net www.client1.net

I test these out with a browser and they all take me to the same default page served by Apache on port 80. Per:

If Apache has no vhosts, it will use the main server's DocumentRoot directory (often set to /var/www/html).
Bingo. Now to change the behaviour of Apache.

Within a vhost block--between  and  tags in httpd.conf--many directives may be given, but only two are typically required: the ServerName and the DocumentRoot directives. As a matter of good form,vhost blocks and related directives should go at the end of the httpd.conf file. 
So using "sudo vi /etc/apache2/apache2.conf", added the following:


Tuesday, 3 November 2009

Restarting Apache in CENTOS / RHEL

/sbin/service httpd restart

May work without the /sbin/ depending on the path.

Monday, 2 November 2009

Automated Rails Website Clone / Mirror with WGet and FTP script.

As a bit of paid work outside of my day job I wrote a css layout for someone's business website. It was just a product presentation site. Eventually I was being asked to update it all the time so I wrote a rails app to allow stuff to be added by the customer in a 'wiki' style manner: [http://code.google.com/p/rapid-space/].

At first I had this served from my host, but it was a bit slow and occasionally my host had issues. So I've moved the rails app onto another domain, and each week I'm looking to configure a copy process to mirror the rails site, then FTP it up to my customer's own public host.
Clone locally
First step is to clone the site generated from the rails app into a static folder on my host, which is running CENTOS. I did this using wget:
  • [root@host ~]# wget --mirror -w 2 -p --convert-links -P foldertocopy2 http://rooturltomirror/
Annoyingly, the site came out unviewable: the HTML was OK, but the link to the CSS and the images were all broken. This was due to a random number appended to each CSS and Image URL such as ?323124124. These were generated using the Rails Asset Tag helper: http://api.rubyonrails.org/classes/ActionView/Helpers/AssetTagHelper.html
Given the scale of this site, there is no benefit to leaving the asset timestamps feature switched on, so I turned it off as follows ... in /config/environment.rb add:
Finally, I was missing files which were linked to via the CSS file, i.e. via @import url("importthis.css"); or images which are only referenced by the css file. Given these files are not subject to change, I'm going to overwrite them from a static folder when I upload to the public host- I can use the same mechanism to blank out the forms (which won't work on a static host).
FTP to the public domain.
I just tried to use the ftp client built into CENTOS for this, and echo the commands into it via the EOF mechanism in a shell script, per: http://www.cyberciti.biz/faq/linux-unix-autologin-cron-ftp-script/

However, using the standard ftp command you can't recurse through directories. I.e. you can copy all files in a directory, but not descend into sub directories. First I looked at a scripted option such as: http://expect.nist.gov/example/rftp . This approach made me nervous so I upgraded to lftp on my host ... [yum install lftp], and found I could upload the site as follows (with the command 'mirror -R'):
  • [root@host ~]# lftp public-host-ftp-server -u ftpusername, ftppassword -e "mirror -R /local/source /remote/destination"