User:ItamarWMDE/Multi Site Docker

TODO:

   INSERT INTO interwiki (iw_prefix, iw_url, iw_api, iw_wikiid, iw_local, iw_trans) VALUES ('default', 'http://default.web.mw.localhost:8080/mediawiki/index.php/$1', 'http://default.web.mw.localhost:8080/mediawiki/api.php', , 1, 0)
  • Add bit regarding DPS / Adding hosts
  • Add caveat regarding cache
  • Add caveat regarding CORS

The following page describes how to set up a local multi-wikibase development environment. This environment will consist of a wikibase repo/client installation as a default site for item entities and an additional wikibase client site to interact with those entities.

A little backgroundEdit

While picking up one of my first tickets (phab:T243969), I wanted to set up a local development environment to help me reproduce this issue. Since I was (am) a beginner in wikimedia, I decided to setup my initial environment using Addshore's docker instance.

As a complete noob to both docker and mediawiki, I wasn't quite sure how to go about it, and when things went wrong (as they happen to do with every step of the way), I had a hard time trying to decipher how to debug them. Thanks to the help from the great team here at wikibase/wikidata in WMDE, I'm writing this guide as a primer on how to reproduce this setup, with as much of a hassle free process as possible.

The following tutorial assumes that you are working in a Linux environment, and that you are using bash as your shell.

Step 0: Get you a docker envEdit

Note: This entire tutorial is based on the docker dev environment provided by Addshore If you would like to set up your multi wiki environment in a different way, I recommend visiting the Official Installation Guide.

If you haven't done so already, head over to mediawiki-docker-dev on Github and follow the instructions there to prepare your local installation. Once you are done, make sure to also install the wikibase extension according to the instructions for a Repo/Client site.

Step 1: Add another wiki to the mixEdit

Adding a new site is pretty simple with the provided scripts in mediawiki-docker-dev. To add a new site run the following (replace <site-name> with the name for your wiki:

$ mw-dev addsite <site-name>

Assuming we ran the command above with a name such as testwiki, we will be able to access our new wiki in the browser by going to testwiki.web.mw.localhost:8080. The command above also creates a new database with the exact same name.

Problem #1: Repo vs. ClientEdit

Even though we got two wikis with two separate databases, we still have a small issue: since they are both using the same mediawiki directory, it also means that they are using the same LocalSettings.php file.

Normally this wouldn't be an issue. However, we want to create two separate wikis, with two different sets of extensions. Namely, we would like to have a "Repo/Client" wikibase in our original wiki, and a "Client Only" wikibase, in our new wiki.

Luckily, this can be mitigated by re-purposing a handy variable included in /.docker/LocalSettings.php: $dbName, which contains the name of the wiki (database) being accessed. This will enable us to create and load separate LocalSettings files such as LocalSettings.default.php or LocalSettings.testwiki.php depending on the requested wiki.

1.1. Prepare gitEdit

Since we will be adding several LocalSettings files, we would probably want to ignore them, without shamelessly polluting .gitignore for our own needs. To achieve that (In this and any other project) I like to create a .local directory in the repo and add it to .git/info/exclude.

In your mediawiki directory run the following:

$ mkdir .local
$ echo .local/ >> .git/info/exclude

1.2. Split LocalSettingsEdit

Now that we have a place to put our new LocalSettings files, we can add some conditional magic to our main LocalSettings.php.

Paste the following code at the bottom of mediawiki/LocalSettings.php:

// Load correct settings file per site
if(file_exists(__DIR__ . '/.local/LocalSettings.' . $dockerDb . '.php')){
	require_once __DIR__ . '/.local/LocalSettings.' . $dockerDb . '.php';	
}

These lines above will load LocalSettings files according to the name of the requested site, if that file exists.

1.3. Add per site configurationEdit

With the code setup, we can now add our various LocalSettings files (remember to replace <site-name> with the name of your site):

$ touch .local/LocalSettings.<site-name>.php

Continuing with our example, having our wikibase Client/Repo called default, and our Client Only wikibase called testwiki, we would end up with something like this:

mediawiki/
|- .local/
|  |- LocalSettings.default.php
|  |- LocalSettings.testwiki.php
|
|...
|
|- LocalSettings.php

With this configuration, we can place any shared extensions / skins in the main LocalSettings.php, and we will place wikibase Repo/Client specific configs in LocalSettings.default.php and Client Only specific configs in LocalSettings.testwiki.php. We can validate that the two sites load different extensions by visiting each site's Special:Version page and comparing between them.

Step 2: Introduce your wikis to one anotherEdit

Having two wiki with different config is great, but sometimes it might not be enough, especially when we deal with wikis that have to talk to each other. In our scenario, we would like our Client Only wiki (testwiki) to be able to access items on our Repo/Client wiki (default) and vice versa. For that, they need to be aware of each other through the sites table in their respective databases.

Important: Since in our use case we will be dealing with sitelinks, make sure to enable sitelinks on your Repo/Client wiki first.

Conveniently enough, mediawiki core provides us with a handy script to add sites to the sites table. To run it, we will open an interactive shell on the running docker instance, and execute the following:

$ mw-dev bash
root@<uid>:/var/www/mediawiki# php maintenance/addSite.php testwiki wikilocal --wiki=default --language=en --pagepath="http://testwiki.web.mw.localhost:8080/mediawiki/index.php/\$1" --filepath="http://testwiki.web.mw.localhost:8080/mediawiki/\$1"

The command above is a bit of an eyeful, so let's try to break it down:

The arguments passed into the script (by order) represent the added wiki's <globalid> and the wiki <group> to place it in. In our case we will be adding our new site entry under testwiki (to keep things nice and simple) and a new group called wikilocal.

The --wiki option denotes which database to add the site entry to. In our case we are adding testwiki to our default wiki's database. --lang determines which language our new wiki will be listed under when we create new sitelinks.

Most importantly, the --pagepath and --filepath both determine which patterns to use when preforming lookups for pages or resolving urls to load resources. More info can be found in the sites table manual.

To summarize, we can run this command for any site we want to add by replacing the tags <site-name> and <target-wiki>, where site-name is the wiki we would like to add and target-wiki is the wiki we want to add the site to:

root@<uid>:/var/www/mediawiki# php maintenance/addSite.php <site-name> wikilocal --wiki=<target-wiki> --language=en --pagepath="http://<site-name>.web.mw.localhost:8080/mediawiki/index.php/\$1" --filepath="http://<site-name>.web.mw.localhost:8080/mediawiki/\$1"


Problem #2: Client crashes horriblyEdit

If you have been following this tutorial naively, with relatively empty LocalSettings files, at this point whenever you try to edit any of the pages in the testwiki client, you would probably see something like this:

 
An unseemly crash

This error occurs due to the fact that the Client Only wikibase doesn't actually recognize a Repo wikibase, since we never actually defined one as such. There are some fairly hidden (as of the time of writing) configurations that must be added in order for the client wiki to be able to communicate with it's repo. Adding these to your client only config, can save some head scratching later (if you're a noob to wikibase like I am [was]):

// Add these after the initial client setup
$wgWBClientSettings['repoUrl'] = 'http://<repo-wiki>.web.mw.localhost:8080';
$wgWBClientSettings['repoScriptPath'] = '/mediawiki';
$wgWBClientSettings['repoArticlePath'] = '/mediawiki/index.php/$1';
$wgWBClientSettings['siteGlobalID'] = '<client-wiki>';
$wgWBClientSettings['repositories']['']['repoDatabase'] = '<repo-wiki>';
$wgWBClientSettings['repositories']['']['changesDatabase'] = '<repo-wiki>';

Therefore, in our example, it should look something like this:

// Add these after the initial client setup
$wgWBClientSettings['repoUrl'] = 'http://default.web.mw.localhost:8080';
$wgWBClientSettings['repoScriptPath'] = '/mediawiki';
$wgWBClientSettings['repoArticlePath'] = '/mediawiki/index.php/$1';
$wgWBClientSettings['siteGlobalID'] = 'testwiki';
$wgWBClientSettings['repositories']['']['repoDatabase'] = 'default';
$wgWBClientSettings['repositories']['']['changesDatabase'] = 'default';

Step 3: Get your wikis linkedEdit

Now that the site is added to the sites table, we should be able to create links to it from items in our default Repo/Client wiki. All we need to do is add the wikilocal group to our sites array. In LocalSettings.default.php we add the following:

// Site Links: https://www.mediawiki.org/wiki/Wikibase/Installation#Enable_Sitelinks
$wgWBRepoSettings['siteLinkGroups'] = [ 'wikilocal', /* Other sites from before */ ];

This will make the new wikilocal group appear in any item page in our Repo/Client wikibase. If we configured it properly we should even be able to select our client when adding a new sitelink, just by typing it's name and selecting an existing page.