Migrating WordPress BLOG to docker

 This blog is powered by WordPress and has been running natively using LAMP on my Ubuntu-server since 2014, it has served me well with a few caveat, mainly related the fact that the MySQL database and the WEB-server is shared with other uses on this system.

During these 7 years Ubuntu has gone from version 12.04 to 20.4, the hardware has been upgraded once, from a desktop-grade PC to a server, while a ZFS mirror has made disk-crashes a non-issue.

So it is time to migrate to a container based setup.

Install Docker and docker-compose

Read https://docs.docker.com/engine/install/ubuntu/ or get and execute https://gist.github.com/wdullaer/f1af16bd7e970389bad3 which is a shell-script that installs the latest version of docker and docker-compose, here is the script I executed

# Ask for the user password
# Script only works if sudo caches the password for a few minutes
sudo true
# Install kernel extra's to enable docker aufs support
# sudo apt-get -y install linux-image-extra-$(uname -r)
# Add Docker PPA and install latest version
# sudo apt-key adv –keyserver hkp://keyserver.ubuntu.com:80 –recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9
# sudo sh -c "echo deb https://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list"
# sudo apt-get update
# sudo apt-get install lxc-docker -y
# Alternatively you can use the official docker install script
wget -qO- https://get.docker.com/ | sh
# Install docker-compose
COMPOSE_VERSION=`git ls-remote https://github.com/docker/compose | grep refs/tags | grep -oE "[0-9]+\.[0-9][0-9]+\.[0-9]+$" | sort –version-sort | tail -n 1`
sudo sh -c "curl -L https://github.com/docker/compose/releases/download/${COMPOSE_VERSION}/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose"
sudo chmod +x /usr/local/bin/docker-compose
sudo sh -c "curl -L https://raw.githubusercontent.com/docker/compose/${COMPOSE_VERSION}/contrib/completion/bash/docker-compose > /etc/bash_completion.d/docker-compose"
# Install docker-cleanup command
cd /tmp
git clone https://gist.github.com/76b450a0c986e576e98b.git
cd 76b450a0c986e576e98b
sudo mv docker-cleanup /usr/local/bin/docker-cleanup
sudo chmod +x /usr/local/bin/docker-cleanup
view raw install.sh hosted with ❤ by GitHub

This should result in a working Docker environment, For convenience let us add ourselves to the docker group, so we can execute docker commands without sudo

sudo usermod -aG docker $USER

Install WordPress in Docker

For the installation of WordPress, WEB-server and SQL-server I followed: https://nickvanhoof.com/docker-compose-wordpress/

This should gives us a virgin WordPress installation. I have tweaked docker-compose.yml to my needs, I replaced mysql with mariadb, put in some very secret passwords, and made it start automagically. Since I plan on running more instances, I have exposed the ports for this blog at 13306,10080,10081, for the next instance I add 10000 to the port number.

version: '3.7'

volumes:
  wp-data:
networks:
  wp-back:

services:

  db:
    restart: always
    image: mariadb
    volumes:
      - ./db_data:/var/lib/mysql
    environment:
       MYSQL_ROOT_PASSWORD: rootPassword
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wp-user
       MYSQL_PASSWORD: wp-pass
    ports:
      - 13306:3306
    networks:
      - wp-back

  phpmyadmin:
    restart: always
    depends_on:
      - db
    image: phpmyadmin/phpmyadmin
    environment:
      PMA_HOST: db
      MYSQL_USER: wp-user
      MYSQL_PASSWORD: wp-pass
      MYSQL_ROOT_PASSWORD: rootPassword
    ports:
      - 10081:80
    networks:
      - wp-back

  wordpress:
    restart: always
    depends_on:
      - db
    image: wordpress:latest
    ports:
      - 10080:80
      - 10443:443
    environment:
       WORDPRESS_DB_HOST: db
       WORDPRESS_DB_USER: wp-user
       WORDPRESS_DB_PASSWORD: wp-pass
    volumes:
      - ./wp_data:/var/www/html
    container_name: wordpress-site
    networks:
      - wp-back

Migrate the current WordPress site to the docker based WordPress

Now we just need to migrate the  current WordPress blog for http://storepeter.dk to the new docker based WordPress . A WordPress blog is made up of two parts, a file-system-tree and a sql-tree,.  Again we are lucky someone has made a plugin which can import and export a complete blog.

But there is a slight problem, the free version only handles up to 512Mb, and my WordPress blog fills more than 1Gb,  you can buy an unlimited version,  Or you could get an older version of this tool, where the limit can be modified, check Removing the 512MB size limit on All-in-One WP Migration Plugin. Of course you could copy it manually using rsync an mysqldump.

Running more than a single BLOG

In my original LAMP setup i used VirtualHost in the Apache configuration-file to serve multiple blogs, here is an excerpt of /etc/apache2/sites-enabled/wordpress.conf 

<VirtualHost *:80>
    ServerName peter.lorenzen.us
    UseCanonicalName Off
    VirtualDocumentRoot /var/www/peter.lorenzen.us
    CustomLog /var/log/apache2/peter-access.log combined
    Options All
    <Directory /var/www/peter.lorenzen.us>
        AllowOverride All
    </Directory>
</VirtualHost>

<VirtualHost *:80>
    ServerName deborah.lorenzen.us
    UseCanonicalName Off
    VirtualDocumentRoot /var/www/deborah.lorenzen.us
    CustomLog /var/log/apache2/deborah-access.log combined
    Options All
    <Directory /var/www/deborah.lorenzen.us>
        AllowOverride All
    </Directory>
</VirtualHost>

Now I would like to have seperate containers per blog, hence a demultiplexer of some kind is needed to send the request to the relevant WordPress-Docker instance.

The simplest way to achieve this is just to change the Apache configuration to use mod_proxy, and the VirtualHost definition would look like this

<VirtualHost *:80>
    ServerName peter.lorenzen.us
    ServerAdmin peter@lorenzen.us
    ProxyRequests off
    ProxyPreserveHost On
    LogLevel error
    # debug, info, notice, warn, error, crit, alert, emerg.
    <Location />
        ProxyPass http://localhost:10080/
        ProxyPassReverse http://localhost:10080/
        Order allow,deny
        Allow from all
    </Location>
</VirtualHost>

Thats it  – the BLOG should now be running inside a Docker container.

Was the containerization worth it 

It took me a few days to get this working, having never used docker before,  The real challenge  will be when things do not work,  Docker has introduced new layers so it might be hard to figure out what is wrong.  The old system just had one Web-server and one SQL-server which handled all the blogs on my system, and  they also handled other workload irrelevant to the blogs.

Performance wise I am not too worried: a http request will first be served by Apache (reverse proxy) which will send the request to the relevant WEB- server running inside Docker,  That Web-server will run some PHP code  from the file system which will aquire some information from the Database server in another Docker-container. Compared to the original LAMP based system, there will be a WEB/SQL-server per BLOG and there will be an extra delay going through the reverse proxy.

A great advantage is that all the files and the database are now in one spot, and I can just clone the directory /y/DOCKER/peter.lorenzen.us to a different host, and start a new instance there using “docker-compose up -d” hence trying out new stuff away from the production server is a breeze.

Another great advantage is that: if the system administrator (that’s me) is fooling around with f,ex.  the database-server and makes a mistake, the BLOG-servers will not be affected.

Let us see how I like this in another 7 year, that is how long the previous LAMP system worked without any flaws, and very little downtime.

This entry was posted in internet, Linux, Web, Wordpress. Bookmark the permalink.