MediaWiki Docker Installation

Aus Laub-Home.de Wiki
Zur Navigation springen Zur Suche springen

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.

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 es somit persistent zu machen
  • Danach lauscht das MediaWiki auf localhost:8091
  • sollte dann via NGINX Reverse Proxy in die weite Welt rausgereicht werden
  • Optional: Extensions einbinden
  • Optional: Extension Visual Editor mit Parsoid Container
  • Optional: Migration von einem anderen Server
  • Backup and Restore

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
DB_ROOT_PASS=DBROOTPASSWORD
DB_NAME=wiki
DB_USER=wiki
DB_PASS=DBPASSWORD

# Port Configuration
INT_PORT=80
BIND_TO=127.0.0.1:8091

# Memcached Size
CACHE=64M

# Timezone
TZ=Europe/Berlin

/opt/mediawiki/docker-compose.yml

version: '3.7'

services:
  database: 
    image: mariadb:latest
    volumes:
      - data_mediawiki_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:latest
    depends_on:
      - database
      - memcached
    restart: always
    environment:
      TZ: ${TZ}
    ports:
      - ${BIND_TO}:${INT_PORT}
    volumes:
      - data_mediawiki_wiki:/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
      # Spezial 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
      # Mediwaiki Extensions
      #- ./data/extensions/WikiCategoryTagCloud:/var/www/html/extensions/WikiCategoryTagCloud:ro
      #- ./data/extensions/CategoryTagCloud:/var/www/html/extensions/CategoryTagCloud:ro
      #- ./data/extensions/SelectCategory:/var/www/html/extensions/SelectCategory:ro
      #- ./data/extensions/googleAnalytics:/var/www/html/extensions/googleAnalytics:ro
      #- ./data/extensions/GoogleAdSense:/var/www/html/extensions/GoogleAdSense: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
      # Mediawiki Skins
      #- ./data/skins/MinervaNeue:/var/www/html/skins/MinervaNeue:ro

    networks:
      frontend-nw:
        aliases:
          - wiki
      backend-nw:

volumes:
  data_mediawiki_db:
  data_mediawiki_wiki:

networks:
  frontend-nw:
    driver: bridge
    driver_opts:
      com.docker.network.bridge.name: br-mediawikife
  backend-nw:
    driver: bridge
    driver_opts:
      com.docker.network.bridge.name: br-mediawikibe

/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

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
  • Aktivieren von maximal 5 Contribution Credits im Footer
  • Short URLs aktivieren (Achtung, hierfür wird die .htaccess Datei benötigt!)
  • Apple Touch und Favicon definieren
  • Suchmaschinen dürfen Links folgen
  • 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://mx.laub-home.de", // could also be an IP address. Where the SMTP server is located
    'IDHost'   => "laub-home.de",      // 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' => "wiki@laub-home.de",     // Username to use for SMTP authentication (if being used)
    'password' => "Karma33$"       // 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;

# 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",
];

# 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=$(docker exec laubhome_mediawiki_1 env | grep MEDIAWIKI_BRANCH |cut -d"=" -f2)
git clone -b $MW_BRANCH "https://gerrit.wikimedia.org/r/mediawiki/extensions/CookieWarning"
git clone -b $MW_BRANCH "https://gerrit.wikimedia.org/r/mediawiki/extensions/GoogleAdSense"
git clone -b $MW_BRANCH "https://gerrit.wikimedia.org/r/mediawiki/extensions/googleAnalytics"
git clone -b $MW_BRANCH "https://gerrit.wikimedia.org/r/mediawiki/extensions/Lockdown"
git clone -b $MW_BRANCH "https://gerrit.wikimedia.org/r/mediawiki/extensions/SelectCategory"
git clone -b $MW_BRANCH "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"

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";

# Google Analytics
require_once( "$IP/extensions/googleAnalytics/googleAnalytics.php" );
$wgGoogleAnalyticsAccount = 'UA-9xx09xx-3'; 

# Enable Google Adsense
wfLoadExtension( 'GoogleAdSense' );
$wgGoogleAdSenseClient = 'ca-pub-656xx14736xxx828';
$wgGoogleAdSenseSlot = '218218xxxx';
$wgGoogleAdSenseID = 'Wiki_Big';
$wgGoogleAdSenseWidth  = 160;
$wgGoogleAdSenseHeight = 250;
// Source URL of the AdSense script
$wgGoogleAdSenseSrc    = '//pagead2.googlesyndication.com/pagead/show_ads.js';

# 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');

# Cookie Warning Extension
wfLoadExtension( 'CookieWarning' );
$wgCookieWarningEnabled = true;

# Discription2
wfLoadExtension( 'Description2' );
$wgEnableMetaDescriptionFunctions = true;

# Related Articles
wfLoadExtension( 'RelatedArticles' );
$wgRelatedArticlesFooterWhitelistedSkins = ['minerva', 'vector'];
$wgRelatedArticlesDescriptionSource = 'pagedescription';

Mehr Extensions findet ihr hier:

VisualEditor einbinden

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

 1 ...
 2 
 3   parsoid:
 4     image: thenets/parsoid:0.10.0
 5     restart: always
 6     environment:
 7       PARSOID_DOMAIN_localhost: http://wiki:80/api.php
 8     networks:
 9       backend-nw:
10         aliases:
11             - parsoid
12 
13 ...

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

1 ...
2 
3       # Mediwaiki Extensions
4       - ./data/extensions/VisualEditor:/var/www/html/extensions/VisualEditor:ro
5 
6 ...

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_mediawiki_1 php maintenance/generateSitemap.php --skip-redirects --server https://www.laub-home.de --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 laubhome_mediawiki_1 php maintenance/generateSitemap.php --skip-redirects --server https://www.laub-home.de --fspath sitemap --urlpath sitemap/

Apple Touch Icons

Optional:

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

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

oder via Script alle automatisch aktualisieren:

Nun das Ganze wieder hochfahren:

docker-compose up -d

und nun alle Funktionen testen!

Quellen