How to support multiple self-contained production quality web sites based on django, postgres and nginx on a single server using mkwebsite

The mkwebsite package allows you to install multiple completely self contained production quality websites on a single server for development and debugging without root privileges. I have used it for web development on linux and Mac OS X. The sites generated can also be used in production.

I developed it because I wanted to be able to completely remove my development sites without leaving any system wide packages around that I didn’t need and because I wanted to compare security settings side by side for sites that were otherwise identical.

It is very easy to use, simply download the package, extract it and run the associated install script for each website that you want to create. It takes care of all the system administration details (like database and server configuration) so that you can concentrate on development.

Each website contains a web server (nginx), a database (postgres), a web framework (django), a web server gateway interface (uwsgi) to connect the framework to the server, caching using memcache and a host of client side tools for web development such as jquery, jquery-ui, cryptojs, tooltipters, bootstrap, datatables, dynatree and flot.

In addition each website has HTTP and HTTPS infrastructure with self signed certificates to get you started. Because HTTP and HTTPS ports (80, 443) are on privileged ports by default, the installation process will choose non-privileged ports for those services. Like almost all aspects of the package, these are fully customizable during installation.

And finally media and static files are handled by the server in the the django directory tree as the media and static sub-directories, respectively. You can, of course, customize the server to serve them from other hosts if you wish.

This package mkwebsite system incorporates the following open source packages and would not be possible without them. Please give them your support.

Package Version Type URL
bootstrap 3.0.3 client http://getbootstrap.com/
cryptojs 3.1.2 client http://code.google.com/p/crypto-js/
datatables 1.9.4 client http://datatables.net/
django 1.6.2 server https://www.djangoproject.com/
dynatree 1.2.5 client http://code.google.com/p/dynatree/
flot 0.8.2 client http://www.flotcharts.org/
jquery 2.0.3 client http://jquery.com/
jquery-ui 1.10.3 client http://jqueryui.com/
libevent 2.0.21 server http://libevent.org/
memcached 1.4.17 server http://memcached.org/
nginx 1.4.4 server http://nginx.org/en/
pcre 8.34 server http://www.pcre.org/
postgresql 9.3.2 server http://www.postgresql.org/
tooltipster n/a client http://iamceege.github.io/tooltipster/
uwsgi 1.2.6 server https://uwsgi-docs.readthedocs.org/en/latest/

The mkwebsite package is available as tar or zip files from the following links.

TYPE CHECKSUM INSTALLATION
tar.bz2 20780 $ wget http://projects.joelinoff.com/mkwebsite/mkwebsite.tar.bz2
$ tar jxf mkwebsite.tar.bz2
$ ./mkwebsite*/install.sh

tar.gz 62790 $ wget http://projects.joelinoff.com/mkwebsite/mkwebsite.tar.gz
$ tar zxf mkwebsite.tar.gz
$ ./mkwebsite*/install.sh

zip 13983 $ wget http://projects.joelinoff.com/mkwebsite/mkwebsite.zip
$ unzip mkwebsite.zip
$ ./mkwebsite*/install.sh

The table above shows how to run the install script for each different download type. As you can see, the package will be extracted to a local directory. At the time of this writing the version is 0.16 so the local install directory will be mkwebsite-0.16. The version number will change when new versions are released but the basic structure will be the same.

EXAMPLE: Download and Install

The example below shows how to install the tool.

EXAMPLE: Create a Website

Once the tool has been downloaded and extracted you can create a website by running the install.sh script in the mkwebsite-<version> directory.

Before starting this process you will want to choose a site name and an app name. I typically use a company name (like acme_inc) or a group name (like data_mining) for the site and the app name (inventory). The app name is really not that important because you easily add new apps in Django using the startapp command.

If you plan to install multiple websites, make sure that you use different ports for HTTP, HTTPS and the database to avoid creating hard to debug errors. Unfortunately this cannot be automated because the installations are local for easy removal and because other sites may not be running at the time of the install so the port use cannot be detected.

You will see that I used the “-p” switch to force the install script to prompt for each option. I did that because the install script remembers all of your previous entries so that you can re-use them. You always want to use this option if you are planning to install multiple sites. If you are only planning to install one then it doesn’t matter.

This example shows the long, interactive form. You can also run the whole thing using command line options and no prompts.

NOTE: You will not be able to install a web site if you do not have a development environment available that contains make, gcc, python and other tools used to build the infrastructure. Once the site is built you can migrate it to another server that does not contain those tools.

At this point the configuration is done and the install script calls the mkwebsite.py script which is the tool that does all of the heavy lifting. The full installation usually takes between 10 and 20 minutes depending on your host and internet connection speed.

It generates a lot of output which is captured in a log file in the acme_inc/rtf/log/install.log file. At the end you will see a message that looks something like this that tells you how to manage the web server.

As you can see, the installer created a custom website manager tool was created called “acme_inc/rtf/bin/acme_inc-mgr.py” that provides a number of commands for managing the server.

There are commands for starting the server, stopping the server, determining the status of the server, for collecting static data for django, for database management and so on. Although each of these can be run independently using tools like psql (for the database) or in your own custom python script, having them in a single manager tool is very convenient.

With all of this in place you can start the webserver as follows:

You can check the webserver status like this:

To stop the web server simply use the “stop” command.

Now that that the webserver is running you can access it using your favorite browser at http://localhost:9080 or https://localhost:9081.

Here is a screen shot showing what this site looks like in firefox.

mkwebsite-1

Now you can customize it using python and the django infrastructure.

Delete a Website

Deleting a website is trivial. Simply stop it using the manager in <website>/rtf/bin and then delete the directory tree using rm.

Production Considerations

Because the website is completely self contained, it is easy to copy it around for use in production systems. Just keep the following considerations in mind.

You do not need to install development tools like make or gcc on the production website because you are only using the results of the build/installation.

Directories are hard coded during the installation so the location on the production site must be the same as the location on the development site. I typically use a location like “/opt/website” as the root.

To install on the production site, all you need to do it copy over the entire website directory tree or use the update/get option of a distributed version control system like git. In both cases the src sub directory tree can be ignored.

One final consideration is that you should use the same user on both systems. Although that is not required it makes things simpler.

Directory Structure

The website directory is a combination of the root directory and the website name. For the example above the website directory is “/Users/jlinoff/webdev/acme_inc” where “/Users/jlinoff/webdev” is the root.

Here is a list of interesting sub directories under the website installation directory.

DIRECTORY DESCRIPTION
django/<website> The django directory tree.
This is where the django management tools, apps, static and media directories
are located.
The initial app directory is in django/<website>/<app>.
The main website directory is in django/<website>/<website>.
The media directory is in django/<website>/media.
The static directory is in django/<website>/static.
rtf The release to field directory.
This is where the production versions of the database (postgres), server (nginx),
gateway interface (uwsgi), the logs and the management tools are located.
src The directory tree that contains the source code for the installed packages.
venv The python virtual environment for the website.
You must call <website>/venv/bin/activate before doing any django work.

Conclusion

As you can see from this brief introduction, mkwebsite is a powerful tool for helping you develop, maintain and test websites. It also useful for learning how the infrastructure of a website works.

I hope that you find it as useful as I have.

Enjoy!

2 thoughts on “How to support multiple self-contained production quality web sites based on django, postgres and nginx on a single server using mkwebsite”

Leave a Reply