MediaWiki Wiki Farms — Multiple Wikis, Shared Code, and Farm Extensions
In this tutorial, you will learn about MediaWiki Wiki Farms. We cover key concepts, practical examples, and best practices to help you master this topic.
Wiki farms in MediaWiki let you run multiple wikis from a single codebase installation — sharing core files, extensions, and skins while giving each wiki its own database, configuration, and content — the same architecture Wikipedia uses across hundreds of language editions and Wikimedia projects.
What You'll Learn
- Understanding wiki farm architecture
- Configuring multiple wikis from one codebase
- Setting up separate databases for each wiki
- Sharing extensions and skins across wikis
- Using farm management extensions
- Best practices for farm maintenance
Why It Matters
If you need more than one wiki, a farm saves time and resources. Instead of installing MediaWiki 10 times, you install it once and configure 10 virtual wikis. Each wiki gets its own content, users, and settings. Upgrades update all wikis at once. Extensions and skins are shared. Disk usage is minimized. This is how Wikimedia runs hundreds of wikis including Wikipedia in every language.
Real-World Use
A DodaTech organization runs three wikis: "docs" (public documentation), "internal" (employee knowledge base), and "dev" (development team wiki). All three share the same MediaWiki codebase and server. Each has its own database and configuration. The public wiki allows anonymous reading. The internal wiki requires login. The dev wiki integrates with the issue tracker. When an upgrade is released, all three wikis are updated with a single git pull and update.php run.
Learning Path
flowchart LR A["29: Cite & References"] --> B["30: Interwiki Links"] B --> C["31: Wiki Farms"] C:::current D["32: Content Translation"] E["33: Import & Export"] F["34: REST API"] C --> D --> E --> F classDef current fill#38bdf8,color#0f172a,stroke-width:2px
Wiki Farm Architecture
A wiki farm has one MediaWiki installation and multiple configurations.
/var/www/mediawiki/ ← Single codebase
├── includes/
├── extensions/
├── skins/
├── images/
│ ├── wiki1/ ← Separate upload directories
│ ├── wiki2/
│ └── wiki3/
├── config/ ← Per-wiki configuration
│ ├── wiki1.php
│ ├── wiki2.php
│ └── wiki3.php
└── LocalSettings.php ← Main settings (detects wiki)
Each wiki has:
- Own database (or database prefix)
- Own configuration file (included from LocalSettings.php)
- Own upload directory (
images/wiki1/,images/wiki2/) - Own cache directory
- Shared code (MediaWiki core, extensions, skins)
Step 1: Choose a Detection Method
LocalSettings.php must detect which wiki is being accessed. Three common methods:
Method 1: Server Name Detection
// LocalSettings.php
switch ( $_SERVER['SERVER_NAME'] ) {
case 'docs.dodatech.com':
require_once '/config/docs.php';
break;
case 'internal.dodatech.com':
require_once '/config/internal.php';
break;
case 'dev.dodatech.com':
require_once '/config/dev.php';
break;
default:
die( 'Unknown wiki' );
}
Method 2: Directory-Based Detection
https://example.com/wiki1/
https://example.com/wiki2/
// LocalSettings.php
$parts = explode( '/', $_SERVER['REQUEST_URI'] );
$wikiName = $parts[1] ?? 'default';
require_once "/config/$wikiName.php";
Method 3: Environment Variable
# Apache virtual host configuration
SetEnv MW_WIKI_NAME docs
$wikiName = getenv( 'MW_WIKI_NAME' ) ?: 'default';
require_once "/config/$wikiName.php";
Step 2: Configure Per-Wiki Settings
docs.php Configuration
<?php
// docs.dodatech.com — Public documentation wiki
// Database
$wgDBname = 'dodatech_docs';
$wgDBuser = 'wiki_user';
$wgDBpassword = 'secure_password';
// Site
$wgSitename = 'DodaTech Documentation';
$wgServer = 'https://docs.dodatech.com';
// Uploads
$wgUploadDirectory = "$IP/images/docs";
$wgUploadPath = "$wgScriptPath/images/docs";
// Permissions
$wgGroupPermissions['*']['read'] = true;
$wgGroupPermissions['*']['edit'] = false;
// Cache
$wgCacheDirectory = "$IP/cache/docs";
internal.php Configuration
<?php
// internal.dodatech.com — Internal knowledge base
$wgDBname = 'dodatech_internal';
$wgDBuser = 'wiki_user';
$wgDBpassword = 'secure_password';
$wgSitename = 'DodaTech Internal Wiki';
$wgServer = 'https://internal.dodatech.com';
$wgUploadDirectory = "$IP/images/internal";
$wgUploadPath = "$wgScriptPath/images/internal";
// Private wiki
$wgGroupPermissions['*']['read'] = false;
$wgGroupPermissions['user']['read'] = true;
// Enable VisualEditor only for internal
wfLoadExtension( 'VisualEditor' );
dev.php Configuration
<?php
// dev.dodatech.com — Developer wiki
$wgDBname = 'dodatech_dev';
$wgDBuser = 'wiki_user';
$wgDBpassword = 'secure_password';
$wgSitename = 'DodaTech Dev Wiki';
$wgServer = 'https://dev.dodatech.com';
$wgUploadDirectory = "$IP/images/dev";
$wgUploadPath = "$wgScriptPath/images/dev";
// Developer tools
wfLoadExtension( 'CodeEditor' );
wfLoadExtension( 'Scribunto' );
Step 3: Create Databases
Each wiki needs its own database:
CREATE DATABASE dodatech_docs CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE DATABASE dodatech_internal CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE DATABASE dodatech_dev CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
GRANT ALL PRIVILEGES ON dodatech_docs.* TO 'wiki_user'@'localhost';
GRANT ALL PRIVILEGES ON dodatech_internal.* TO 'wiki_user'@'localhost';
GRANT ALL PRIVILEGES ON dodatech_dev.* TO 'wiki_user'@'localhost';
Run Installation Script
For each wiki, run the maintenance script:
# Use the wiki's configuration
php maintenance/install.php \
--dbname=dodatech_docs \
--dbuser=wiki_user \
--dbpass=secure_password \
--server=https://docs.dodatech.com \
--scriptpath=/ \
"DodaTech Documentation" \
"admin"
# Repeat for internal and dev wikis
Step 4: Share Extensions and Skins
Extensions placed in the shared extensions/ directory are available to all wikis. Each wiki's config file decides which extensions to load.
Shared Extensions
/var/www/mediawiki/extensions/
├── VisualEditor/ ← Loaded on docs and internal
├── Scribunto/ ← Loaded on dev
├── Cite/ ← Loaded on all wikis
├── ConfirmEdit/ ← Loaded on all wikis
└── CodeEditor/ ← Loaded on dev only
Selective Loading
Each wiki's config file loads only the extensions it needs:
// docs.php
wfLoadExtension( 'Cite' );
wfLoadExtension( 'ConfirmEdit' );
wfLoadExtension( 'VisualEditor' );
// dev.php
wfLoadExtension( 'Cite' );
wfLoadExtension( 'Scribunto' );
wfLoadExtension( 'CodeEditor' );
Step 5: Manage Shared Resources
Shared User Database
Optionally, share a user database across wikis:
// In ALL wiki config files
$wgSharedDB = 'dodatech_users'; // Shared user database
$wgSharedTables = [ 'user', 'user_groups' ];
Changes:
- Users register on any wiki and can log in to all wikis
- User preferences are still per-wiki
- Permissions (groups) are also shared
Shared Cache
Use a shared cache backend for all wikis:
$wgMainCacheType = CACHE_MEMCACHED;
$wgMemCachedServers = [ '127.0.0.1:11211' ];
This reduces memory usage and improves performance across the farm.
Step 6: Farm Management Extensions
CentralAuth Extension
CentralAuth provides single sign-on across the wiki farm:
wfLoadExtension( 'CentralAuth' );
Features:
- One login for all wikis
- Global user groups
- Central user management
- Cross-wiki activity tracking
Global Preferences Extension
Allow users to set preferences that apply to all wikis:
wfLoadExtension( 'GlobalPreferences' );
Users can set a global skin, editor preference, or notification settings that apply everywhere.
ManageWiki Extension
ManageWiki provides a web interface for managing farm settings:
wfLoadExtension( 'ManageWiki' );
Features:
- Create new wikis from a web interface
- Manage extensions per wiki
- Change settings without editing config files
- Grant permissions per wiki
Step 7: Farm Maintenance
Upgrading a Farm
# 1. Update codebase
git pull
# 2. Run update.php for each wiki
php maintenance/update.php --conf config/docs.php
php maintenance/update.php --conf config/internal.php
php maintenance/update.php --conf config/dev.php
# 3. Clear all caches
php maintenance/rebuildall.php --conf config/docs.php
Backing Up a Farm
Back up each wiki's database individually:
for db in dodatech_docs dodatech_internal dodatech_dev; do
mysqldump --user=wiki_user --password=secure_password $db > backup/$db.sql
done
Adding a New Wiki
- Create the database
- Create a config file
- Add the server name to the switch statement
- Run
maintenance/install.php - Set up upload directories
What You Learned
- A wiki farm runs multiple wikis from one codebase
- Server name detection routes requests to the correct wiki
- Each wiki has its own database, config, and upload directory
- Extensions are shared but loaded selectively per wiki
- CentralAuth provides single sign-on across the farm
- ManageWiki provides a web interface for farm management
- Farm upgrades require running update.php for each wiki
In the next lesson, you'll learn about content translation.
Common Mistakes
| Mistake | Why It Happens | How to Fix |
|---|---|---|
| Wrong wiki shows for a URL | Server name detection misconfigured | Check the switch statement in LocalSettings.php. Verify SERVER_NAME matches the expected domain. Test with a debug output of $_SERVER['SERVER_NAME']. |
| Extension not visible on a wiki | Extension loaded in wrong config file | Move the wfLoadExtension line to the correct wiki's config file. Check that the extension directory exists in the shared extensions folder. |
| User cannot log in to multiple wikis | No shared user database | Configure $wgSharedDB to point to a common user database. Ensure all wikis use the same shared tables configuration. |
| Upload failed on one wiki | Upload directory permissions | Create the upload directory for each wiki and set proper permissions: mkdir -p images/wikiname && chmod 755 images/wikiname. |
| Farm performance degraded | No shared cache | Install and configure Memcached or Redis. Set $wgMainCacheType to CACHE_MEMCACHED. Shared cache dramatically improves farm performance. |
Practice Questions
- What are three methods for detecting which wiki to serve in a farm configuration?
- How do you share extensions across wikis while loading them selectively?
- What is the purpose of CentralAuth in a wiki farm?
- Challenge: Build a wiki farm with three wikis. Create directories and databases for "public," "internal," and "sandbox" wikis. Configure LocalSettings.php to detect the wiki by server name (use localhost with different ports or directories for testing). Create three config files with different site names, databases, and permission settings. Install an extension (e.g., Cite) in the shared directory and enable it only on the "public" and "internal" wikis. Configure a shared user database. Test that creating an account on one wiki lets you log in to all three. Run the upgrade Process on all three wikis.
FAQ
Mini Project
Goal: Build and deploy a three-wiki farm.
- Create the directory structure for a wiki farm with three wikis
- Create three databases:
farm_docs,farm_internal,farm_dev - Create three config files with unique settings
- Configure LocalSettings.php with server name detection (use subdirectories for testing)
- Set up shared upload directories for each wiki
- Share the Cite extension and enable it on all wikis
- Enable Scribunto only on the dev wiki
- Configure a shared user database across all wikis
- Create three test pages (one per wiki) confirming each is independent
- Run the upgrade process and verify all wikis still work
- Create a "Wiki Farm Overview" page documenting the architecture
What's Next
Multiple wikis are powerful, but translating content across them requires the right tools.
Continue to Lesson 32: Content Translation — learn how to use the Translate extension for page translation workflows.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro