Search

04 December, 2018

Production server launch using Django and Apache and mod wsgi

Some of us develop Django applications which can be used inside Intranet for various purposes.
Some ideas are:
  • HRMS apps
  • Interview Management Tools
  • Grievance Management Tool
  • Financial Report Generators. 

These apps running on intranet, generally don't face too much traffic at a time, but they do need to compute or face heavy queries which is why, it's a good idea to release them on a proper environment . Typically they are light on UI. I choose to use bootstrap which is enough to achieve a decent look . 
Still you should serve them using something which is good at serving static content. So I chose Apache. Lets get started. 


----------------------------------------------------------
1. Server Requirement
----------------------------------------------------------

  • For source Control: svn
  • For database: MySQL
  • For project: Python2.7
  • OS: Ubuntu 16.04
  • For serving the Project: Apache2


Even though your Linux instance is dedicated to your project, you must still choose to use a virtualenv


----------------------------------------------
2. Test your Server
----------------------------------------------

I assume that you have been given a fresh server with credentials. We will need Putty to login to it and WinSCP for any file transfer. Test if you can connect to it . You will need IP address of the server, username and password.

----------------------------------------
3. Test Apache2
----------------------------------------
I am assuming you have been given Apache2 installed on you server. If not , use this to install it:

sudo apt-get install apache2

On your PC browser, launch : serverip e.g xxx.xxx.xxx.xxx

You must see the default Apache Welcome page. This means Apache is working fine.

-----------------------------------------------------------------------------------------------------------------
4. General Installations: (use sudo if required)
-----------------------------------------------------------------------------------------------------------------

Subversion: 
apt-get install subversion

Pip and other essentials: 
apt install python-pip python-dev build-essential

Mod Wsgi module for Apache: 
sudo apt-get install libapache2-mod-wsgi

For MySQL to work with Python:
apt-get install libmysqlclient-dev

------------------------------------------------------------------------------------------------------
5. Creating a Virtual Env and activating it
------------------------------------------------------------------------------------------------------

5.1 Now, we need to create a virtual env and install everything we need for our project to run.
 ---------------------------------------------------------------------------------------------------------------------------------

Assuming your prompt is at location /home/username

$ virtualenv ProdEnv

This takes some time . After it finishes, do a "ls" and check if a folder has been created.

Note: If you are setting up on "pythonanywhere", then use:

mkvirtualenv ProdEnv --python=/usr/bin/python3.8 

5.2 Now activate this virtual env :
 -------------------------------------------

"source ProdEnv\bin\activate"

Note: If you are using Pythonanywhere (2021), then use "workon venv" to activate.

-----------------------------------------------------------------------------------------
6. Package installations.
-----------------------------------------------------------------------------------------

Now that our VirtualEnv is activated, lets start installing all packages.

  • pip install Django==1.11.0
  • pip install mysqlclient


Note: If you have other external packages , install them now.

-------------------------------------------------------------------------------------
7. My SQL Setup Test
-------------------------------------------------------------------------------------
Check your MySQL installation by trying to login to it :

$ mysql -u username -p
Enter password

If works , yay.

$ show databases; # Check what db are present.
$ create database db_name; # Create you new database to be used with the website.
$ create user UserName identified by 'some_password'; # Create a user that will be used. We must not use root.
$ grant all on db_name.* to 'UserName'@'%'; # Give permissions for the db to this user.
$ flush privilages; # when we grant some privileges for a user, running the command flush privileges will reloads the grant tables in the mysql database enabling the changes to take effect without reloading or restarting mysql service

------------------------------------------------------------------------
8. Checkout the Project files
------------------------------------------------------------------------
Here I am using SVN for source control. My Django project files are committed on it. We need to bring that inside our server.

svn co project_url

The project location should be /home/user/

-------------------------------------------------------------------------------------------------------------
9. Changes in settings.py file (In the Project Folder)
---------------------------------------------------------------------------------------------------------------

My project tree looks like this. MySite contains settings.py and other files :

E:.
├───.idea
│   └───scopes
└───MySite
    ├───mysite
    └───polls
        ├───migrations
        ├───static
        │   └───polls
        └───templates
            └───polls

After these steps, edit the settings.py file

1) Replace username with the above "UserName" and also the password.
2) In the list ALLOWED_HOSTS , only the server address "xxx.xxx.xxx.xxx" should be there.


-------------------------------------------------------------------------------------------------------------------
10. Transfer you MySQL db file from you dev environment to production server
--------------------------------------------------------------------------------------------------------------------

Ignore this section if you don't need old data , and you need a fresh db.

10.1 On Local PC (Development PC)
    ---------------------------------------------------------------------
  1. Check databases with "Show databses;)
  2. In Prompt: C:\Users\username>mysqldump -u root -p --databases db_name> project_name.sql
  3. Now using WinSCP, copy the MySQL file in some place (preferably root)


10.2 On Server
    -------------------------------------------

mysql -u root -p db_name< project_name.sql


--------------------------------------------------------------------------------------------------------
11. Configure Apache to serve static files.
--------------------------------------------------------------------------------------------------------

11. 1 In a nut shell , Apache will be running our Django app using the wsgi.py file located inside the Django project folder . Refer the tree shown above. We don't need to run our project explicitly on a shell.

  • -- Apache needs to know where is our project.
  • -- Apache needs to know about static files.
  • -- Apache needs to know, we are using a virtual environment. 


11.1.1 Step 1 : First check if mod_wsgi module for Apache is successfully installed:

$sudo service apache2 restart
$ sudo a2enmod wsgi

Module already exists

This means, module was successfully installed.

11.1.2 Step 2: Apache2 config files.
--------------------------------------------------------------------------------------------------

There is the main config file called : /etc/apache2/apache2.conf . Add to this at the bottom of the file,

WSGIPythonPath /home/user/MyDjangoProject

This is the path to your project (you can find that by executing "pwd" while inside the Project in prompt. Add this on the last line.

11.1.3 Step 3: Location of apache files: /etc/apache2/sites-available/
---------------------------------------------------------------------------------------------------------------------------------------------------

In the above "sites-available" folder, you will find two files. Create a backup copy of the file

 cp 000-default.conf 000-default_copy.conf

Edit the file 000-default.conf and add the follow:

<VirtualHost *:80>
        ServerName example.org
        ServerAlias www.example.org
        ServerAdmin somebodies_mail@somemail.com
        DocumentRoot /home/user/MyDjangoProject
        WSGIScriptAlias / /home/user/MyDjangoProject/MySite/wsgi.py
        Alias /static /home/user/MyDjangoProject/static/

        <Directory /home/user/MyDjangoProject/>
                Require all granted
        </Directory>

        # 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".
        #Include conf-available/serve-cgi-bin.conf
</VirtualHost>




11.2 By Default, apache is configured to pick files from folder: /var/www/html (which has a single file index.html")
--------------------------------------------------------------------------------------------------------------------------

After making all changes to apache.conf and sites-available\000-default.conf , restart Apache2:

service apache2 restart

Note: Apache Logs can be found in this location:

/var/log/apache2/

Under this folder, access.log and error.log are the main logs.

--------------------------------------------------------------------------------------------------------------------------------------------------
12. Add statements to activate VirtualEnv when Apache starts
--------------------------------------------------------------------------------------------------------------------------------------------------

We activate our virtualenv before we can start our Django server.  For this we need to add a few lines MySite/wsgi.py file. Add the lines to the top of the wsgi.py file. These should be the first 3 lines.

virtual_env = '/home/user/ProdEnv'
activate_this = virtual_env + '/bin/activate_this.py'
execfile(activate_this, dict(__file__= activate_this))

Note: This "activate_this.py" file can be found inside the "ProdEnv/bin/" You don't need to create it.

-------------------------------------------------------------------------
13. Give Permissions to log file
-------------------------------------------------------------------------

chmod 777 MyDjangoProject\MySite\Logs\debug.log

Restart Apache2 and visit the site at address xxx.xx.xx.xx


----------------------------------------------------------------------------------------------------------
********************************* Finish ********************************


No comments:

Post a Comment