Jonasfj.dk/Blog
A blog by Jonas Finnemann Jensen


September 13, 2020
Reviving a php4/mysql4 LAMP Application with docker
Filed under: Computer,English,Linux,School by jonasfj at 2:15 pm

Back in high school (HTX 2005-2008) I operated a custom MediaWiki application for collaborative note taking, tracking home work and occasional sharing of homework 🙈. In case you don’t know MediaWiki is the software behind wikipedia.org. At the time I was using a Danish hosting provider, and couldn’t get LaTeX integration working properly, so I ended up hacking MediaWiki to use mimetex. Similarly, I added a few extensions for calendar integration, raw HTML, etc. These hacks and extensions made upgrading MediaWiki challenging, hence, I never upgraded past MediaWiki 1.5.5 released in 2006.

It should not surprise anyone that the wiki was full of spam a few years later. Even though, write access was only granted to trusted users. Some bot must have been scanning the internet for MediaWiki installations with known vulnerabilities, and automatically exploited those vulnerabilities to post spam. Naturally, I ended up taking the wiki offline, being too busy to fix it.

Then earlier this year I decided that it was the time to revive my old wiki. But how do you revive an ancient php4 / mysql4 application? It’s probably possible to tweak it such that it works on newer versions of PHP and MySQL. But my database dumps from mysql4 didn’t import on mysql5 without hacks, and some of my extensions didn’t work with php5. So I decided to go looking for a way to install and run php4 and mysql4.

Initially, I went looking for a docker image or virtual machine with a php4 and mysql4 LAMP stack pre-configured. But I had no such luck, there was a few php4 docker images, but they were running mysql5. Then I found the End-Of-Life Debian images on hub.docker.com/r/debian/eol/. Using debian/eol:sarge it is easy to install php4 and mysql4 from the package manager, as illustrated in the Dockerfile below.

FROM debian/eol:sarge

ENV DEBIAN_FRONTEND noninteractive

# Install php4, mysql4, apache2, imagemagick, build-essential and phpmyadmin (for good measure)
RUN apt-get update -y \
  && apt-get install -y \
    mysql-server \
    mysql-client \
    php4 \
    apache2 \
    libapache2-mod-php4 \
    php4-mysql \
    imagemagick \
    build-essential \
    phpmyadmin

# Enable mod_rewrite
RUN a2enmod rewrite \
  && sed -i 's/AllowOverride None/AllowOverride all/' /etc/apache2/sites-available/default

# Launch apache2 and mysql when starting the container
ENTRYPOINT /bin/bash -c 'apache2 > /dev/null && mysqld > /dev/null & exec bash --login'

The Dockerfile above will create an image with a php4/mysql4 LAMP stack serving from /var/www/. For simple LAMP applications all that remains is to configure mysql users, restore database from SQL dump, and copy php files and resources into /var/www/. This can be done with a few commands as illustrated below.

# Setup mysql with empty root password
mysqladmin -u root password ''

# Create $DATABASE_USERNAME with $DATABASE_PASSWORD
echo "GRANT ALL PRIVILEGES ON *.* TO '$DATABASE_USERNAME'@'localhost' IDENTIFIED BY '$DATABASE_PASSWORD';" | mysql;

# Create $DATABASE_NAME and load contents from SQL dump.
echo "CREATE DATABASE $DATABASE_NAME; USE $DATABASE_NAME;" | cat - /src/database-dump.sql | mysql

# Copy php files and resources to /var/www
cp -r /src /var/www

From php4 your application can connect to localhost:socket with the $DATABASE_USERNAME and $DATABASE_PASSWORD created above. Obviously, one should never expose this Docker image to the internet (ie. deploy it to a server). Debian Sarge haven’t received security updates for years. But we can crawl the site and convert it to static files using wget. Simply run the LAMP app as a Docker container locally, find the IP of the Docker container, and run wget as follows:

wget \
  --no-clobber \
  --recursive \
  --user-agent='Mozilla/5.0 (X11; Linux i686; rv:10.0) Gecko/20100101 Firefox/10.0' \
  --page-requisites \
  --adjust-extension \
  --span-hosts \
  --convert-links \
  --restrict-file-names=windows,ascii \
  --trust-server-names \
  --domains "$DOCKER_CONTAINER_IP" \
  -e robots=off \
  --tries 1 \
  "http://$DOCKER_CONTAINER_IP/"

If your old LAMP application contains absolute links, one can temporarily tweak /etc/hosts to make the domain point to docker container. Also checkout the wget manual for more options, depending on our URL patterns --restrict-file-names=nocontrol might look better. To successfully render my old MediaWiki setup into static files I tweaked the theme to remove unnecessary links. But wget also has options to exclude certain directories for patterns. In my case the final result is visible at jopsen.dk/wiki, these are my high school notes (in Danish).

I had actually dreaded this project a bit, fearing that I would have to follow a lengthy install guide to setup a server on a slow virtual machine. But thanks to the amazing Debian EOL images for docker reviving and old php4 / mysql4 LAMP app was almost a breeze — who knew restarting apache could make you feel all nostalgic 😀