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
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://peter.lorenzen.us 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 firstname.lastname@example.org 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.