Setting up a web-server for flask-app deployment in mod_wsgi :: Part-2 ::

Before we start I would assume we are ready with our cloud instance and are able to connect to it via ssh as shown in Part-1 of this post. I expect that you have your flask application ready already. Lets start with setting up the web-server without anymore delay. We can deploy our application in many ways, but we will be focussing on mod_wsgi in this post. First we need to install some of the basic packages needed for setting up a web-server.

sudo apt-get install apache2 libapache2-mod-wsgi #For Debian/Ubuntu:

sudo yum install mod_wsgi                        #For Rpm based OS

You can test if things are working and server is up, just find out your public IP from amazon ec2 console, and type it in your browser. This should show the default pages. Next we need to get our flask app into the instance. For this i used github as remote repository. You need to install Git and then Git clone your repo into the user home. Now setup virtualenv and install the dependencies(installing dependencies into virtual environment is a good practice) :

sudo apt-get install python-pip 
or                                  #depending on the OS
sudo yum install python-pip 
sudo pip install virtualenv

Now that you have your virtualenv installed we will now create our virtual environment

virtualenv 
eg: virtualenv env
source /bin/activate #to activate the virtualenv

you can singly install dependencies as

pip install <package-name>

Or install from a requirements.txt file as

pip install -r requirements.txt

Now copy your whole project along with virtual environment to ‘/var/www/’ folder.

sudo cp /current/path/app-root /var/www/ -r

:: Adding your .wsgi file::

Now that you are ready lets add a new file to our app root called the named ‘youappname.wsgi’ Having the content

from yourapplication import app as application //structure this line such that you must be 
                                               //able to import app from your flask-app as 
                                               //application

To run our app we need to specify the environment path.

Method 1:
Adding the following two line to the top of your .wsgi file.
activate_this = '/var/www/project-root/your_virtualenv/bin/activate_this.py'
execfile(activate_this, dict(__file__=activate_this))

Method 2:  This method will be shown in the next topic

::Writing config file for apache::

This took me some while to figure out how and what to write in this file. You need to create a configuration file for apache.

sudo vi /etc/apache2/sites-enabled/000-default.conf    // for Ubuntu
sudo vi /etc/httpd/conf.d/wsgi.conf  //for RHELorAmazon Linux

Now add the following line to the file. Method 2 for adding virtual environment path is shown below.

WSGISocketPrefix /var/run/wsgi        // to avoid permission denied error in RHEL or Amazon 
                                      // Linux , not necessary in ubuntu

ServerName yourservername.com   
WSGIDaemonProcess yourappname user=user1 group=group1 threads=5 python-path=/var/www/yourappname:/var/www/test_app/env/lib/python2.6/site-packages    //running as different user is 
                                                          //good for security reason
WSGIScriptAlias / /var/www/yourappname/yourappname.wsgi

           WSGIProcessGroup yourappname
           WSGIApplicationGroup %{GLOBAL}
           Order deny,allow
           Allow from all

You can check the link if you find things confusing. In mod_wsgi jinja2 won’t show you errors in browser even if you put ‘app.debug=True’ instead you can make your app show debug output and print statements in terminal. For this you need to add

WSGIRestrictStdout Off

in the config files. You need to open these config files using vi editor.

sudo vi /etc/apache2/apache.conf    // for Ubuntu
sudo vi /etc/httpd/conf/httpd.conf  //for RHELorAmazon Linux

Now ubuntu users need to enable mod wsgi and restart server.

sudo a2enmod wsgi 
sudo service apache2 restart

RHEL users just need to restart their server. To do so type

sudo service httpd restart //you may get a [FAIL] for stopping server, that's ok because you are running apache 1st time.

If things work fine well and good if not then you can have a look at the error logs.

sudo tail -f /var/log/apache2/* //for Ubuntu
sudo cat /etc/httpd/logs/error_log //for RHEL/Amazon Linux

Now if you look closely in the config file, we wrote user=user1 & group=group1. These needs to be created. For this: You can check the current owner and their permission using

ls -ld /var/www/site1/
drwxr-xr-x 2 root root 4096 Oct 10 11:21 site1/

Create the group first and then add the user to it.

sudo groupadd group1

Now adding the user to the new group

sudo useradd user1 -g group1

Also we need to add the apache user to this group but first we need to find it

finding the apache user,
ps aux | grep apache  //for Ubuntu it's generally www-data
ps aux | grep httpd   // for RHEL/Amazon Linux it's generally apache 
then,
sudo usermod -a -G group1 <user>  //user as found from the above commands

You can now verify if the user you created is in the new group

groups user1
user1 :  group1 //output

Now we will change the ownership of the flask-app folder to group1 so that it has full access only to that folder. This will let the app create new files or upload files into the server.

sudo chown -vR :group1 /var/www/site1/
changed ownership of `/var/www/site1/' from root:root to :group1
chown -> change ownership
-v    -> verbose it shows file names affected by the command
-R    -> recursively applies to all children
:group1 -> name of the new group1
sudo chmod -vR g+w /var/www/site1
mode of `/var/www/site1/' changed from 0755 (rwxr-xr-x) to 0775 (rwxrwxr-x)
chmod -> change mode bit
-v    -> verbose output
-R    -> Apply recursively
g+w   -> give write access to group

Now you can verify if group1 has been added

ls -ld /var/www/site1/
drwxrwxr-x 2 root group1 4096 Oct 10 11:21 /var/www/site1/

Restart your server and check . If you liked this blog give it a like and share it. Happy Coding. Continue reading “Setting up a web-server for flask-app deployment in mod_wsgi :: Part-2 ::”

Setting up a web-server for flask-app deployment in mod_wsgi :: Part-2 ::

Setting up a web-server for flask-app deployment in mod_wsgi :: Part-1 ::

Here i have discussed how to setup your cloud instance and connect to it. If you are already able to connect to your instance you can directly goto the Part-2 of this article.This week I had a tough time setting up my web-server for my flask-app. Firstly you need to get your server instance ready. I opted for AWS EC2 Instance for my app. you can look at these suggestions below for cloud server providers.

@ Amazon EC2

@ Crowncloud

@ DigitalOcean

How to launch EC2 Instance?

If you selected AWS as your cloud server provider then you can continue reading else for others if your instance is ready you can directly jump to Connecting to your Instance. For AWS you need to create an account and login, then from aws console goto EC2 dashboard and then “Launch Instance”. Select your Instance configuration and launch it.

Step 1:: Select you Instance Image, which in simple works is the OS you want to use. I used Ubuntu Server 14.04 LTS (HVM), SSD Volume Type 64-bit

Step 2:: Next choose the Instance Type depending on your needs. Step 3:: For now we are going to opt for the default settings.

Step 4:: Attach a volume to your Instance. Specify the required size and type of Volume you need.

Step 5:: You can Tag your instance for better identification of the instance.

Step 6:: You can choose a security group if group already exists or create a new group. To create a new group select the “create new” option give a proper name to your security group, then add rules to it. For now we will add two rules:

Rule1 : set type as "ssh" and source "my ip" or "custom ip" (recommended), selecting "anywhere" may be a security loophole.
Rule 2: set type as HTTP and source anywhere.

Step 7:: Review and launch the instance. You will be asked to create a key pair or choose an existing one. To create new enter the key-pair name and download. Note: Do remember the downloaded key file location we will be needing it later. Congrats Your Instance has been created!!!

How to connect to the instance?

If you are using windows in your local machine you can follow this link to connect to your instance using putty. You can get putty and puttygen from here. Linux users have ssh installed by default so I will be using ssh from my local fedora machine to connect to my ubuntu instance. Before you connect change the file permission of the key-file

$chmod 400 /path/to/my_key_file.pem

Now to connect to the instance:

$ssh -i path/to/your/key-file.pem <user>@<public dns>

eg:
$ssh -i ~/.ssh/awskey.pem ec2-user@ec2-54-183-159-198.us-west-1.compute.amazonaws.com

Now , the key-file.pem here is the file that was downloaded to your machine while creating a new key-pair. The user here is ec2-user or root for Red-Hat Linux , ec2-user for Amazon Linux and ubuntu for Ubuntu. You can get your Public DNS from your instance page as shown below.

Public DNS

If its the first time you are logging into the instance you will be asked if it can store the ECDSA fingerprint. Type in “yes” and it will be added to your list of known host. Next time you will be spared from these questions. SSH

In the next part we shall discuss how to deploy the application in server.

Note: For people with dynamic ip may have prolbem connecting to your instance if your ip gets changed (like mine). Solution is open EC2 dashoard -> Security Groups -> select the security group attached to your instance -> Click the “Inbound” tab below -> edit -> Change the source for ssh to my ip -> Save . Now try logging in from your terminal.

Setting up a web-server for flask-app deployment in mod_wsgi :: Part-1 ::