It is the 26th of June 2017

Mezzanine - How to use different layouts for domains. Simple multisite setup

In this tutorial I will show you how to setup a single Mezzanine codebase for multiple domains with different layouts.

All hail to the King

who wrote this brilliant Django based CMP.

Considerations

As long as I can remember I was never happy with any CMS solution out there because they were all too bloated for me. Mezzanine was the very first to give me really just what I needed, exactly what I wanted. So without further ado, let's start.

New mezzanine site

Install pip on your system and create your django mezzanine project:

# Install from PyPI
$ pip install mezzanine

# Create a project
$ mezzanine-project myproject
$ cd myproject

# Create a database
$ python manage.py createdb

# Run the web server
$ python manage.py runserver

take a look at your new site at localhost:8000.
Now this tutorial is not about developing mezzanine or to say Django so consult the official documentation of them and create a site to your needs.

Project layout

The focus of this tutorial is to show you a simple way on how to deploy to different domains using different layouts running from the same code repository. So when you host several sites and you want to introduce lets say a polls module to all of them you'd only have to change a single project for that and deploy it to different servers with different layouts. This is only useful for sites that have pretty much the same functionality of course, like different blogs for example.

For this purpose I use the following schematic directory structure: The different spins can be single domains or multiple domains whichever you need. You obviously want to use more expressive names than layoutA or spinA... for your real project.

  • myproject
    • ... (whatever you have in your project)
    • ./layouts
      • layoutA/templates...
      • layoutB/templates....
    • ./fabfile_spinA.py
    • ./fabfile_spinB.py
    • ./settings_spinA.py
    • ./settings_spinB.py
    • ./deploy
      • live_settings_spinA
      • live_settings_spinB

The layouts are simply python modules (django apps). In the simplest case they only provide some templates and static files.

Layout switching

Layouts are nothing more than INSTALLED_APPs. The only difficulty is to have only the desired layout module for a given site. So I introduce a new APP_LAYOUT variable that lives only in local_settings which are spin specific. So for local testing I would add the following to:

./local_settings.py

LAYOUT_APP = ("layouts.layoutA", )

and to:

./settings.py

INSTALLED_APPS = LAYOUT_APP + INSTALLED_APPS #@UndefinedVariable

after the load local_settings directive.

Deployment settings

Now I want some spin specific deployment settings. So I create several settings files:

./settings_spinA.py:

from settings import *

FABRIC = {
    "SSH_USER": "www-data", # SSH username
    "SSH_PASS":  "", # SSH password (consider key-based authentication)
    "SSH_KEY_PATH":  "/path/to/my/.ssh/id_rsa", # Local path to SSH key file, for key-based auth
    "HOSTS": ["33.33.33.24"], # List of hosts to deploy to
    "PROJECT_NAME": "spinA", # Unique identifier for project
    "REQUIREMENTS_PATH": "requirements/project.txt", # Path to pip requirements, relative to project
    "GUNICORN_PORT": 8022, # Port gunicorn will listen on
    "LOCALE": "en_US.UTF-8", # Should end with ".UTF-8"
    "LIVE_HOSTNAME": "prograssing.com www.prograssing.com m.prograssing.com someotherdomain.tld", # Host for public site.
    "REPO_URL": "/path/to/myproject.git", # Git or Mercurial remote repo URL for the project
    "DB_PASS": "supersecret", # Live database password
    "ADMIN_PASS": "12345", # Live admin user password
    "SECRET_KEY": "shhhh", 
    "NEVERCACHE_KEY": "aye",
}

./deploy/live_settings_spinA: This is going to be the local_settings of the remote deployment.

LAYOUT_APP = ("layouts.layoutA", )
ALLOWED_HOSTS = ("prograssing.com","m.prograssing.com","www.prograssing.com", "somedomain.tld")

The only thing left is a separate fabfile for this spin that uses the newly created settings.

cp fabfile.py fabfile_spinA.py

And modify the templates, settings file and whatever else you might want to change in the spin specific fabfile.

Repeat those steps for as many combination of spins and domains as you like.

Deployment

Finally all you have to do is:

fab -f fabfile_spinA.py all

And your site should be accessible from all domains specified in spinA settings files. This way you can deploy your site to different domains with different layouts using only very little modification and with no need to create separate code repositories or cloning the same one for that matter. This is a nice way to go if you have a few websites to administer or want to have a separate testing environment for example. However for that purpose you might want to have a build and ci server that separates the environment based on git branches.

Featured Apps

Free Money