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
- 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.
- Starting from that file above, change the database image from mysql to mariadb.
- 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. - 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/ - 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 - 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.
- 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
- This set of steps is only needed if you are restoring from backup. Otherwise, the setup process for Mediawiki above should be enough.
- 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.
- 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 - Start a shell inside the docker container
docker exec -it mw-database-1 bash - 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 - 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
- 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!
- [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.
- [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.
- [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: - [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
- Since we have mapped the images to ~/code/mw/images, we just copy over all the images to that directory, and we are done.
- 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
- 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 - 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 - [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
- 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 - Copy this over to the docker container
docker cp php.ini mw-mediawiki-1:/usr/local/etc/php - Restart the docker container
docker compose restart - 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
- One advantage of using docker is that updating the mediawiki install is very easy. Just run
docker compose pull
docker compose up -d - 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
Post a Comment