Jump to content

MediaWiki Setup Guide Portainer-Docker-251215-00: Difference between revisions

From Game in the Brain Wiki
No edit summary
No edit summary
 
Line 1: Line 1:
= MediaWiki Setup Guide (Portainer & Docker) =
= MediaWiki Setup Guide (Portainer & Docker) =


This guide documents how to deploy, configure, and secure a '''MediaWiki''' instance using '''Portainer''' and '''Docker Compose'''. Designed as a general tutorial for any user, it walks through the process of setting up a wiki from scratch. It covers initial deployment, resolving common extension folder issues, and applying production configurations (using <code>wiki.gi7b.org</code> as the example domain).
This guide documents how to deploy, configure, and secure a '''MediaWiki''' instance using '''Portainer''' and '''Docker Compose'''. Designed as a general tutorial, it walks through the process of setting up a wiki from scratch, resolving common extension folder issues, and applying production configurations.


'''Reference:''' Official MediaWiki Docker Image [https://hub.docker.com//mediawiki https://hub.docker.com//mediawiki]
'''Reference:''' Official MediaWiki Docker Image [https://hub.docker.com//mediawiki https://hub.docker.com//mediawiki]
Line 9: Line 9:
Before starting, ensure you have:
Before starting, ensure you have:


'''Docker & Docker Compose'''
'''Docker & Docker Compose''': [https://docs.docker.com/engine/install/ Installation Guide]


#* Installation (Linux/Windows/Mac): [https://docs.docker.com/engine/install/ https://docs.docker.com/engine/install/]
'''Portainer CE''': [https://docs.portainer.io/start/install-ce/server/docker/linux Docker Standalone Install Guide]
#* Docker Compose Standalone (if needed separately): [https://docs.docker.com/compose/install/ https://docs.docker.com/compose/install/]


'''Portainer CE (Community Edition)'''
'''Domain & Cloudflare Setup''': [https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/get-started/create-remote-tunnel/ Cloudflare Tunnel (Cloudflared) Setup Guide]


#* Docker Standalone Install Guide: [https://docs.portainer.io/start/install-ce/server/docker/linux https://docs.portainer.io/start/install-ce/server/docker/linux]
'''NGINX Reverse Proxy''': [https://nginxproxymanager.com/guide/#quick-setup Nginx Proxy Manager Setup]
 
'''Domain & Cloudflare Setup'''
 
#* How to Register a Domain with Cloudflare: [https://developers.cloudflare.com/registrar/get-started/register-domain/ https://developers.cloudflare.com/registrar/get-started/register-domain/]
#* Cloudflare Tunnel (Cloudflared) Setup Guide: [https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/get-started/create-remote-tunnel/ https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/get-started/create-remote-tunnel/]
 
'''NGINX Reverse Proxy'''
 
#* Nginx Proxy Manager (Docker Setup): [https://nginxproxymanager.com/guide/#quick-setup https://nginxproxymanager.com/guide/#quick-setup] (This is the standard GUI-based Nginx used in Docker stacks)
#* Nginx Official Docker Image (for raw configuration): [https://hub.docker.com//nginx https://hub.docker.com//nginx]


== 2. Host Folder Setup ==
== 2. Host Folder Setup ==
Line 43: Line 32:
== 3. Deployment (Portainer / Docker Compose) ==
== 3. Deployment (Portainer / Docker Compose) ==


Use the following YAML configuration.
=== In Portainer ===
 
=== In Portainer: ===


Go to '''Stacks''' → '''Add stack'''.
Go to '''Stacks''' → '''Add stack'''.


Name it <code>mediawiki</code>.
Name it mediawiki.


Paste the configuration below into the Web editor.
Paste the configuration below into the Web editor.
Line 56: Line 43:


=== docker-compose.yml ===
=== docker-compose.yml ===
<syntaxhighlight lang="yaml">
<syntaxhighlight lang="yaml">
services:
services:
Line 93: Line 79:
== 4. First-Time Setup Wizard ==
== 4. First-Time Setup Wizard ==


Open <code>http://localhost:8191</code> (or your server IP:8191).
Open http://[YOUR_SERVER_IP]:8595 in your browser.


Follow the prompts. When asked for '''Database Settings''', use:
Follow the prompts. When asked for '''Database Settings''', use:


#* '''Host:''' <code>database</code>
#* '''Host:''' database
#* '''Name:''' <code>mediawiki</code>
#* '''Name:''' mediawiki
#* '''User:''' <code>mediawiki</code>
#* '''User:''' mediawiki
#* '''Password:''' <code>mediawiki</code>
#* '''Password:''' mediawiki


Complete the wizard and '''Download LocalSettings.php''' to your computer.
Complete the wizard and '''Download LocalSettings.php''' to your computer.
Line 106: Line 92:
== 5. Fixing Extensions (The "Magic Command") ==
== 5. Fixing Extensions (The "Magic Command") ==


'''Crucial Step:''' Because we mounted a volume to <code>/extensions</code>, the container's default extensions (VisualEditor, WikiEditor, '''SyntaxHighlight_GeSHi''', etc.) are hidden. We must copy them from the image to the host.
'''Crucial Step:''' Because we mounted a volume to /extensions, the container's default extensions (VisualEditor, SyntaxHighlight_GeSHi, etc.) are hidden. We must copy them from the image to the host.


=== Step A: Extract Extensions ===
=== Step A: Extract Extensions ===
'''Run this on your Host Terminal:'''
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
docker run --rm --entrypoint tar mediawiki -c -C /var/www/html/extensions . | tar -x -C /opt/stacks/mediawiki/extensions
docker run --rm --entrypoint tar mediawiki -c -C /var/www/html/extensions . | tar -x -C /opt/stacks/mediawiki/extensions
Line 117: Line 100:


=== Step B: Fix Permissions for Code Highlighting ===
=== Step B: Fix Permissions for Code Highlighting ===
 
The SyntaxHighlight_GeSHi extension requires a specific Python file (pygmentize) to be executable.
The <code>SyntaxHighlight_GeSHi</code> extension (which creates code blocks) requires a specific Python file (<code>pygmentize</code>) to be executable. This permission is often lost during the copy.
 
'''Run this command to fix it:'''
 
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
chmod a+x /opt/stacks/mediawiki/extensions/SyntaxHighlight_GeSHi/pygments/pygmentize
chmod a+x /opt/stacks/mediawiki/extensions/SyntaxHighlight_GeSHi/pygments/pygmentize
</syntaxhighlight>
</syntaxhighlight>
If you skip this, code blocks will not render or will show errors.


=== Step C: Add External Extensions ===
=== Step C: Add External Extensions ===
'''Download Mermaid (External Extension):'''
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
cd /opt/stacks/mediawiki/extensions
cd /opt/stacks/mediawiki/extensions
git clone https://github.com/SemanticMediaWiki/Mermaid.git Mermaid
git clone https://github.com/SemanticMediaWiki/Mermaid.git Mermaid
</syntaxhighlight>
</syntaxhighlight>
Verify the folder content. You should see a mix of default extensions and Mermaid:
<code>ls -F /opt/stacks/mediawiki/extensions/</code>
Output should include: <code>SyntaxHighlight_GeSHi/</code>, <code>VisualEditor/</code>, <code>Mermaid/</code>, <code>WikiEditor/</code>, etc.


== 6. Configuring LocalSettings.php ==
== 6. Configuring LocalSettings.php ==


Move the downloaded <code>LocalSettings.php</code> to <code>/opt/stacks/mediawiki/LocalSettings.php</code>.
Move the downloaded LocalSettings.php to /opt/stacks/mediawiki/LocalSettings.php.


<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
in linux terminal
sudo nano /opt/stacks/mediawiki/LocalSettings.php
sudo nano /opt/stacks/mediawiki/LocalSettings.php
</syntaxhighlight>
</syntaxhighlight>
Edit the file (<code>sudo nano /opt/stacks/mediawiki/LocalSettings.php</code>) and make the following changes:


=== A. Set the Custom Domain ===
=== A. Set the Custom Domain ===
 
Find the $wgServer line and change it to your actual domain:
Find the <code>$wgServer</code> line (around line 30) and change it to your actual domain:
 
<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
The protocol and server name to use in fully-qualified URLs
$wgServer = "https://wiki.gi7b.org";
$wgServer = "https://wiki.gi7b.org";
</syntaxhighlight>
</syntaxhighlight>


=== B. Add Permissions & Extensions ===
=== B. Add Permissions & Extensions ===
 
Paste this block at the '''very bottom''' of the file:
Paste this block at the '''very bottom''' of the file to enable security and extensions.
 
<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
 
/* -----------------------------------------------------------------------
-----------------------------------------------------------------------
 
CUSTOM PERMISSIONS & EXTENSIONS
CUSTOM PERMISSIONS & EXTENSIONS
 
----------------------------------------------------------------------- */
-----------------------------------------------------------------------


1. SECURITY: Prevent anonymous editing and account creation
1. SECURITY: Prevent anonymous editing and account creation
Line 183: Line 137:
$wgGroupPermissions['']['createaccount'] = false;
$wgGroupPermissions['']['createaccount'] = false;


2. BUNDLED EXTENSIONS (Included in Docker image)
2. BUNDLED EXTENSIONS


wfLoadExtension( 'WikiEditor' );
wfLoadExtension( 'WikiEditor' );
Line 197: Line 151:
wfLoadExtension( 'Interwiki' );
wfLoadExtension( 'Interwiki' );


3. EXTERNAL EXTENSIONS (Must be manually downloaded to /extensions folder)
3. EXTERNAL EXTENSIONS


wfLoadExtension( 'Mermaid' );
wfLoadExtension( 'Mermaid' );


4. VISUALEDITOR CONFIGURATION
4. VISUALEDITOR CONFIGURATION
Enable by default for everyone


$wgDefaultUserOptions['visualeditor-enable'] = 1;
$wgDefaultUserOptions['visualeditor-enable'] = 1;
Allow VE to work in Docker containers (Fixes "Error contacting Parsoid")
$wgVisualEditorParsoidForwardCookies = true;
$wgVisualEditorParsoidForwardCookies = true;


Line 214: Line 163:


$wgScribuntoDefaultEngine = 'luastandalone';
$wgScribuntoDefaultEngine = 'luastandalone';
</syntaxhighlight>
=== C. Adding additional Extensions (WIP - waiting till v1.46 is released this does not work) ===
Go to the HOST PC running the docker mediawiki. You can ssh into it. As an example, let's add [https://www.mediawiki.org/wiki/Extension:Collection Collections] and [https://www.mediawiki.org/wiki/Extension:PdfBook PdfBook].
<syntaxhighlight lang="bash">
cd /opt/stacks/mediawiki/extensions
git clone https://gerrit.wikimedia.org/r/mediawiki/extensions/Collection
git clone https://gerrit.wikimedia.org/r/mediawiki/extensions/PdfBook
</syntaxhighlight>
Then edit <code>LocalSettings.php</code>:
<syntaxhighlight lang="php">
3. EXTERNAL EXTENSIONS (Must be manually downloaded to /extensions folder)
wfLoadExtension( 'Mermaid' );
wfLoadExtension( 'Collection' ); // wait till version 1.46
wfLoadExtension( 'PdfBook' );
</syntaxhighlight>
</syntaxhighlight>


== 7. Apply Changes ==
== 7. Apply Changes ==


'''Mount the settings:''' In Portainer, go to the Stack Editor and '''uncomment''' the <code>LocalSettings.php</code> line.
'''Mount the settings''': In Portainer, go to the Stack Editor and '''uncomment''' the LocalSettings.php line.


'''Update the Stack:''' Click "Update the stack".
'''Update the Stack''': Click "Update the stack".


'''Run Database Update:''' Run this command to initialize tables for the new extensions:
'''Run Database Update''':


<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
docker exec -it mediawiki php maintenance/update.php --quick
docker exec -it mediawiki php maintenance/update.php --quick
</syntaxhighlight>
</syntaxhighlight>
Your wiki is now live at '''https://wiki.gi7b.org''' with VisualEditor, Mermaid, and Code Highlighting enabled!


== 8. Email Configuration and Admin Setup ==
== 8. Email Configuration and Admin Setup ==


=== 1. Email goal (what we were trying to achieve) ===
=== 1. SMTP Logic ===
 
MediaWiki must be able to send emails for account confirmation and resets. Authentication must work with '''Gmail / Google Workspace'''.
MediaWiki must be able to '''send email reliably''' (account confirmation, password reset, notifications).
 
Emails should appear as coming from <code>info@gi7b.org</code>.
 
Authentication must work with '''Gmail / Google Workspace'''.


No local SMTP server, no Docker mail container.
=== 2. Google App Password ===


'''Success criterion:''' MediaWiki explicitly says '''“email sent”''' — not just “no error”.
Go to Google Account → Security → App passwords.


=== 2. App Password (Google side) ===
'''Critical Detail:''' MediaWiki must receive the password '''without spaces'''.


'''Where it lives:''' Google Account settings (Security → App passwords).
Displayed: xxxx xxxx xxxx xxxx → Input: xxxxxxxxxxxxxxxx
 
'''Preconditions:''' 2-Step Verification '''must be enabled'''.
 
'''Critical Detail (The "Space" Trap):'''
: Google displays the password like this: <code>xxxx xxxx xxxx xxxx</code>
: But MediaWiki / PHP '''must receive it without spaces''': <code>xxxxxxxxxxxxxxxx</code>
 
:If you keep the spaces, Google returns <code>SMTP 535 5.7.8 BadCredentials</code>.
 
=== 3. Real email vs Alias (Authentication Reality) ===
 
'''Core Rule:''' SMTP login must use a '''real mailbox''', not an alias.
 
{| class="wikitable"
! Address type !! Can authenticate?
|-
| Real Gmail / Workspace mailbox || ✅ Yes
|-
| Alias (Send mail as) || ❌ No
|-
| Forward-only address || ❌ No
|}
 
'''Login / username''' → Real mailbox (e.g., <code>admin@gi7b.org</code>)
 
'''Sender address''' → Can be the alias (e.g., <code>info@gi7b.org</code>)
 
=== 4. "Send as" using Cloudflare Email Routing ===
 
If <code>info@gi7b.org</code> is an alias using '''Cloudflare Email Routing''':
 
Cloudflare routes incoming mail for <code>info</code> to your real mailbox.
 
Gmail authenticates as the '''real mailbox'''.
 
MediaWiki sends "from" the alias.
 
This combination is valid and correct.
 
=== 5. Final MediaWiki SMTP Configuration ===
 
Add this to <code>LocalSettings.php</code>:


=== 3. SMTP Configuration ===
Add this to LocalSettings.php:
<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
$wgEnableEmail = true;
$wgEnableEmail = true;
Line 322: Line 201:
'port'    => 465,
'port'    => 465,
'auth'    => true,
'auth'    => true,
'username' => 'admin@gi7b.org',   // REAL mailbox (replace with yours)
'username' => 'admin@gi7b.org',       // REAL mailbox
'password' => 'APP_PASSWORD_NO_SPACES', // Your Google App Password
'password' => 'APP_PASSWORD_NO_SPACES', // Your Google App Password
];
];


$wgPasswordSender = 'info@gi7b.org'; // ALIAS is fine here
$wgPasswordSender = 'info@gi7b.org';       // ALIAS is fine here
</syntaxhighlight>
</syntaxhighlight>


=== 6. Testing and Defining "Success" ===
=== 4. Promote Account to Admin ===
 
'''Failure:''' MediaWiki shows "authentication failure".
 
'''Success:''' MediaWiki returns '''"email sent"'''.
 
=== 7. Final Step: Making your Account Admin ===
 
Once email is stable, use the MediaWiki maintenance runner to promote your account.
 
'''Command:'''
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
docker exec -it mediawiki php maintenance/createAndPromote.php --sysop --bureaucrat YourUsername
docker exec -it mediawiki php maintenance/createAndPromote.php --sysop --bureaucrat YourUsername
</syntaxhighlight>
</syntaxhighlight>


(Note: If the user already exists, you may need to use <code>maintenance/run.php userOptions</code> or edit the database directly if <code>createAndPromote</code> complains, but often <code>createAndPromote</code> handles existing users gracefully or you can use the UserRights page if you have another admin).
== 9. Brute Force Protection ==
 
'''Alternative (UI Method):'''
If you are the first user (Sysop) created during installation, go to <code>Special:UserRights</code> to manage permissions.
 
=== 8. Final Mental Model ===
 
'''Gmail''' = SMTP server.
 
'''MediaWiki''' = SMTP client.
 
'''App Password''' = Machine credential (no spaces!).
 
'''Real Mailbox''' = Authenticates (Security).
 
'''Alias''' = Presentation (What users see).
 
== 9. Protect your account from brute force ==
 
Add to <code>LocalSettings.php</code>:


Add throttling to LocalSettings.php:
<syntaxhighlight lang="php">
<syntaxhighlight lang="php">


Line 374: Line 225:


== 10. How to use Code Blocks ==
== 10. How to use Code Blocks ==
Once <code>SyntaxHighlight_GeSHi</code> is active (see Section 5):
'''VisualEditor:''' Click '''Insert''' > '''More''' > '''Code Block'''.


'''Source Editor:''' Use the tag:
'''Source Editor:''' Use the tag:


<syntaxhighlight lang="html">
<pre>
<syntaxhighlight lang="python" copy>
<syntaxhighlight lang="python" copy>
print("This code has a copy button!")
print("This code has a copy button!")
</syntaxhighlight>
</syntaxhighlight>
</syntaxhighlight>
</pre>


:*Note: The <code>copy</code> attribute adds a copy-to-clipboard button (available in newer MediaWiki versions).
== 11. Quick Guide: Adding Extensions ==


== 11. List of Extensions ==
'''Download''':
 
[https://www.youtube.com/watch?v=4xYbqbabTwI Youtube: Introduction to MediaWiki: Wikipedia's extensions (Part 2)]
 
[https://en.wikipedia.org/wiki/Special:Version The installed Extensions of Wikipedia]
 
== 12. Quick Guide: Adding or Disabling Extensions (Refresher) ==
 
If you have already set up the wiki and just need to add or remove a feature, follow this checklist.
 
'''1. Go to the Extensions Folder'''
Run this on your host machine:


<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
cd /opt/stacks/mediawiki/extensions
cd /opt/stacks/mediawiki/extensions
git clone https://www.google.com/search?q=https://gerrit.wikimedia.org/r/mediawiki/extensions/ExtensionName
</syntaxhighlight>
</syntaxhighlight>


'''2. Download the Extension'''
'''Enable''': Add wfLoadExtension( &#39;ExtensionName&#39; ); to LocalSettings.php.
Find the extension on [https://www.mediawiki.org/wiki/Special:ExtensionDistributor MediaWiki.org]. Use <code>git</code> to download it (replace <code>ExtensionName</code> with the actual name).
 
<syntaxhighlight lang="bash">


Example: Downloading "Math" extension
'''Update''':
 
git clone https://www.google.com/search?q=https://gerrit.wikimedia.org/r/mediawiki/extensions/Math.git
</syntaxhighlight>
 
''Tip: Ensure the folder name matches exactly what <code>wfLoadExtension</code> expects.''
 
'''3. Edit Configuration'''
Open your settings file:
 
<syntaxhighlight lang="bash">
sudo nano /opt/stacks/mediawiki/LocalSettings.php
</syntaxhighlight>
 
'''4. Enable or Disable'''
Scroll to the bottom.
 
'''To Enable:''' Add <code>wfLoadExtension( 'ExtensionName' );</code>
 
'''To Disable:''' Add a <code>#</code> at the start of the line: <code># wfLoadExtension( 'ExtensionName' );</code>
 
'''5. Apply Changes'''
Save the file (<code>Ctrl+O</code>, <code>Enter</code>, <code>Ctrl+X</code>). Then run the update script inside the container:


<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
docker exec -it mediawiki php maintenance/update.php --quick
docker exec -it mediawiki php maintenance/update.php --quick
</syntaxhighlight>
</syntaxhighlight>
Note: This step is required whenever you add an extension that modifies the database.

Latest revision as of 09:43, 26 January 2026

MediaWiki Setup Guide (Portainer & Docker)

This guide documents how to deploy, configure, and secure a MediaWiki instance using Portainer and Docker Compose. Designed as a general tutorial, it walks through the process of setting up a wiki from scratch, resolving common extension folder issues, and applying production configurations.

Reference: Official MediaWiki Docker Image https://hub.docker.com//mediawiki

1. Prerequisites

Before starting, ensure you have:

Docker & Docker Compose: Installation Guide

Portainer CE: Docker Standalone Install Guide

Domain & Cloudflare Setup: Cloudflare Tunnel (Cloudflared) Setup Guide

NGINX Reverse Proxy: Nginx Proxy Manager Setup

2. Host Folder Setup

Create a dedicated folder for your stack on the Docker host. This path is critical as it will store your configuration and extensions.

Run on host terminal

sudo mkdir -p /opt/stacks/mediawiki
sudo mkdir -p /opt/stacks/mediawiki/extensions
cd /opt/stacks/mediawiki

3. Deployment (Portainer / Docker Compose)

In Portainer

Go to StacksAdd stack.

Name it mediawiki.

Paste the configuration below into the Web editor.

Click Deploy the stack.

docker-compose.yml

services:
mediawiki:
image: mediawiki
container_name: mediawiki
restart: always
ports:
- 8595:80
depends_on:
- database
volumes:
- 230912_images:/var/www/html/images
# EXTENSIONS: Mounts host folder to container (Requires "Magic Command" step below)
- /opt/stacks/mediawiki/extensions:/var/www/html/extensions
# CONFIG: Uncomment the line below AFTER generating LocalSettings.php
# - /opt/stacks/mediawiki/LocalSettings.php:/var/www/html/LocalSettings.php:ro

database:
image: mariadb
container_name: mediawiki-db
restart: always
environment:
MYSQL_DATABASE: mediawiki
MYSQL_USER: mediawiki
MYSQL_PASSWORD: mediawiki
MYSQL_ROOT_PASSWORD: mediawiki
volumes:
- 230912_db:/var/lib/mysql

volumes:
230912_images:
230912_db:

4. First-Time Setup Wizard

Open http://[YOUR_SERVER_IP]:8595 in your browser.

Follow the prompts. When asked for Database Settings, use:

    • Host: database
    • Name: mediawiki
    • User: mediawiki
    • Password: mediawiki

Complete the wizard and Download LocalSettings.php to your computer.

5. Fixing Extensions (The "Magic Command")

Crucial Step: Because we mounted a volume to /extensions, the container's default extensions (VisualEditor, SyntaxHighlight_GeSHi, etc.) are hidden. We must copy them from the image to the host.

Step A: Extract Extensions

docker run --rm --entrypoint tar mediawiki -c -C /var/www/html/extensions . | tar -x -C /opt/stacks/mediawiki/extensions

Step B: Fix Permissions for Code Highlighting

The SyntaxHighlight_GeSHi extension requires a specific Python file (pygmentize) to be executable.

chmod a+x /opt/stacks/mediawiki/extensions/SyntaxHighlight_GeSHi/pygments/pygmentize

Step C: Add External Extensions

cd /opt/stacks/mediawiki/extensions
git clone https://github.com/SemanticMediaWiki/Mermaid.git Mermaid

6. Configuring LocalSettings.php

Move the downloaded LocalSettings.php to /opt/stacks/mediawiki/LocalSettings.php.

sudo nano /opt/stacks/mediawiki/LocalSettings.php

A. Set the Custom Domain

Find the $wgServer line and change it to your actual domain:

$wgServer = "https://wiki.gi7b.org";

B. Add Permissions & Extensions

Paste this block at the very bottom of the file:

/* -----------------------------------------------------------------------
CUSTOM PERMISSIONS & EXTENSIONS
----------------------------------------------------------------------- */

1. SECURITY: Prevent anonymous editing and account creation

$wgGroupPermissions['']['edit'] = false;
$wgGroupPermissions['']['createaccount'] = false;

2. BUNDLED EXTENSIONS

wfLoadExtension( 'WikiEditor' );
wfLoadExtension( 'VisualEditor' );
wfLoadExtension( 'CodeEditor' );
wfLoadExtension( 'SyntaxHighlight_GeSHi' ); # REQUIRED for Code Blocks
wfLoadExtension( 'Cite' );
wfLoadExtension( 'InputBox' );
wfLoadExtension( 'Scribunto' );
wfLoadExtension( 'AbuseFilter' );
wfLoadExtension( 'Gadgets' );
wfLoadExtension( 'ParserFunctions' );
wfLoadExtension( 'Interwiki' );

3. EXTERNAL EXTENSIONS

wfLoadExtension( 'Mermaid' );

4. VISUALEDITOR CONFIGURATION

$wgDefaultUserOptions['visualeditor-enable'] = 1;
$wgVisualEditorParsoidForwardCookies = true;

5. LUA CONFIGURATION (Required for Scribunto)

$wgScribuntoDefaultEngine = 'luastandalone';

7. Apply Changes

Mount the settings: In Portainer, go to the Stack Editor and uncomment the LocalSettings.php line.

Update the Stack: Click "Update the stack".

Run Database Update:

docker exec -it mediawiki php maintenance/update.php --quick

8. Email Configuration and Admin Setup

1. SMTP Logic

MediaWiki must be able to send emails for account confirmation and resets. Authentication must work with Gmail / Google Workspace.

2. Google App Password

Go to Google Account → Security → App passwords.

Critical Detail: MediaWiki must receive the password without spaces.

Displayed: xxxx xxxx xxxx xxxx → Input: xxxxxxxxxxxxxxxx

3. SMTP Configuration

Add this to LocalSettings.php:

$wgEnableEmail = true;
$wgEnableUserEmail = true;

$wgSMTP = [
'host'     => 'ssl://smtp.gmail.com',
'IDHost'   => 'wiki.gi7b.org',
'port'     => 465,
'auth'     => true,
'username' => 'admin@gi7b.org',        // REAL mailbox
'password' => 'APP_PASSWORD_NO_SPACES', // Your Google App Password
];

$wgPasswordSender = 'info@gi7b.org';       // ALIAS is fine here

4. Promote Account to Admin

docker exec -it mediawiki php maintenance/createAndPromote.php --sysop --bureaucrat YourUsername

9. Brute Force Protection

Add throttling to LocalSettings.php:

Login attempt throttling

$wgRateLimits['user']['login'] = [ 5, 60 ];   // 5 attempts per minute
$wgRateLimits['ip']['login']   = [ 20, 300 ]; // 20 attempts per 5 minutes

10. How to use Code Blocks

Source Editor: Use the tag:

<syntaxhighlight lang="python" copy>
print("This code has a copy button!")
</syntaxhighlight>

11. Quick Guide: Adding Extensions

Download:

cd /opt/stacks/mediawiki/extensions
git clone https://www.google.com/search?q=https://gerrit.wikimedia.org/r/mediawiki/extensions/ExtensionName

Enable: Add wfLoadExtension( 'ExtensionName' ); to LocalSettings.php.

Update:

docker exec -it mediawiki php maintenance/update.php --quick