Wagtail Multi-Site Setup

Our company is engaged in the development, support and maintenance of sites of any complexity. From simple one-page sites to large-scale cluster systems built on micro services. Experience of developers is confirmed by certificates from vendors.
Development and maintenance of all types of websites:
Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Our competencies:
Development stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1212
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    852
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1041
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    822
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Website development for FIXPER company
    815

Wagtail Multisite Configuration

Wagtail supports multiple sites within one installation. One Django project, one database, one admin panel, but different domains with independent page trees. Architecture suits holding companies, agencies managing client sites.

How Multisite Works

Wagtail stores site config in wagtailcore_site table. Each record contains:

  • hostname — domain
  • port — port (80/443)
  • root_page — root of site tree
  • is_default_site — default site flag

When request arrives, Wagtail checks Host header and selects the site.

Basic Setup via Admin Panel

  1. Create root page for each site (usually HomePage)
  2. Add Sites record with domain and root page
  3. Repeat for each domain

For local development with multiple domains, add to /etc/hosts:

127.0.0.1  brand-a.local
127.0.0.1  brand-b.local

Programmatic Setup via Data Migration

For reproducible setup:

# migrations/0002_multisite_setup.py
from django.db import migrations

def create_sites(apps, schema_editor):
    Site = apps.get_model('wagtailcore', 'Site')
    Page = apps.get_model('wagtailcore', 'Page')

    brand_a_root = Page.objects.get(slug='brand-a')
    brand_b_root = Page.objects.get(slug='brand-b')

    Site.objects.filter(is_default_site=True).update(
        hostname='brand-a.example.com',
        root_page=brand_a_root,
    )

    Site.objects.create(
        hostname='brand-b.example.com',
        port=443,
        root_page=brand_b_root,
        site_name='Brand B',
        is_default_site=False,
    )

class Migration(migrations.Migration):
    dependencies = [('website', '0001_initial')]
    operations = [migrations.RunPython(create_sites, migrations.RunPython.noop)]

Multisite Settings

BaseSiteSetting binds settings to specific site:

from wagtail.contrib.settings.models import BaseSiteSetting, register_setting

@register_setting
class BrandSettings(BaseSiteSetting):
    logo = models.ForeignKey('wagtailimages.Image', null=True, blank=True, on_delete=models.SET_NULL)
    primary_color = models.CharField(max_length=7, default='#000000')
    footer_text = models.TextField(blank=True)

    panels = [
        FieldPanel('logo'),
        FieldPanel('primary_color'),
        FieldPanel('footer_text'),
    ]

    class Meta:
        verbose_name = 'Brand Settings'

In templates:

{% load wagtailsettings_tags %}
{% get_settings %}
<style>:root { --primary: {{ settings.website.BrandSettings.primary_color }}; }</style>

Nginx Routing

upstream wagtail {
    server 127.0.0.1:8000;
}

server {
    listen 443 ssl;
    server_name brand-a.example.com;
    location / {
        proxy_pass http://wagtail;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto https;
    }
}

Editor Access Control

from django.contrib.auth.models import Group
from wagtail.models import GroupPagePermission

def setup_brand_editors(brand_root_page, group_name):
    group, _ = Group.objects.get_or_create(name=group_name)
    GroupPagePermission.objects.get_or_create(
        group=group,
        page=brand_root_page,
        permission_type='change',
    )
    return group

Timeline

Basic multisite setup for 2–3 domains: 1–2 days. With custom brand settings, media management: 3–4 days.