Mediawiki-Docker on Apple M1
2021-02-16 09:23:05 +0100 +0100
In a previous post I wrote about speeding up Docker for Mac by giving up on Docker for Mac (tl;dr SSH tunnels and PhpStorm’s deploy feature to work on a remote server).
There are aspects to that workflow that aren’t great, so I’ve spent some time working on a config for working locally with ARM images that overriode the images used in the default MediaWiki-Docker config.
Here’s where I ended up.
Override file
version: '3.7'
services:
mediawiki-web:
user: "root"
build: docker/apache/
mediawiki-jobrunner:
user: "root"
build: docker/php/
mediawiki:
working_dir: /var/www/html/w
user: "root"
build: docker/php/
volumes:
- ./:/var/www/html/w:cached
- ../localsettings:/localsettings
mariadb:
image: arm64v8/mariadb
ports:
- 3306:3306
volumes:
- mariadbdata:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: root
elasticsearch:
ports:
- "9200:9200"
- "9300:9300"
#image: docker.elastic.co/elasticsearch/elasticsearch-oss:7.10.2-arm64
image: docker.elastic.co/elasticsearch/elasticsearch-oss:6.8.14
volumes:
- esdata:/usr/share/elasticsearch/data
environment:
- discovery.type=single-node
- bootstrap.system_call_filter=false
redis:
image: arm64v8/redis
volumes:
mariadbdata:
driver: local
esdata:
driver: local
I’m using custom Dockerfiles for the web/php containers, which I’ll get to in a second. The main thing to note is that most images extend from arm64v8 variants of the official images, e.g. arm64v8/redis
instead of redis
.
While there is a arm64 version of ElasticSearch, it’s currently just for version 7 and CirrusSearch uses version 6 still. Note the bootstrap.system_call_filter=false
line which is needed to avoid startup errors on a host ARM system.
PHP Dockerfile
Pretty basic:
FROM arm64v8/php:7.3-fpm
ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/
RUN chmod +x /usr/local/bin/install-php-extensions && sync && \
install-php-extensions intl gd opcache
RUN docker-php-ext-install mbstring mysqli && docker-php-ext-enable mbstring mysqli opcache gd intl
RUN pecl install redis \
&& pecl install xdebug \
&& docker-php-ext-enable redis xdebug
RUN echo xdebug.client_host=host.docker.internal >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
RUN echo xdebug.mode=debug >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
RUN apt-get update && apt-get install -y default-mysql-client
In the future I’ll probably tune this so it matches what is in the releng/dev-images
repo.
Apache Dockerfile
Like the releng/dev-images
repo, I’m extending Debian Stretch to build this. In the official PHP Docker Hub images (https://hub.docker.com/_/php) I think there is a vanilla Apache image designed to work with php-fpm, but I couldn’t find the equivalent in the arm64v8 repo, so that’s why I’ve gone with Stretch as the base.
FROM arm64v8/debian:stretch
RUN apt-get update && apt-get install -y apache2 \
&& rm /var/www/html/index.html \
&& a2enmod proxy_fcgi \
&& a2enmod mpm_event \
&& a2enmod rewrite \
&& a2enmod http2 \
&& a2enmod cache
COPY 000-default.conf /etc/apache2/sites-available/000-default.conf
RUN echo "Listen 8080" > /etc/apache2/ports.conf
EXPOSE 8080
ENTRYPOINT ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]
And the conf file, which is basically the same as what is in releng/dev-images
:
<VirtualHost *:8080>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
<Directory /var/www/html>
Require all granted
</Directory>
<FilesMatch "\.php$">
SetHandler "proxy:fcgi://mediawiki:9000/"
</FilesMatch>
# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the loglevel for particular
# modules, e.g.
#LogLevel info ssl:warn
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
# For most configuration files from conf-available/, which are
# enabled or disabled at a global level, it is possible to
# include a line for only one particular virtual host. For example the
# following line enables the CGI configuration for this host only
# after it has been globally disabled with "a2disconf".
#Include conf-available/serve-cgi-bin.conf
## 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>
Benchmarks
With the arm64v8
images:
ab -c 4 -n 100 http://localhost:8080/wiki/Special:BlankPage
This is ApacheBench, Version 2.3 <$Revision: 1879490 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking localhost (be patient).....done
Server Software: Apache/2.4.25
Server Hostname: localhost
Server Port: 8080
Document Path: /wiki/Special:BlankPage
Document Length: 31525 bytes
Concurrency Level: 4
Time taken for tests: 21.235 seconds
Complete requests: 100
Failed requests: 99
(Connect: 0, Receive: 0, Length: 99, Exceptions: 0)
Total transferred: 3142418 bytes
HTML transferred: 3097218 bytes
Requests per second: 4.71 [#/sec] (mean)
Time per request: 849.403 [ms] (mean)
Time per request: 212.351 [ms] (mean, across all concurrent requests)
Transfer rate: 144.51 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 0
Processing: 323 832 731.4 788 5743
Waiting: 323 832 731.5 788 5743
Total: 323 833 731.4 788 5743
Percentage of the requests served within a certain time (ms)
50% 788
66% 838
75% 860
80% 872
90% 967
95% 1078
98% 5714
99% 5743
100% 5743 (longest request)
With the amd64 default images:
ab -c 4 -n 100 http://localhost:8080/wiki/Special:BlankPage
This is ApacheBench, Version 2.3 <$Revision: 1879490 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking localhost (be patient).....done
Server Software: Apache/2.4.25
Server Hostname: localhost
Server Port: 8080
Document Path: /wiki/Special:BlankPage
Document Length: 16792 bytes
Concurrency Level: 4
Time taken for tests: 44.441 seconds
Complete requests: 100
Failed requests: 98
(Connect: 0, Receive: 0, Length: 98, Exceptions: 0)
Total transferred: 1702201 bytes
HTML transferred: 1657001 bytes
Requests per second: 2.25 [#/sec] (mean)
Time per request: 1777.636 [ms] (mean)
Time per request: 444.409 [ms] (mean, across all concurrent requests)
Transfer rate: 37.40 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 0
Processing: 862 1729 763.5 1724 7215
Waiting: 862 1728 763.5 1724 7215
Total: 862 1729 763.5 1724 7215
Percentage of the requests served within a certain time (ms)
50% 1724
66% 1761
75% 1790
80% 1800
90% 1862
95% 1875
98% 6201
99% 7215
100% 7215 (longest request
Conclusion
p50 of 788 ms / p95 of 1.07 seconds is good enough for now, but would be great to get this lower. Still, it’s a huge improvement over p50 of 1724ms / p95 of 1.8 seconds.