Running Mediawiki in a Docker container, and restoring from backup

 Background

A wiki for a game I play and that I contributed to went down a few weeks ago due to suspected DNS issues. The person who had registered the DNS wasn't able to (or was unwilling to) respond, so we felt as if a lot of our work was lost. However, a few people still had access to the hosting environment of the wiki, and I was able to take a backup of the entire home directory, which included some fairly recent database backups.

Aside:

Renewing a domain immediately after it has expired is quite expensive. Registrars charge an arm and a leg for missing your auto-renew, so it is good practice to not let your domains expire.

The problem statement

I decided to step in and get the wiki up and running again. It had to be on a different domain, since the original domain was -- for all practical purposes -- gone. I decided on the following objectives:
  • Register a reasonable domain for not too much money
  • Run Mediawiki in a docker container so that we can easily move servers
  • Restore the data from backup
Now, running from a docker container seemed like a good idea to me in case I needed to move servers, or move it to my other server I use for my other sites. It seemed like it will prevent unnecessary entanglements. Mediawiki folks are slightly unhappy with this image ("it does not fulfill all of the roles and capabilities that MediaWiki has to offer"), but it seemed to work fine for me.

I began experimenting on a local VM, and once I figured out that it works, I created a Virtual Private Server with Hetzner and began deploying it. Here, I will walk you through the creation steps, with optional steps marked by a [backup] marker so you know which steps are for restoring from backup.

Steps to get Mediawiki running in Docker

Step 1: Grab a reasonable docker compose YAML

  1. I started with a YAML file for docker compose that I got from the internet, but the official one is by Mediawiki, and that is very similar to what I ended up with (my starting point was this one). I ended up creating a directory ~/code/mw and storing the docker compose YAML file there.
  2. Starting from that file above, change the database image from mysql to mariadb.
  3. Mediawiki stores its images in the directory /var/www/html/images The official docker file maps this to a docker volume, but we map it instead to a local directory so that we can handle backups more easily. So we change the line
    images:/var/www/html/images
    to
    /home/$USER/code/mw/images:/var/www/html/images
    Note: replace $USER above with the actual username you have on linux.
  4. We will be running a few extensions in addition to the pre-packaged extensions in Mediawiki. For those, we create an extensions directory, and map that as well
    /home/$USER/code/mw/extensions/:/var/www/ext/
  5. Docker runs mediawiki using the linux username www-data. The directories above need to be accessible to this user. To do this, run
    sudo chgrp -R www-data /home/$USER/code/mw/images
    sudo chmod -R 775 /home/$USER/code/mw/images
    sudo chgrp -R www-data /home/$USER/code/mw/extensions
    sudo chmod -R 775 /home/$USER/code/mw/extensions
  6. Also change the port to something else if you use some other server to reverse-proxy mediawiki. Change the line 80:80 to 8080:80, for example, if you want to use port 8080.
  7. At this point, you should be ready to test your docker setup, and you can execute
    docker compose up -d
    to check if everything is working. Try the site out, and go through the setup process, as guided by the Mediawiki interface. Note: the setup process will ask you for the database hostname, that should be just 'database'. Don't try to use 'localhost', that doesn't work.

Step 2: [Backup] restore the database

  1. This set of steps is only needed if you are restoring from backup. Otherwise, the setup process for Mediawiki above should be enough.
  2. Your database backup will be in the form of a .sql file, you may have to extract it from a compressed archive if needed. Copy it over to your server.
  3. Because we are using docker, we need to copy over this .sql file inside the docker before we can restore it. Assuming the name of your database docker instance is mw-database-1 (you can run docker ps to see what it actually is), copy the file over like so:
    docker cp ./backup.sql mw-database-1:/var/local/backup.sql
  4. Start a shell inside the docker container
    docker exec -it mw-database-1 bash
  5. Run this to restore from backup (Note: the variables will be automatically substituted, because they are present in the docker compose file)
    mariadb -u $MYSQL_USER -p$MYSQL_PASSWORD $MYSQL_DATABASE <  /var/local/backup.sql
  6. To confirm that this worked, you can run
    mariadb -u $MYSQL_USER -p$MYSQL_PASSWORD $MYSQL_DATABASE
    and then run various queries, such as
    SHOW TABLES;
    SELECT COUNT(*) FROM <some table name, like *_content>;

Step 3: LocalSettings.php

  1. If you are not restoring from backup, then at the end of your wiki setup, you would have downloaded a LocalSettings.php file. Copy it over to your server, at ~/code/mw, and then uncomment the line in docker compose file that maps this LocalSettings.php. Run docker compose up -d to update the server, and you're done!
  2. [Backup] If you are restoring from a backup, then find the LocalSettings.php from your previous install, and copy it over to the server. At this point, it is worth using Visual Studio Code's remote extensions to edit the file directly on the server, because this typically takes some iterating. Uncomment the entry in docker compose, and try to access the server. You will probably find a bunch of errors.
  3. [Backup] If you are getting an error about extensions, we will get to those shortly. Comment out all the $wfLoadExtension calls for now, and try the site again.
  4. [Backup] If you are getting an error about /tmp files, or lockfiles, then look in your LocalSettings for a line with $wgTmpDirectory. We need to map this directory to a volume in docker. In the docker compose file, add a line under the volumes section of the mediawiki container to say something like this:
    wikitmp:/tmp/tmp_6tgfrhys
    where /tmp/tmp_6tgfrhys is the directory specified by $wgTmpDirectory
    Then at the bottom of the docker compose file, add the volume itself as a default docker volume:
    volumes:
      wikitmp:

  5. [Backup] This newly created volume needs to be attached to mediawiki, and then it needs the right permissions. Attaching is accomplished simply by asking docker compose to restart the container:
    docker compose up -d
    and to get the right permissions, we go inside the docker and chmod it:
    docker exec -it mw-mediawiki-1 bash
    chown www-data -R /tmp/tmp_6tgfrhys

Step 4: [Backup] Restore the images

  1. Since we have mapped the images to ~/code/mw/images, we just copy over all the images to that directory, and we are done.
  2. Rerun the permissions command again, in case the copying did not respect the permissions of the directory
    sudo chgrp -R www-data /home/$USER/code/mw/images
    sudo chmod -R 775 /home/$USER/code/mw/images

Step 5: Extensions

  1. Notice that we have created a directory for extensions under ~/code/mw/extensions. We can install all extensions there. One nifty way is to grab them straight from git. For example, for the TemplateData extensions, one can run this
    git clone --depth=1 -b REL1_42 \
     https://gerrit.wikimedia.org/r/mediawiki/extensions/TemplateData

    Note the specific branch we are pulling. We have to match the release of Mediawiki we are running to the branch, otherwise the extension will not work. The advantage of doing this is that we can simply run git pull origin REL1_42 to update the extensions
  2. Now we can add the extensions to LocalSettings.php. Note that we have to specify the path to the extensions json file, since we are loading it from a non-standard location, as mapped in our docker compose file. That is, we need to write 
    $wfLoadExtension( 'TemplateData' , '/var/www/ext/TemplateData/extension.json');
    where /var/www/ext is the path mapped in our docker compose
  3. [Backup] if restoring from backup, now is the time to download all the extensions mentioned in the LocalSettings file one by one, and uncommenting the lines one by one. Remember to change the $wfLoadExtension call to add the path as described above. Note: if you are getting an error about a version mismatch, check if you downloaded the right branch of the extension in the git command above, or manually download the files and put it in the extensions folder.

Step 6: PHP settings

  1. The default settings of php only upload 2MB uploads, and this is annoying for modern systems. Mediawiki default docker container does not change this. Create a php.ini file in ~/code/mw and put the following text in it, adjusting as needed
    [PHP]
    ; Maximum allowed size for uploaded files.
    ; http://php.net/upload-max-filesize
    upload_max_filesize = 100M
    ; Maximum size of POST data that PHP will accept.
    ; Its value may be 0 to disable the limit. It is ignored if POST data reading
    ; is disabled through enable_post_data_reading.
    ; http://php.net/post-max-size
    post_max_size = 100M
  2. Copy this over to the docker container
    docker cp php.ini mw-mediawiki-1:/usr/local/etc/php
  3. Restart the docker container
    docker compose restart
  4. Note: Because we did a one-time copy of this file, it will need to be copied over every time the docker container is updated or recreated. Consider putting it in a docker volume to avoid this.

Step 7: Learn how to update the install

  1. One advantage of using docker is that updating the mediawiki install is very easy. Just run
    docker compose pull
    docker compose up -d
  2. If you have customized the php.ini file above, also run the following commands
    docker cp php.ini mw-mediawiki-1:/usr/local/etc/php
    docker compose restart
That's it! you should have a server up and running! It's a good idea to have a reverse proxy like nginx in front of the server, and you should also consider setting up a CDN for it, but you have the basics up now.

Comments

Popular posts from this blog

Windows Task Manager is lying to you, and I don't know how to make it stop

Laptop Surprises: Lenovo Yoga Slim 7i

Trouble installing KB2881553