MediaWiki Docker Installation
Wie kann man ein MediaWiki am besten via Docker bzw. Docker Compose deployen?
Zunächst nehmen wir den von WikiMedia betreuten Container von MediaWiki, packen dazu noch eine MariaDB und für ein wenig mehr Performance noch einen memcached Container. Optional kann dann, für den VisualEditor, Parsoid mit deployt werden. Vor das gesamte Docker Compose Projekt (MediaWiki Applikation) packen wir noch einen NGINX SSL Reverse Proxy für Docker Container, fertig ist unsere MediaWiki Installation. Möchte man dann noch ein bereits bestehendes MediaWiki migrieren, findet ihr im MediaWiki Migration von einem anderen Server HowTo das richtige Vorgehen.
Deployment via Docker Container
Was passiert hier nun in Kurzfassung:
- es wird ein Projekt erstellt mit MediaWiki, MariaDB und Memcached
- die MediaWiki und MariaDB Daten werden als Volumes gemountet um sie somit persistent zu machen
- Danach lauscht das MediaWiki auf localhost:8091
- sollte dann via NGINX Reverse Proxy in die weite Welt rausgereicht werden
- Optional: können weitere Extensions eingebunden werden
- Optional: Migration von einem anderen Server
- Backup and Restore des gesamten MediaWiki
Docker Compose Projekt
Als erstes legen wir das docker-compose
Projekt an:
mkdir -p /opt/mediawiki/data/conf
mkdir /opt/mediawiki/data/extensions
mkdir /opt/mediawiki/data/sitemap
mkdir /opt/mediawiki/data/skins
cd /opt/mediawiki
/opt/mediawiki/.env
# Config File for MediaWiki Application # Docker Compose Project Name # max length 11 characters PROJECT_NAME=mediawiki # Maria DB Configuration DB_ROOT_PASS=DBROOTPASSWORD DB_NAME=wiki DB_USER=wiki DB_PASS=DBPASSWORD # MediaWiki Port Configuration WIKI_HTTP_PORT=127.0.0.1:8091 # Wiki Version # for latest: WIKI_VERSION=latest # Specific Version #WIKI_VERSION=1.42 # Memcached Size CACHE=16M # Timezone TZ=Europe/Berlin
/opt/mediawiki/docker-compose.yml
services:
database:
image: mariadb:latest
volumes:
- data_mw_db:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASS}
MYSQL_DATABASE: ${DB_NAME}
MYSQL_USER: ${DB_USER}
MYSQL_PASSWORD: ${DB_PASS}
TZ: ${TZ}
networks:
backend-nw:
aliases:
- db
memcached:
image: memcached:alpine
restart: always
command: ["-m", "${CACHE}"]
environment:
- TZ=${TZ}
networks:
backend-nw:
aliases:
- wikimemcached
mediawiki:
image: mediawiki:${WIKI_VERSION}
depends_on:
- database
- memcached
restart: always
environment:
TZ: ${TZ}
ports:
- ${WIKI_HTTP_PORT}:80
volumes:
- data_mw_images:/var/www/html/images
- ./data/sitemap:/var/www/html/sitemap
# After initial setup, download LocalSettings.php to data/conf directory
# and uncomment the following line and use compose to restart
# the mediawiki service
#- ./data/conf/LocalSettings.php:/var/www/html/LocalSettings.php:ro
- ./data/conf/.htaccess:/var/www/html/.htaccess:ro
# Special Stuff (Google AdSense & Search Console)
#- ./data/conf/robots.txt:/var/www/html/robots.txt:ro
#- ./data/conf/ads.txt:/var/www/html/ads.txt:ro
# Mediawiki Extensions
#- ./data/extensions/WikiCategoryTagCloud:/var/www/html/extensions/WikiCategoryTagCloud:ro
#- ./data/extensions/Lockdown:/var/www/html/extensions/Lockdown:ro
#- ./data/extensions/MobileFrontend:/var/www/html/extensions/MobileFrontend:ro
#- ./data/extensions/CookieWarning:/var/www/html/extensions/CookieWarning:ro
#- ./data/extensions/RelatedArticles:/var/www/html/extensions/RelatedArticles:ro
#- ./data/extensions/Description2:/var/www/html/extensions/Description2:ro
#- ./data/extensions/RottenLinks:/var/www/html/extensions/RottenLinks:ro
# Mediawiki Skins
#- ./data/skins/MinervaNeue:/var/www/html/skins/MinervaNeue:ro
networks:
app-nw:
aliases:
- wiki
backend-nw:
volumes:
data_mw_db:
data_mw_images:
networks:
app-nw:
internal: false
driver: bridge
driver_opts:
com.docker.network.bridge.name: app-${PROJECT_NAME}
backend-nw:
internal: true
driver: bridge
driver_opts:
com.docker.network.bridge.name: be-${PROJECT_NAME}
/opt/mediawiki/data/conf/.htaccess
<IfModule mod_rewrite.c> RewriteEngine On # Normale Desktop Short URL Umleitung RewriteBase / RewriteRule ^/index.php/(.*) /wiki/$1 [QSA,R=permanent] RewriteRule ^/?wiki(/.*)?$ %{DOCUMENT_ROOT}/index.php </IfModule> # Sitemap umleiten Redirect /sitemap.xml /sitemap/sitemap-index-wiki.xml # Upload Limit erhöhen php_value upload_max_filesize 100M php_value post_max_size 100M
Optional:
Diese Datei wird von Google AdSense verlangt. Den Inhalt bekommt man aus dem Adsense Webinterface. Im docker-compose.yml
bitte die entsprechende Zeile einkommentierten!
/opt/mediawiki/data/conf/ads.txt
google.com, pub-656291473678xxx, DIRECT, f08c47fec094xxx
Optional:
Falls gewollt kann man eine robots.txt für Suchmaschinen anlegen. Diese hier verbietet den zugriff auf die Spezialseiten, Diskussionen und die Index.php selbst, damit nur die Short URLs gecrawlt werden. Zusätzlich informiert sie über den Ort der Sitemap. Im docker-compose.yml
bitte die entsprechende Zeile einkommentierten!
/opt/mediawiki/data/conf/robots.txt
User-agent: * Disallow: /index.php Disallow: /Index.php Disallow: /*Spezial: Disallow: /*Diskussion: Sitemap: https://www.laub-home.de/sitemap/sitemap-index-wiki.xml
Nun kann das Ganze einfach gestartet werden:
docker compose up -d
nun sollte via
curl http://localhost:8091
eine Ausgabe kommen.
Nginx Reverse Proxy
Um das Ganze dann von außen verfügbar zu machen, richten wir auf unserem NGINX SSL Reverse Proxy für Docker Container einen neuen vhost ein:
/opt/nginxproxy/data/nginx/conf/www.example.tld.conf
server { listen 80; listen [::]:80; server_name www.example.tld wiki.example.tld example.tld; return 301 https://$host$request_uri; } server { listen 443 ssl; listen [::]:443 ssl; server_name www.example.tld wiki.example.tld example.tld; if ($host != $server_name) { rewrite ^/(.*) $scheme://$server_name/$1 permanent; } ssl_certificate /etc/letsencrypt/live/www.example.tld/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/www.example.tld/privkey.pem; include /etc/nginx/conf.d/includes/site-defaults.conf; include /etc/nginx/conf.d/includes/cert_bot.conf; include /etc/nginx/conf.d/includes/google.conf; expires $expires; location / { proxy_pass http://127.0.0.1:8091; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; client_max_body_size 0; #include /etc/nginx/conf.d/includes/proxy_cache.conf; } # show cache status and any skip cache reason #add_header Proxy-Cache $upstream_cache_status; add_header X-XSS-Protection "1; mode=block"; }
Nun nicht vergessen die SSL Zertifikate für die neue Domain zu erstellen:
dadurch wird auch der Nginx Proxy neu gestartet und die MediaWiki Startseite sollte im Anschluss verfügbar sein. MediWiki kann dann einfach konfiguriert werden, oder aber ein bereits bestehendes MediaWiki migriert werden.
Konfiguration des Mediawiki
Die Grundkonfiguration erfolgt durch das erstmalige aufrufen der Startseite. Diese, falls es keine LocalSettings.php
, ist ein Konfigurationsassistent. Einfach nun nach belieben konfigurieren und an der Stelle wo nach dem Memcached gefragt wird folgendes eintragen:
wikimemcached:11211
Und bei der Frage nach der Datenbankverbindung bitte den DB Alias Namen von Docker eintragen:
db
Im Anschluss kann die Datei heruntergeladen und nach /opt/mediawiki/data/conf/
kopiert werden. Dann im /opt/mediawiki/docker-compose.yml
die Zeile mit der LocalSettings.php
einkommentierten:
# After initial setup, download LocalSettings.php to data/conf directory
# and uncomment the following line and use compose to restart
# the mediawiki service
- ./data/conf/LocalSettings.php:/var/www/html/LocalSettings.php:ro
und das Projekt neu deployen:
cd /opt/mediawiki
docker compose up -d
Nun sollte die richtige Startseite angezeigt werden.
Spezielle Einstellungen
Ich habe in der LocalSettings.php
noch die folgenden Einstellungen vorgenommen:
- SMTP Server Konfiguration (da Docker nicht über localhost mailen kann)
- E-Mail Adressen der Benutzer müssen bestätigt werden
- Short URLs aktivieren (Achtung, hierfür wird die
.htaccess
Datei benötigt!) - Apple Touch und Favicon definieren
- Suchmaschinen dürfen Links nicht folgen
- Setzen von
noindex
für Seiten die nicht gecrawlt werden sollen - Externe Links sollen in neuem Tab geöffnet werden
- Aushebeln der Fileupload Restriktion, somit können alle Arten von Dateien hochgeladen werden
- IPv6 Ready Logo im Footer
- Debugging Optionen (einkommentierten, falls benötigt)
- Wiki Read Only schalten, damit kann niemand etwas editieren
/opt/mediawiki/data/conf/LocalSettings.php
# End of automatically generated settings.
# Add more configuration options below.
# Mailserver connection
$wgSMTP = [
'host' => "ssl://YOURMXSERVER", // could also be an IP address. Where the SMTP server is located
'IDHost' => "example.org", // Generally this will be the domain name of your website (aka mywiki.org)
'port' => 465, // Port to use when connecting to the SMTP server
'auth' => true, // Should we use SMTP authentication (true or false)
'username' => "yourmailadress", // Username to use for SMTP authentication (if being used)
'password' => "yourpassword" // Password to use for SMTP authentication (if being used)
];
# E-Mail Adressvalidierung
$wgEmailConfirmToEdit = true;
# Contribution Credits
$wgMaxCredits = 5;
# Short URLs
$wgScriptExtension = ".php";
$wgArticlePath = "/wiki/$1";
$wgUsePathInfo = true;
# NoIndex for crawlers
$wgNamespaceRobotPolicies[NS_TALK] = 'noindex';
$wgNamespaceRobotPolicies[NS_SPECIAL] = 'noindex';
$wgNamespaceRobotPolicies[NS_MEDIA] = 'noindex';
$wgNamespaceRobotPolicies[NS_FILE] = 'noindex';
$wgNamespaceRobotPolicies[NS_CATEGORY] = 'noindex';
$wgNamespaceRobotPolicies[NS_CATEGORY_TALK] = 'noindex';
#$wgNamespaceRobotPolicies[NS_USER] = 'noindex';
# Apple Touch Icon
$wgAppleTouchIcon = "/images/apple-touch-icon-ipad3.png";
# Favicon
$wgFavicon = "/images/favicon.ico";
# Follow Links
$wgNoFollowLinks = false;
# Externe Links in neuem Fenster
$wgExternalLinkTarget = '_blank';
# File Upload Restriction
$wgStrictFileExtensions = false;
#$wgFileExtensions = array('txt','rar','gz','tar','zip','pdf','png','jpg','jpeg','ogg','doc','xls','ppt','mp3','sxc','nse','ico');
#$wgVerifyMimeType = false;
# IPV6 Ready Logo
$wgFooterIcons['poweredby']['ipv6'] = [
"src" => "https://ipv6-test.com/button-ipv6-small.png",
// you may also use a direct path to the source, e.g. "http://example.com/my/custom/path/to/MyCustomLogo.png"
"url" => "https://ipv6-test.com/validate.php?url=referer",
"alt" => "ipv6 ready",
// If you have a non-default sized icon you can specify the size yourself.
"height" => "31",
"width" => "88",
];
# VisualEditor
// OPTIONAL: Enable VisualEditor's experimental code features
$wgDefaultUserOptions['visualeditor-enable-experimental'] = 1;
$wgVisualEditorEnableVisualSectionEditing = true;
$wgVisualEditorEnableWikitext = true;
$wgVisualEditorEnableDiffPage = true;
# ReadOnly Mode
#$wgReadOnly = "<h1><b>Ist nur der Mirror. Bitte unter www.laub-home.de editieren</b></h1><br>";
#$wgReadOnly = "<h1><b>Migration Ongoing</b></h1><br>";
# Enable Debugging
#$wgShowExceptionDetails = true;
#$wgShowDBErrorBacktrace = true;
Am besten nach dem Konfigurieren einmal das Projekt Neustarten und den Browser Cache leeren:
cd /opt/mediawiki
docker compose restart
Extensions herunterladen
Möchte man eigene, zusätzliche extensions nutzen, sollten diese im Ordner /opt/mediawiki/data/extensions
geladen werden. Ich habe die folgenden Extension integriert. Möchte man diese dann verwenden, einfach im docker-compose.yml
diese als Volume in den Container mounten.
Hier die GIT Befehle, für die von mir verwendeten Extensions:
MW_BRANCH=REL1_39
git clone -b $MW_BRANCH "https://gerrit.wikimedia.org/r/mediawiki/extensions/Lockdown"
git clone -b master "https://gerrit.wikimedia.org/r/mediawiki/extensions/WikiCategoryTagCloud"
git clone -b $MW_BRANCH "https://gerrit.wikimedia.org/r/mediawiki/extensions/Description2"
git clone -b $MW_BRANCH "https://gerrit.wikimedia.org/r/mediawiki/extensions/RelatedArticles"
git clone -b $MW_BRANCH "https://gerrit.wikimedia.org/r/mediawiki/extensions/MobileFrontend"
git clone https://github.com/miraheze/RottenLinks.git
nun im docker-compose.yml
die entsprechenden Zeilen einkommentierten und das Projekt neu deployen:
docker compose up -d
Nun können die Extension via LocalSettings.php
eingebunden und konfiguriert werden.
/opt/mediawiki/data/conf/LocalSettings.php
# End of Standard Extensions and Settings
# enable more Extensions below
# WikiCategoryTagCloud
wfLoadExtension( 'WikiCategoryTagCloud' );
# Enable SelectCategory
require_once "$IP/extensions/SelectCategory/SelectCategory.php";
# Enable Lockdown
wfLoadExtension( 'Lockdown' );
$wgSpecialPageLockdown['Version'] = array('user', 'bureaucrat', 'sysop');
$wgSpecialPageLockdown['Export'] = array('user', 'bureaucrat', 'sysop');
$wgSpecialPageLockdown['Listfiles'] = array('user', 'bureaucrat', 'sysop');
$wgSpecialPageLockdown['Listusers'] = array('user', 'bureaucrat', 'sysop');
$wgSpecialPageLockdown['Statistics'] = array('user', 'bureaucrat', 'sysop');
$wgSpecialPageLockdown['Booksources'] = array('user', 'bureaucrat', 'sysop');
$wgSpecialPageLockdown['Protectedpages'] = array('user', 'bureaucrat', 'sysop');
$wgActionLockdown['history'] = array('user', 'bureaucrat', 'sysop');
$wgActionLockdown['edit'] = array('user', 'bureaucrat', 'sysop');
# Discription2
wfLoadExtension( 'Description2' );
$wgEnableMetaDescriptionFunctions = true;
# Related Articles
wfLoadExtension( 'RelatedArticles' );
$wgRelatedArticlesFooterWhitelistedSkins = ['minerva', 'vector'];
$wgRelatedArticlesDescriptionSource = 'pagedescription';
$wgRelatedArticlesUseCirrusSearchApiUrl = '/api.php';
# Rotten Links Extension
wfLoadExtension( 'RottenLinks' );
Mehr Extensions findet ihr hier:
VisualEditor einbinden
Achtung! Ab Version des MediaWiki 1.35 ist der VisualEditor inklusive dem Parsoid Service im Paket enthalten und Bedarf keiner separaten Einbindung.
Möchte man noch die Extension VisualEditor (Wysigwyg Editor von Wikipedia) einbinden, um ein einfacheres Bearbeiten von Wiki Seiten zu ermöglichen, braucht man zunächst den Container thenets/parsoid:0.10.0
. Ich verwende hier ein MediaWiki 1.34, man sollte auf jedenfalls schauen, welche Parsoid Version zum verwendeten MediaWiki passt. Um den besagten Container mit unserer Applikation hochzufahren, fügen wir vor den MediaWiki Part die folgenden Zeilen ein:
/opt/mediawiki/docker-compose.yml
...
parsoid:
image: thenets/parsoid:0.10.0
restart: always
environment:
PARSOID_DOMAIN_localhost: http://wiki:80/api.php
networks:
backend-nw:
aliases:
- parsoid
...
Nun laden wir die VisualEditor Extension in unseren Extension Ordner unter /opt/mediawiki/data/extensions
herunter
MW_BRANCH=$(docker exec laubhome_mediawiki_1 env | grep MEDIAWIKI_BRANCH |cut -d"=" -f2)
cd /opt/mediawiki/data/extensions
git clone -b $MW_BRANCH https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor.git
cd VisualEditor
git submodule update --init
Wichtig zu beachten ist, dass wir hier zwingend den Branch in Form von der MediaWiki Version angeben müssen, da der Master nur mit der Alpha Version von MediaWiki lauffähig ist.
Nun aktivieren wir die Extension noch im docker-compose.yml
/opt/mediawiki/docker-compose.yml
...
# Mediwaiki Extensions
- ./data/extensions/VisualEditor:/var/www/html/extensions/VisualEditor:ro
...
Nun können wir das Setup deployen:
docker-compose up -d
Nun konfigurieren wir das Ganze noch in der LocalSettings.php
# VisualEditor and Parsoid
wfLoadExtension( 'VisualEditor' );
// Enable by default for everybody
$wgDefaultUserOptions['visualeditor-enable'] = 1;
// Optional: Set VisualEditor as the default for anonymous users
// otherwise they will have to switch to VE
$wgDefaultUserOptions['visualeditor-editor'] = "visualeditor";
// Don't allow users to disable it
$wgHiddenPrefs[] = 'visualeditor-enable';
// OPTIONAL: Enable VisualEditor's experimental code features
#$wgDefaultUserOptions['visualeditor-enable-experimental'] = 1;
$wgVisualEditorEnableVisualSectionEditing = true;
$wgVisualEditorEnableTocWidget = true;
$wgVirtualRestConfig['modules']['parsoid'] = array(
// URL to the Parsoid instance
// Use port 8142 if you use the Debian package
'url' => 'parsoid:8000',
// Parsoid "domain", see below (optional)
'domain' => 'localhost',
// Parsoid "prefix", see below (optional)
'prefix' => 'localhost'
);
Wenn man jetzt einen Reload seines Wikis macht, sieht man sofort, dass es nun Bearbeiten
und Quelltext Bearbeiten
gibt. Quelltext Bearbeiten
ist der alte WikiEditor, während Bearbeiten
zum neuen Visual Editor führen sollte.
Sitemap generieren
Mediawiki bringt ein Skript mit, welches automatisch eine Sitemap generiert. Will man es Manuel ausführen einfach folgenden Befehl nutzen:
docker exec -i <mediawiki_container_name> php maintenance/generateSitemap.php --skip-redirects --server https://<yourdomain> --fspath sitemap --urlpath sitemap/
Hier das Ganze automatisch, alle 4h via Cron-Job.
/etc/cron.d/wikisitemap
# # Regular cron job for the Wiki Sitemap generation # 15 */4 * * * root docker exec -i <mediawiki_container_name> php maintenance/generateSitemap.php --skip-redirects --server https://<yourdomain> --fspath sitemap --urlpath sitemap/
Apple Touch Icons
Optional:
Vector-2022 als Standard Skin
Möchtet ihr den neuen Vector-2022 Skin als Default haben, sucht $wgDefaultSkin
Parameter in der LocalSettings.php und ändert ihn wie folgt ab. Solltet ihr den Parameter gar nicht haben, einfach einfügen.
LocalSettings.php
## Default skin: you can change the default skin. Use the internal symbolic
## names, ie 'vector', 'monobook':
#$wgDefaultSkin = "vector";
$wgDefaultSkin = 'vector-2022';
Mobile Theme
Will man den selben Mobile Theme wie Wikipedia zur Verfügung stellen, dann die folgende Anleitung nutzen:
Migration eines bestehenden MediaWikis
Hat man bereits auf einem anderen System eine Mediawiki Installation, dann kann man diese einfach in die neue Container basierte integrieren.
Backup des Projektes
- das MediaWiki Images Volume muss gesichert werden
- MariaDB Datenbank muss via
mysqldump
gesichert werden
wie das geht, erfahrt ihr hier:
Update des Mediawiki
Will man das MediaWiki docker compose
Projekt aktualisieren, dann muss zunächst das gesamte Projekt undeployt werden:
cd /opt/mediawiki
docker compose down
Solltet ihr nicht mit der latest Version im .env
file arbeiten, solltet ihr nun die neue Version konfigurieren.
nun kann mit dem PULL das komplette Projekt / die Container aktualisiert werden:
docker compose pull
Das Ganze kann auch Watchtower übernehmen und die Container automatisch aktualisieren.
nun alle Extensions manuell aktualisieren
cd data/extensions/EXTENSIONFOLDER
git pull
Solltet ihr ein neues MediaWiki Release verwenden, müssen die passenden Extension heruntergeladen werden. Hierfür am besten alle Extension löschen und neu herunterladen.
oder via Script alle automatisch aktualisieren:
Nun das Ganze wieder hochfahren:
docker compose up -d
und nun alle Funktionen testen!