Homebrew PHP/Apache/MySQL/Redis/Elastic for MediaWiki

2021-01-21 21:58:22 +0100 +0100

Here’s how I set up MediaWiki for local development on an Apple M1. Everything should apply to Intel based Macs too.

Install Homebrew

https://brew.sh/ is the starting point. The installer will know if you’re on arm64 or i386 and install Homebrew accordingly.

Install PHP

Default for brew install php is to use PHP 8 which isn’t yet fully supported for MediaWiki and more importantly not what we use in production at Wikimedia (PHP 7.2 at the moment).

If on arm64: do brew install php@7.4 since earlier versions fail to install / aren’t available. If on Intel architecture, do brew install php@7.2.

Make sure you follow the instructions at the end of the output (do brew info php@7.4 to see them again) for adding the php version installed by Homebrew to your path.

Start the php-fpm service with brew services start php@7.4.

Install extensions

When you’re sure your new php is in the path of your terminal (php -v should show PHP 7.4.14) then you can install extensions like XDebug and Redis. Do this with pecl install xdebug and pecl install redis.

Setup Apache

Next up, install Apache. brew install httpd will do the trick, and we want to start the background service so follow that up with brew services start httpd.

Now, we need to tell Apache which directory to serve. For my setup I am only serving a single site, so I have not made use of sites-available, I am just editing httpd.conf. On ARM architecture this will be at /opt/homebrew/etc/httpd/httpd.conf and for Intel it will be /usr/local/etc/httpd/httpd.conf.

At the bottom of my httpd.conf file I’ve added:

# Note that on an Intel Mac, the path won't be /opt/homebrew but rather /usr/local/etc...
LoadModule php7_module /opt/homebrew/opt/php@7.4/lib/httpd/modules/libphp7.so
LoadModule rewrite_module lib/httpd/modules/mod_rewrite.so

<VirtualHost *:8080>
  ServerAdmin webmaster@localhost
  Protocols h2 http/1.1
  DocumentRoot /Users/kostajh/src/mediawiki
  <Directory /Users/kostajh/src/mediawiki>
    Require all granted
  </Directory>


<FilesMatch \.php$>
    SetHandler application/x-httpd-php
</FilesMatch>
  ErrorLog /tmp/error.log
  CustomLog /tmp/access.log combined

  # Support /wiki style URLs
  RewriteEngine On
  RewriteRule ^/?wiki(/.*)?$ %{DOCUMENT_ROOT}/w/index.php [L]
  RewriteRule ^/?$ %{DOCUMENT_ROOT}/w/index.php [L]

  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d
  RewriteRule ^/?images/thumb/[0-9a-f]/[0-9a-f][0-9a-f]/([^/]+)/([0-9]+)px-.*$ %{DOCUMENT_ROOT}/w/thumb.php?f=$1&width=$2 [L,QSA,B]

  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d
  RewriteRule ^/?images/thumb/archive/[0-9a-f]/[0-9a-f][0-9a-f]/([^/]+)/([0-9]+)px-.*$ %{DOCUMENT_ROOT}/w/thumb.php?f=$1&width=$2&archived=1 [L,QSA,B]

  # VisualEditor support. T262392
  AllowEncodedSlashes NoDecode

</VirtualHost>

If you look closely you’ll see most of this is lifted from the releng/dev-images repo ;)

The important thing is to make sure DocumentRoot and Directory point to an empty directory called mediawiki. The next most important thing is that you clone MediaWiki core inside that directory and rename it to w. This is the desired name for short URL configuration per the manual.

Finally make sure the LoadModule directive points to the correct path for libphp7.so.

Then your LocalSettings.php should also have:

$wgScriptPath = "/w";
$wgArticlePath = "/wiki/$1";

MySQL

Here you can choose brew install mariadb or brew install mysql, I can’t remember which one works for ARM architecture at the moment but it’s only one of them.

Redis

brew install redis will take care of this for you. Then in your LocalSettings.php you can have config like:

$wgObjectCaches['redis'] = [
	'class' => 'RedisBagOStuff',
	'servers'=> [ 'localhost:6379' ],
];
$wgJobTypeConf['default'] = [
	'class' => 'JobQueueRedis',
	'redisServer' => 'localhost:6379',
	'redisConfig' => [],
	'claimTTL' => 3600,
	'daemonized' => true
];
$wgMainCacheType = 'redis';
$wgSessionCacheType = 'redis';
$wgMainStash = 'redis';

However be warned that on ARM architectures, setting $wgMainCacheType = 'redis' results in php-fpm segfaults to probably best to comment that particular line for now.

ElasticSearch

Here, you probably want to avoid a Homebrew installation and make use of Docker for Mac, because Wikimedia has some plugins for Elastic Search and AFAIK those aren’t trivial to install on a Homebrew install.

On ARM architecture, you’re out of luck with because the image fails to run (apparently not so much of an issue on ElasticSearch 7 but Wikimedia uses version 6). If on an Intel Mac, though, you can do docker run -d -v elasticdata:/usr/share/elasticsearch/data -e "discovery.type=single-node" -p 9200:9200 -p 9300:9300 docker-registry.wikimedia.org/dev/stretch-elasticsearch:0.0.1. Then in LocalSettings.php you tell it to connect to Elastic Search on localhost with $wgCirrusSearchServers = [ 'localhost' ];.

If on ARM, you can run the elasticsearch-oss image from Docker Hub, it just won’t have the (optional) Wikimedia plugins:

docker run -v elasticdata:/usr/share/elasticsearch/data -e "discovery.type=single-node" -e "bootstrap.system_call_filter=false" -p 9200:9200 -p 9300:9300 docker.elastic.co/elasticsearch/elasticsearch-oss:6.8.14