Installation Read The Docs

First, obtain Python 2.7 and virtualenv if you do not already have them. Using a virtualenv environment will make the installation easier, and will help to avoid clutter in your system-wide libraries.

Python 2.7

To install Python 2.7 from source, please see How to install Python 2.7 from source on CentOS.

Linux users may find they need to install a few additional packages in order to sucessfully execute pip install -r requirements.txt. For example, a clean install of CentOS 5.11 (Final) will require the following packages:

yum -y groupinstall "Development Tools"
yum -y install python-devel python-setuptools
yum -y install libxml2-devel libxslt-devel zlib-devel
cd /tmp
wget --no-check-certificate

Git 2.8

You will also need Git in order to clone the repository.

yum -y install curl-devel
yum -y install perl-devel
tar xf git-2.8.2.tar.gz
cd git-2.8.2
./configure --prefix=/usr/local
make install

Read The Docs

Once you have these, create a virtual environment somewhere on your disk, then active it:

virtualenv rtd
cd rtd
source bin/active

Create a folder in here, and clone the repository:

mkdir checkouts
cd checkouts
git clone

Next, install the depedencies using pip (included inside of virtualenv):

pip install -r requirements.txt
  • Could not find a version that satisfies the requirement backports.ssl_match_hostname (from tornado>=4.1->mkdocs==0.14.0->-r requirements/pip.txt (line 7)) (from versions: )

    No matching distribution found for backports.ssl_match_hostname (from tornado>=4.1->mkdocs==0.14.0->-r requirements/pip.txt (line 7))

     source rtd/bin/active
     cd /tmp 
     tar xf backports.ssl_match_hostname-
     cd backports.ssl_match_hostname-
     python install

This may take a while, so go grab a beverage. When it’s done, build your database:

./ migrate

Then please create a super account for Django

./ createsuperuser

Next, create an account for API use and set SLUMBER_USERNAME and SLUMBER_PASSWORD in order for everything to work properly.

./ shell
>>> from django.contrib.auth.models import User
>>> user = User.objects.create_user('test','','test')
>>> user.is_staff = True

Now let’s properly generate the static assets:

./ collectstatic

Finally, your’re ready to start the webserver:

./ runserver

For builds to properly kick off as expected, it is necessary the port you’re serving on (i.e. runserver match the port defined in PRODUCTION_DOMAIN. You can utilize to modify this. (By default, it’s localhost:8000)

If you put a file named in the readthedocs/settings directory, it will override settings available in the base install.



TIME_ZONE = 'Asia/Chongqing'

DEBUG = False

Configuration of the production servers


To install uWSGI with Python support, please refer to Python & WSGI applications

cd rtd
source bin/active
pip install uwsgi

Configuration file readthedocs_wsgi.ini

ini = :pro

env =
ini = :readthedocs

env =
ini = :readthedocs

virtualenv = /home/x/rtd/
chdir = /home/x/rtd/checkouts/
wsgi-file = readthedocs/
# module = django.core.handlers.wsgi:WSGIHandler()
# module = readthedocs.wsgi:applicaiton

# http =
socket =
# socket = /tmp/%n.sock
# chmod-socket = 777

uid = x
gid = x

stats =
pidfile = logs/
# daemonize = logs/%n.log

master = true
workers = 4
enable-threads = true

vaccum = true


Building nginx from Sources, refer to Building nginx from Sources

tar xf nginx-1.10.0.tar.gz
tar xf pcre-8.38.tar.gz
tar xf zlib-1.2.8.tar.gz
cd nginx-1.10.0
make && make install

Configuration File’s Structure


location / {
        include uwsgi_params;
        uwsgi_read_timeout 60;

location /static/ {
        alias /home/x/rtd/checkouts/;

location /media/ {
        alias /home/x/rtd/checkouts/;

location /docs/ {
        alias /home/x/rtd/checkouts/;
        index  index.html index.htm;

XSendfile: Nginx & Django


location /protected/docs/ {
        alias /home/x/rtd/checkouts/;
        index  index.html index.htm;

from django.http import HttpResponse

class AuthenticationMiddleware(object):
    def __init__(self):
        self.mime_map = {
            '.css': 'text/css',
            '.htm': 'text/html',
            '.html': 'text/html',
            '.jpeg': 'image/jpeg',
            '.jpg': 'image/jpeg',
            '.js': 'application/javascript',
            '.json': 'application/json',
            '.zip': 'application/x-zip-compressed',
        self.protected_url = '/protected'

    def is_authenticated(self, request):
        return True

    def x_accel_redirect(self, request_path):
        resp = HttpResponse()
        ext = path.splitext(request_path)[1]
        if ext:
            resp['Content-Type'] = self.mime_map[ext]
        resp['X-Accel-Redirect'] = self. protected_url + request_path
        return resp

    def process_request(self, request):
        if request.path.startswith('/docs') and self.is_authenticated(request):
            return self.x_accel_redirect(request.path)