3. Installing nitrate on RHEL6 with Apache and MySQL

This deployment document presumes that you are running Red Hat Enterprise Linux 6. Of course, all deployment steps being described through this document also apply to other Linux distributions, such as CentOS, openSUSE, or Debian.

This document aims to deployment within a server that will serve test case management service to stuffs or customers. Therefore, all commands and configuration are done with system Python interpreter and those configuration files installed in the standard system directories, like the /etc/httpd/conf/httpd.conf.

3.1. Installation

3.1.1. Get source code

The Nitrate source code is available at:https://github.com/Nitrate/Nitrate

You can get the latest changes with git easily:

git clone https://github.com/Nitrate/Nitrate.git
git checkout --track [a proper tag or branch]

3.1.2. Install dependencies

Install devel packages that should be installed first:

sudo yum install gcc w3m python-devel mysql-devel krb5-devel libxml2-devel libxslt-devel

Install dependencies from requirements/base.txt:

sudo pip install -r requirements/base.txt

3.1.3. Install from source code

After downloading the source code, go to the source code directory and install this project with python setup.py:

cd [nitrate_download_path]/nitrate
sudo python setup.py install

3.2. Initialize database

Database is required by Nitrate (and all of Django apps). Django ORM supports many database backends, we recommend you to use MySQL.

Create database and user for nitrate in mysql:

mysql> create database nitrate;
mysql> GRANT all privileges on nitrate.* to nitrate@'%' identified by 'password';

Update settings/product.py:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': 'nitrate',                      # Or path to database file if using sqlite3.
        # The following settings are not used with sqlite3:
        'USER': 'nitrate',
        'PASSWORD': 'password',
        'HOST': '',                      # Empty for localhost through domain sockets or '127.0.0.1' for localhost through TCP.
        'PORT': '',                      # Set to empty string for default.
    }
}

Create tables through syncdb & migrate and create super user if needed:

django-admin.py syncdb --settings=tcms.settings.product
django-admin.py migrate --settings=tcms.settings.product

Load initial data:

django-admin.py loaddata --settings=tcms.settings.product

3.3. Config Settings

First please go to nitrate root path, it’s different based on your current OS.

Like on RHEL6.3, the root path is located in:

/usr/lib/python2.6/site-packages/nitrate-3.8.6-py2.6.egg/tcms

As we plan to deploy a example server for nitrate, we can use product.py as the default settings. After backed up the product.py, please modify following settings based on your custom configurations in settings/product.py:

# Django settings for product env.

from common import *

# Debug settings
DEBUG = False
TEMPLATE_DEBUG = DEBUG

# Database settings
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'nitrate',
        'USER': 'nitrate',
        'PASSWORD': 'nitrate',
        'HOST': '',
        'PORT': '',
    },
    'slave_1': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'nitrate',
        'USER': 'nitrate',
        'PASSWORD': 'nitrate',
        'HOST': '',
        'PORT': '',
    },
}

# add RemoteUserMiddleWare if kerberos authentication is enabled
MIDDLEWARE_CLASSES += (
#    'django.contrib.auth.middleware.RemoteUserMiddleware',
)

# Remote kerberos authentication backends
#AUTHENTICATION_BACKENDS = (
#    'tcms.core.contrib.auth.backends.ModAuthKerbBackend',
#)

DATABASE_ROUTERS = ['tcms.core.utils.tcms_router.RWRouter']

# Kerberos realm
#KRB5_REALM = 'EXAMPLE.COM'

# Bugzilla integration setttings
# Config following settings if your want to integrate with bugzilla
BUGZILLA3_RPC_SERVER = ''
BUGZILLA_URL = ''
BUGZILLA_USER = ''
BUGZILLA_PASSWORD = ''

# JIRA integration setttings
# Config following settings if your want to integrate with JIRA
JIRA_URL = ''

# Set the default send mail address
EMAIL_HOST = 'smtp.example.com'
EMAIL_FROM = 'noreply@example.com'

# Site-specific messages

# This one, if set, is shown on the front page.
# It is only shown to authenticated users
MOTD_AUTH = """
<p>This is the development server for the production instance of the TCMS,
connected to a copy of the testopia database.</p>
"""

# First run - to detemine need port user or not.
FIRST_RUN = False

MOTD_LOGIN = """<p>This is the development server of the TCMS (for testing).</p>
<p>Please use your kerberos user name and password.</p>
"""
# You can add a help link on the footer of home page as following format:
# ('http://foo.com', 'foo')
FOOTER_LINKS = (
 ('/xmlrpc/', 'XML-RPC service'),
)

# added for nitrate3.4 compatibility
DEFAULT_GROUPS = ['default']
TESTOPIA_XML_VERSION = '1.0'

# admin settings
ADMINS = (
    # ('Your Name', 'your_email@domain.com'),
)

# user guide URL
USER_GUIDE_URL = ""

DEFAULT_PAGE_SIZE = 100

3.4. Use cache (Optional)

You can use Django’s cache framework to get better performance.

Refer to following docs for more details:

3.5. Start the django app

After upon steps is completed, now you can try to start the web server which is a built-in development server provided by Django to test if the app can run as expected. Run following command:

django-admin.py runserver --settings=tcms.settings.product

Then try to use web browser to open http://localhost:8000/ to verify the working status of this web service.

3.6. Install Apache & mod_wsgi

Install httpd & mod_wsgi:

sudo yum install httpd mod_wsgi

3.6.1. Create upload dir

Create upload dir and change dir own & group to apache:

sudo mkdir -p /var/nitrate/uploads
sudo chown apache:apache /var/nitrate/uploads

3.6.2. Collect static files

The default directory to store static files is /var/nitrate/static, you can modify it by changing STATIC_ROOT setting in /path/to/nitrate/tcms/settings/product.py.

Run following command to collect static files:

sudo django-admin.py collectstatic --settings=tcms.settings.product

Reference: https://docs.djangoproject.com/en/1.5/howto/static-files/deployment/

3.6.3. Deploy with Apache

Deploying Django projects with Apache and mod_wsgi is the recommended way to get them into production.

Create wsgi.conf in /etc/httpd/conf.d/ which include one line:

LoadModule wsgi_module modules/mod_wsgi.so

To build a production server with Apache, just copy apache conf to /etc/httpd/conf.d/.

I presume that the conf file is named nitrate-httpd.conf.

# Deployment using mod_wsgi
#
# Useful documentation:
# https://docs.djangoproject.com/en/1.5/howto/deployment/wsgi/

# Force the use of ssl:
#<IfModule mod_rewrite.c>
#    RewriteEngine on
#    RewriteCond %{HTTPS} off
#    RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI}
#</IfModule>

# Make sure static files collected to this dir
# Ref https://docs.djangoproject.com/en/1.5/ref/contrib/staticfiles/#django-admin-collectstatic
Alias /static /usr/share/nitrate/static

# Limit threads forked:
# prefork MPM 
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxClients 256
MaxRequestsPerChild 0

# Configurations for mod_wsgi
WSGIScriptAlias / /usr/lib/python2.6/site-packages/tcms/wsgi.py
WSGIPythonPath /usr/lib/python2.6/site-packages
WSGIPassAuthorization On

<Location "/">
    # ====================
    # Handler for mod_wsgi
    # ====================
    SetHandler wsgi-script

    Options All
    AllowOverride All
    Require all granted
    LimitRequestBody 10485760
    AddOutputFilterByType DEFLATE text/html text/plain text/xml text/javascript application/x-javascript text/css

    ErrorDocument 401 "Your request is unauthorization."
</Location>

<Location "/static">
    SetHandler None

    # Disable auth on the static content, so that we're aren't forced to
    # use Kerberos.  Doing so would remove "Expires" headers from the static
    # content, which would lead to poor page-load times.
    AuthType none
    Satisfy Any
    Allow from All

    # Many file types are likely to benefit from compression
    # Enable gzip compression on them:
    AddOutputFilterByType DEFLATE text/html text/plain text/xml text/javascript application/x-javascript text/css

    # Set far-future Expires headers on static content
    # (trac 184):
    ExpiresActive On
    ExpiresDefault "access plus 10 years"
</Location>

Change any configuration to fit your deployment environment.

In /etc/httpd/conf/httpd.conf, set the following settings simply:

ServerName example.com:80
Listen ip_address:80

After configuration, run:

sudo service httpd start

Please go to browser to have a verify if this service runs successfully.

If any problem, please refer to log file:

/var/log/httpd/error_log

Or any access info, refer to:

/var/log/httpd/access_log

3.7. Upgrading