Advanced MediaWiki Configuration for Power Users
Why “Advanced” Matters
Why “Advanced” Matters
Most MediaWiki installations live happily on the default $wgSitename, $wgScriptPath and a few shared extensions. Power users, however, soon discover that those defaults are a double‑edged sword: they get you up and running, but they also hide a treasure chest of knobs you can turn for speed, security and flexibility. Below is a dense, hands‑on walk‑through of the settings you’ll actually tweak once you’ve outgrown the “just works” stage.
1. Getting the Foundations Right
Before you massage $wgCacheDirectory or tango with $wgObjectCache, make sure the basic environment variables are rock‑solid.
- $IP – the absolute path to the MediaWiki root. Hard‑code it if you ever plan to move the codebase across servers.
- $wgScriptPath – the public URL segment (e.g.
/w). A typo here makes every link break. - $wgArticlePath – the “pretty URL” pattern, like
/wiki/$1. Remember: you need matching rewrite rules in.htaccessornginx.conf.
These three form the spine; any later tweak feels like moving your ribs without adjusting the spine – it hurts.
2. Database Deep‑Dive
Most newbies stop at $wgDBservers. For serious traffic, you’ll want a read/write split, connection pooling and even a fallback cluster.
// Example: master‑slave setup with LoadBalancer
$wgDBservers = [
[
'host' => 'db-master.example.org',
'dbname' => 'wiki',
'user' => 'wikiuser',
'password' => '••••••••',
'type' => 'mysql',
'load' => 0,
'flags' => DBO_DEFAULT,
],
[
'host' => 'db-replica1.example.org',
'dbname' => 'wiki',
'user' => 'wikiuser',
'password' => '••••••••',
'type' => 'mysql',
'load' => 100, // higher load means more reads here
'flags' => DBO_DEFAULT,
],
];
Two tips:
- Replication lag can cause stale reads; set
$wgReadOnlyduring massive imports. - If you’re on PostgreSQL, look at
$wgDBtype = "postgres";and enable$wgSearchType = "CirrusSearch";for better full‑text support.
3. Caching – The Real Speed‑Booster
MediaWiki ships with a simple file cache, but power users treat it like a lazy‑dog: feed it, then let it run. The hierarchy is:
- File cache (
$wgCacheDirectory) – great for static HTML fragments. - MessageCache (
$wgMessageCacheType) – switch to APCu or Redis for instant translation lookups. - Parser cache (
$wgParserCacheType) – set toCACHE_ACCELif you have an opcode cache. - Object cache (
$wgObjectCache) – the heavyweight champion; most sites use Memcached or Redis.
// Using Redis as the object cache
$wgObjectCache = [
'class' => 'RedisBagOStuff',
'servers' => [
[ '127.0.0.1', 6379 ],
],
'persist' => true,
];
Don’t forget $wgUseSquid when you have a reverse‑proxy CDN. It tells MediaWiki to send Cache‑Control: private only when necessary, letting the CDN cache everything else.
4. Uploads, MIME Types & Antivirus
If your wiki is a collaborative knowledge‑base for design assets, you’ll be handling hundreds of megabytes daily. Fine‑tune the upload pipeline:
- $wgFileExtensions – whitelist the exact types you need; every extra entry is a possible attack surface.
- $wgVerifyMimeType – always enabled; it checks the real file signature.
- $wgCheckFileExtensions – keep it true; the UI will politely refuse unknown formats.
- $wgAntivirus – set to
ClamAVorinternalfor on‑the‑fly scanning.
// Example: shared uploads across a farm
$wgEnableUploads = true;
$wgUploadPath = "$wgScriptPath/images";
$wgUploadDirectory = "$IP/images";
$wgHashedUploadDirectory = true; // spreads files into subfolders
When you turn on $wgHashedUploadDirectory, the filesystem stays tidy even after a few hundred thousand pictures. It’s a tiny tweak with a massive payoff.
5. ResourceLoader – Modern JS & CSS
Gone are the days of loading common.js on every request. $wgResourceModules lets you bundle assets per skin or per feature. Here’s a snippet that pulls in a custom script only for logged‑in users.
$wgResourceModules['ext.myExtension.user'] = [
'scripts' => [ 'modules/ext.myExtension.user.js' ],
'styles' => [ 'modules/ext.myExtension.user.css' ],
'targets' => [ 'desktop', 'mobile' ],
'dependencies' => [ 'mediawiki.util' ],
'position' => 'top',
'localBasePath' => __DIR__,
'remoteBasePath' => "$wgScriptPath/extensions/MyExtension",
'skipFunction' => function ( $resourceLoader, $skin ) {
return !$skin->getUser()->isLoggedIn();
},
];
Don’t forget to purge the ResourceLoader cache after changes: php maintenance/rebuildLocalisationCache.php --force or simply php maintenance/update.php. It feels like a chore, but it saves you from mysterious UI glitches that pop up months later.
6. Jobs Queue – Offloading Work
Whenever you edit a page, MediaWiki fires a slew of background jobs: index updates, link tables, thumbnail generation. Tuning the queue prevents those jobs from choking the webworkers.
- $wgJobRunRate – default
1(run a job on every page view). In high‑traffic environments, bring it down to0.1and run a dedicatedrunJobs.phpdaemon. - $wgJobTypeConf – assign heavy jobs (e.g. image scaling) to a separate queue handled by a beefier server.
// Separate queue for thumbnail generation
$wgJobTypeConf['imageResize'] = [
'class' => 'JobQueueRedis',
'servers' => [ [ '127.0.0.1', 6379 ] ],
'dbId' => 1,
];
If you’re using Redis, you can even monitor queue lengths via redis-cli LLEN jobqueue:default. A sudden spike usually means a rogue extension is queuing too many jobs.
7. Security Hardening
Power users treat security like a checklist, not an afterthought.
- $wgSecretKey – generate a unique, 64‑character random string. Never commit it to a public repo.
- $wgSessionsInObjectCache – store sessions in Redis; this prevents session fixation attacks.
- $wgEnableEmail – keep it true only if you need password resets; otherwise set it false to eliminate email‑spoof vectors.
- $wgPasswordPolicy – enforce a minimum length, mixed case and disallow common passwords.
// Example: tight password policy
$wgPasswordPolicy = [
'policy' => [
'MinimalLength' => [ 'min' => 12 ],
'ContainsUppercaseLetter' => true,
'ContainsDigit' => true,
'RejectCommonPasswords' => true,
],
'forceReset' => false,
];
Also, enable $wgContentHandlerUseDB for content‑type safety, and consider turning on $wgEnableWriteAPI only for trusted bots.
8. Internationalisation & Localization
If your wiki speaks more than one language, you’ll want to play with $wgForceUIMsgAsContentMsg and $wgLanguageCode. A neat trick is to force the UI language based on user preference while still serving content in its original language.
// Keep user interface in user language
$wgForceUIMsgAsContentMsg = false;
$wgExposeLangLinks = true; // show interlanguage links
Remember: each language file adds a few hundred kilobytes to memory, so monitor memory_limit after you enable dozens of languages.
9. Monitoring & Debugging
Even the best‑tuned wiki needs eyes on it. MediaWiki ships with built‑in profiling; just turn it on in LocalSettings.php when you suspect a slowdown.
$wgDebugLogFile = "/var/log/mediawiki/debug.log";
$wgDebugToolbar = true; // shows a toolbar with timing data
$wgShowExceptionDetails = true; // useful in dev, never enable in prod
For production, pipe the log to a log‑collector (e.g. Graylog or ELK). If you see “ParserCache: miss” spikes, maybe the $wgParserCacheType fell back to CACHE_NONE after a recent extension update.
10. The “If‑This‑Then‑That” Section
At this point you might be asking: “What if I need a custom setting that isn’t listed?” The answer—use $wgHooks and $wgExtensionFunctions. Hooking early lets you inject configuration before most core code runs.
// Example: force all uploads to be private until reviewed
$wgHooks['UploadComplete'][] = function ( $file ) {
$file->setPublic( false );
// later a reviewer can call $file->setPublic( true );
return true;
};
This little snippet demonstrates the power of the hook system: you can alter core behavior without touching the core itself. Just be mindful of ordering; some extensions register their own hooks that might fire before yours.
Wrapping Up
Advanced MediaWiki configuration isn’t about flipping a switch; it’s about understanding the layered architecture and tuning each layer to match your traffic patterns, security posture, and feature set. The settings above cover the most common pain points: database scaling, caching layers, upload handling, ResourceLoader, background jobs, security, i18n, and observability.
When you return to $wgSitename after a weekend of tweaking, you’ll notice the wiki feels faster, safer, and more responsive—proof that those “advanced” knobs aren’t just for show.