MediaWiki Setup Guide Portainer-Docker-251215-00: Difference between revisions
Justinaquino (talk | contribs) |
Justinaquino (talk | contribs) No edit summary |
||
| Line 1: | Line 1: | ||
= 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 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). | ||
'''Reference:''' Official MediaWiki Docker Image https://hub.docker.com/ | '''Reference:''' Official MediaWiki Docker Image [https://hub.docker.com//mediawiki https://hub.docker.com//mediawiki] | ||
== 1. Prerequisites == | == 1. Prerequisites == | ||
Before starting, ensure you have: | Before starting, ensure you have: | ||
'''Docker & Docker Compose''' | |||
#* Installation (Linux/Windows/Mac): [https://docs.docker.com/engine/install/ https://docs.docker.com/engine/install/] | |||
#* Docker Compose Standalone (if needed separately): [https://docs.docker.com/compose/install/ https://docs.docker.com/compose/install/] | |||
'''Portainer CE (Community Edition)''' | |||
#* Docker Standalone Install Guide: [https://docs.portainer.io/start/install-ce/server/docker/linux https://docs.portainer.io/start/install-ce/server/docker/linux] | |||
'''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 == | |||
Create a dedicated folder for your stack on the '''Docker host'''. This path is critical as it will store your configuration and extensions. | |||
<syntaxhighlight lang="bash"> | |||
Run on host terminal | |||
sudo mkdir -p /opt/stacks/mediawiki | |||
sudo mkdir -p /opt/stacks/mediawiki/extensions | |||
cd /opt/stacks/mediawiki | |||
</syntaxhighlight> | |||
== 3. Deployment (Portainer / Docker Compose) == | == 3. Deployment (Portainer / Docker Compose) == | ||
Use the following YAML configuration. | Use the following YAML configuration. | ||
=== In Portainer: === | === In Portainer: === | ||
Go to '''Stacks''' → '''Add stack'''. | |||
Name it <code>mediawiki</code>. | |||
Paste the configuration below into the Web editor. | |||
Click '''Deploy the stack'''. | |||
=== docker-compose.yml === | === docker-compose.yml === | ||
<syntaxhighlight lang="yaml"> | |||
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: | |||
</syntaxhighlight> | |||
== 4. First-Time Setup Wizard == | == 4. First-Time Setup Wizard == | ||
Open <code>http://localhost:8191</code> (or your server IP:8191). | |||
Follow the prompts. When asked for '''Database Settings''', use: | |||
* '''Host:''' database | #* '''Host:''' <code>database</code> | ||
* '''Name:''' mediawiki | #* '''Name:''' <code>mediawiki</code> | ||
* '''User:''' mediawiki | #* '''User:''' <code>mediawiki</code> | ||
* '''Password:''' mediawiki | #* '''Password:''' <code>mediawiki</code> | ||
Complete the wizard and '''Download LocalSettings.php''' to your computer. | |||
== 5. Fixing Extensions (The "Magic Command") == | == 5. Fixing Extensions (The "Magic Command") == | ||
'''Crucial Step:''' Because we mounted a volume to /extensions, the container's default extensions (VisualEditor, WikiEditor, etc.) are hidden. We must copy them from the image to the host. | |||
'''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. | |||
=== Step A: Extract Extensions === | |||
'''Run this on your Host Terminal:''' | '''Run this on your Host Terminal:''' | ||
<syntaxhighlight lang="bash"> | |||
docker run --rm --entrypoint tar mediawiki -c -C /var/www/html/extensions . | tar -x -C /opt/stacks/mediawiki/extensions | |||
</syntaxhighlight> | |||
=== Step B: Fix Permissions for Code Highlighting === | |||
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"> | |||
chmod a+x /opt/stacks/mediawiki/extensions/SyntaxHighlight_GeSHi/pygments/pygmentize | |||
</syntaxhighlight> | |||
If you skip this, code blocks will not render or will show errors. | |||
=== Step C: Add External Extensions === | |||
'''Download Mermaid (External Extension):''' | '''Download Mermaid (External Extension):''' | ||
ls -F /opt/stacks/mediawiki/extensions/ | <syntaxhighlight lang="bash"> | ||
cd /opt/stacks/mediawiki/extensions | |||
git clone https://github.com/SemanticMediaWiki/Mermaid.git Mermaid | |||
</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 LocalSettings.php to /opt/stacks/mediawiki/LocalSettings.php. | |||
Move the downloaded <code>LocalSettings.php</code> to <code>/opt/stacks/mediawiki/LocalSettings.php</code>. | |||
Edit the file (sudo nano /opt/stacks/mediawiki/LocalSettings.php) and make the following changes: | <syntaxhighlight lang="bash"> | ||
in linux terminal | |||
sudo nano /opt/stacks/mediawiki/LocalSettings.php | |||
</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 (around line 30) 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"> | |||
The protocol and server name to use in fully-qualified URLs | |||
$wgServer = "https://wiki.gi7b.org"; | |||
</syntaxhighlight> | |||
=== B. Add Permissions & Extensions === | === B. Add Permissions & Extensions === | ||
Paste this block at the '''very bottom''' of the file to enable security and extensions. | Paste this block at the '''very bottom''' of the file to enable security and extensions. | ||
<syntaxhighlight lang="php"> | |||
----------------------------------------------------------------------- | |||
CUSTOM PERMISSIONS & EXTENSIONS | |||
----------------------------------------------------------------------- | |||
1. SECURITY: Prevent anonymous editing and account creation | |||
$wgGroupPermissions['']['edit'] = false; | |||
$wgGroupPermissions['']['createaccount'] = false; | |||
2. BUNDLED EXTENSIONS (Included in Docker image) | |||
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 (Must be manually downloaded to /extensions folder) | |||
wfLoadExtension( 'Mermaid' ); | |||
4. VISUALEDITOR CONFIGURATION | |||
Enable by default for everyone | |||
$wgDefaultUserOptions['visualeditor-enable'] = 1; | |||
Allow VE to work in Docker containers (Fixes "Error contacting Parsoid") | |||
$wgVisualEditorParsoidForwardCookies = true; | |||
5. LUA CONFIGURATION (Required for Scribunto) | |||
$wgScribuntoDefaultEngine = 'luastandalone'; | |||
</syntaxhighlight> | |||
=== C. Adding additional Extensions (WIP - waiting till v1.46 is released this does not work) === | === 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>: | |||
Then | <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> | |||
== 7. Apply Changes == | == 7. Apply Changes == | ||
'''Mount the settings:''' In Portainer, go to the Stack Editor and '''uncomment''' the <code>LocalSettings.php</code> line. | |||
'''Update the Stack:''' Click "Update the stack". | |||
== 8. Email Configuration and Admin | '''Run Database Update:''' Run this command to initialize tables for the new extensions: | ||
<syntaxhighlight lang="bash"> | |||
docker exec -it mediawiki php maintenance/update.php --quick | |||
</syntaxhighlight> | |||
Your wiki is now live at '''https://wiki.gi7b.org''' with VisualEditor, Mermaid, and Code Highlighting enabled! | |||
== 8. Email Configuration and Admin Setup == | |||
=== 1. Email goal (what we were trying to achieve) === | === 1. Email goal (what we were trying to achieve) === | ||
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. | |||
'''Success criterion:''' MediaWiki explicitly says '''“email sent”''' — not just “no error”. | |||
=== | === 2. App Password (Google side) === | ||
'''Where it lives:''' Google Account settings (Security → App passwords). | |||
'''Preconditions:''' 2-Step Verification '''must be enabled'''. | |||
But MediaWiki / PHP '''must receive it without spaces''': | '''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 | :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" | {| class="wikitable" | ||
!Address type | ! Address type !! Can authenticate? | ||
!Can authenticate? | |||
|- | |- | ||
|Real Gmail / Workspace mailbox | | Real Gmail / Workspace mailbox || ✅ Yes | ||
|✅ Yes | |||
|- | |- | ||
|Alias (Send mail as) | | Alias (Send mail as) || ❌ No | ||
|❌ No | |||
|- | |- | ||
|Forward-only address | | Forward-only address || ❌ No | ||
|❌ 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. | === 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>: | |||
= | <syntaxhighlight lang="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 (replace with yours) | |||
'password' => 'APP_PASSWORD_NO_SPACES', // Your Google App Password | |||
]; | |||
$wgPasswordSender = 'info@gi7b.org'; // ALIAS is fine here | |||
</syntaxhighlight> | |||
=== 6. Testing and Defining "Success" === | |||
'''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"> | |||
docker exec -it mediawiki php maintenance/createAndPromote.php --sysop --bureaucrat YourUsername | |||
</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). | |||
'''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>: | |||
<syntaxhighlight lang="php"> | |||
Login attempt throttling | |||
$wgRateLimits['user']['login'] = [ 5, 60 ]; // 5 attempts per minute | |||
$wgRateLimits['ip']['login'] = [ 20, 300 ]; // 20 attempts per 5 minutes | |||
</syntaxhighlight> | |||
== 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: | ||
<syntaxhighlight lang="html"> | |||
<syntaxhighlight lang="python" copy> | |||
print("This code has a copy button!") | |||
</syntaxhighlight> | |||
</syntaxhighlight> | |||
:*Note: The <code>copy</code> attribute adds a copy-to-clipboard button (available in newer MediaWiki versions). | |||
== 11. List of Extensions == | |||
[https://www.youtube.com/watch?v=4xYbqbabTwI Youtube: Introduction to MediaWiki: Wikipedia's extensions (Part 2)] | [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"> | |||
cd /opt/stacks/mediawiki/extensions | |||
</syntaxhighlight> | |||
'''2. Download the Extension''' | |||
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 | |||
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"> | |||
docker exec -it mediawiki php maintenance/update.php --quick | |||
</syntaxhighlight> | |||
Note: This step is required whenever you add an extension that modifies the database. | |||
Revision as of 09:03, 23 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 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 wiki.gi7b.org as the example domain).
Reference: Official MediaWiki Docker Image https://hub.docker.com//mediawiki
1. Prerequisites
Before starting, ensure you have:
Docker & Docker Compose
- Installation (Linux/Windows/Mac): https://docs.docker.com/engine/install/
- Docker Compose Standalone (if needed separately): https://docs.docker.com/compose/install/
Portainer CE (Community Edition)
- Docker Standalone Install Guide: https://docs.portainer.io/start/install-ce/server/docker/linux
Domain & Cloudflare Setup
- How to Register a Domain with Cloudflare: 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/
NGINX Reverse Proxy
- Nginx Proxy Manager (Docker 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
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)
Use the following YAML configuration.
In Portainer:
Go to Stacks → Add 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://localhost:8191 (or your server IP:8191).
Follow the prompts. When asked for Database Settings, use:
- Host:
database - Name:
mediawiki - User:
mediawiki - Password:
mediawiki
- Host:
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, WikiEditor, SyntaxHighlight_GeSHi, etc.) are hidden. We must copy them from the image to the host.
Step A: Extract Extensions
Run this on your Host Terminal:
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 (which creates code blocks) requires a specific Python file (pygmentize) to be executable. This permission is often lost during the copy.
Run this command to fix it:
chmod a+x /opt/stacks/mediawiki/extensions/SyntaxHighlight_GeSHi/pygments/pygmentize
If you skip this, code blocks will not render or will show errors.
Step C: Add External Extensions
Download Mermaid (External Extension):
cd /opt/stacks/mediawiki/extensions
git clone https://github.com/SemanticMediaWiki/Mermaid.git Mermaid
Verify the folder content. You should see a mix of default extensions and Mermaid:
ls -F /opt/stacks/mediawiki/extensions/
Output should include: SyntaxHighlight_GeSHi/, VisualEditor/, Mermaid/, WikiEditor/, etc.
6. Configuring LocalSettings.php
Move the downloaded LocalSettings.php to /opt/stacks/mediawiki/LocalSettings.php.
in linux terminal
sudo nano /opt/stacks/mediawiki/LocalSettings.php
Edit the file (sudo nano /opt/stacks/mediawiki/LocalSettings.php) and make the following changes:
A. Set the Custom Domain
Find the $wgServer line (around line 30) and change it to your actual domain:
The protocol and server name to use in fully-qualified URLs
$wgServer = "https://wiki.gi7b.org";
B. Add Permissions & Extensions
Paste this block at the very bottom of the file to enable security and extensions.
-----------------------------------------------------------------------
CUSTOM PERMISSIONS & EXTENSIONS
-----------------------------------------------------------------------
1. SECURITY: Prevent anonymous editing and account creation
$wgGroupPermissions['']['edit'] = false;
$wgGroupPermissions['']['createaccount'] = false;
2. BUNDLED EXTENSIONS (Included in Docker image)
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 (Must be manually downloaded to /extensions folder)
wfLoadExtension( 'Mermaid' );
4. VISUALEDITOR CONFIGURATION
Enable by default for everyone
$wgDefaultUserOptions['visualeditor-enable'] = 1;
Allow VE to work in Docker containers (Fixes "Error contacting Parsoid")
$wgVisualEditorParsoidForwardCookies = true;
5. LUA CONFIGURATION (Required for Scribunto)
$wgScribuntoDefaultEngine = 'luastandalone';
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 Collections and PdfBook.
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
Then edit LocalSettings.php:
3. EXTERNAL EXTENSIONS (Must be manually downloaded to /extensions folder)
wfLoadExtension( 'Mermaid' );
wfLoadExtension( 'Collection' ); // wait till version 1.46
wfLoadExtension( 'PdfBook' );
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: Run this command to initialize tables for the new extensions:
docker exec -it mediawiki php maintenance/update.php --quick
Your wiki is now live at https://wiki.gi7b.org with VisualEditor, Mermaid, and Code Highlighting enabled!
8. Email Configuration and Admin Setup
1. Email goal (what we were trying to achieve)
MediaWiki must be able to send email reliably (account confirmation, password reset, notifications).
Emails should appear as coming from info@gi7b.org.
Authentication must work with Gmail / Google Workspace.
No local SMTP server, no Docker mail container.
Success criterion: MediaWiki explicitly says “email sent” — not just “no error”.
2. App Password (Google side)
Where it lives: Google Account settings (Security → App passwords).
Preconditions: 2-Step Verification must be enabled.
Critical Detail (The "Space" Trap):
- Google displays the password like this:
xxxx xxxx xxxx xxxx - But MediaWiki / PHP must receive it without spaces:
xxxxxxxxxxxxxxxx
- If you keep the spaces, Google returns
SMTP 535 5.7.8 BadCredentials.
3. Real email vs Alias (Authentication Reality)
Core Rule: SMTP login must use a real mailbox, not an alias.
| Address type | Can authenticate? |
|---|---|
| Real Gmail / Workspace mailbox | ✅ Yes |
| Alias (Send mail as) | ❌ No |
| Forward-only address | ❌ No |
Login / username → Real mailbox (e.g., admin@gi7b.org)
Sender address → Can be the alias (e.g., info@gi7b.org)
4. "Send as" using Cloudflare Email Routing
If info@gi7b.org is an alias using Cloudflare Email Routing:
Cloudflare routes incoming mail for info 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 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 (replace with yours)
'password' => 'APP_PASSWORD_NO_SPACES', // Your Google App Password
];
$wgPasswordSender = 'info@gi7b.org'; // ALIAS is fine here
6. Testing and Defining "Success"
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:
docker exec -it mediawiki php maintenance/createAndPromote.php --sysop --bureaucrat YourUsername
(Note: If the user already exists, you may need to use maintenance/run.php userOptions or edit the database directly if createAndPromote complains, but often createAndPromote handles existing users gracefully or you can use the UserRights page if you have another admin).
Alternative (UI Method):
If you are the first user (Sysop) created during installation, go to Special:UserRights 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 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
Once SyntaxHighlight_GeSHi is active (see Section 5):
VisualEditor: Click Insert > More > Code Block.
Source Editor: Use the tag:
<syntaxhighlight lang="python" copy>
print("This code has a copy button!")
</syntaxhighlight>
- Note: The
copyattribute adds a copy-to-clipboard button (available in newer MediaWiki versions).
- Note: The
11. List of Extensions
Youtube: Introduction to MediaWiki: Wikipedia's extensions (Part 2)
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:
cd /opt/stacks/mediawiki/extensions
2. Download the Extension
Find the extension on MediaWiki.org. Use git to download it (replace ExtensionName with the actual name).
Example: Downloading "Math" extension
git clone https://www.google.com/search?q=https://gerrit.wikimedia.org/r/mediawiki/extensions/Math.git
Tip: Ensure the folder name matches exactly what wfLoadExtension expects.
3. Edit Configuration Open your settings file:
sudo nano /opt/stacks/mediawiki/LocalSettings.php
4. Enable or Disable Scroll to the bottom.
To Enable: Add wfLoadExtension( 'ExtensionName' );
To Disable: Add a # at the start of the line: # wfLoadExtension( 'ExtensionName' );
5. Apply Changes
Save the file (Ctrl+O, Enter, Ctrl+X). Then run the update script inside the container:
docker exec -it mediawiki php maintenance/update.php --quick
Note: This step is required whenever you add an extension that modifies the database.