The making of WordPress Docker Image
The next era of portability is called Docker. IMHO Old and new application should be developed keeping in mind the separation between application and data, and in my coaching experience WordPress is one of the application that must take this way. The building of a container image requires these points:
- keep in mind objective requirements of containers that must delivered by this image
- choose a good starting image
- define actions that must executed in 2 moments:
- In the container creation
- In the container execution
- define ports and volumes (this are the hands that will link container to the “external” word.
The container creations
Initial declarations:
1 2 3 4 5 6 7 8 9 10 11 |
FROM ubuntu:trusty ENV WP_LOCALE="it_IT" ENV DB_NAME="wordpress" ENV DB_ROOT_USER="root" ENV DB_ROOT_PWD="" ENV WP_IPFDQN="127.0.0.1" ENV WP_TITLE="wordpress" ENV WP_ADMIN_USER="admin" ENV WP_ADMIN_PWD="admin" ENV WP_ADMIN_EMAIL=<a href="mailto:admin@email.tld">admin@email.tld</a> |
Now it’s time to install the environment
1 |
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get -yq install curl apache2 libapache2-mod-php5 php5-mysql php5-gd php5-curl php5-mcrypt mysql-server-5.6 mysql-client-5.6 php-pear php-apc php5-sqlite git vim && rm -rf /var/lib/apt/lists/* && curl -sS <a href="https://getcomposer.org/installer">https://getcomposer.org/installer</a> | php -- --install-dir=/usr/local/bin --filename=composer |
Then define environment modules and add custom files (like the default apache configurations):
1 2 3 4 5 6 7 8 9 10 |
RUN echo "ServerName localhost" >> /etc/apache2/apache2.conf && \ sed -i "s/variables_order.*/variables_order = \"EGPCS\"/g" /etc/php5/apache2/php.ini RUN sed -i -e 's/127.0.0.1/0.0.0.0/g' /etc/mysql/my.cnf RUN php5enmod mcrypt RUN usermod -u 33 www-data ADD 000-default.conf /etc/apache2/sites-available/ RUN a2enmod rewrite |
Finally install wordpress environment with wpcli and the last available version:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
RUN cd /opt/ && curl -O <a href="https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar">https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar</a> && chmod +x wp-cli.phar && mv wp-cli.phar /usr/local/bin/wp RUN mkdir /var/www/html-wp RUN chown www-data /var/www/html-wp RUN cd /var/www/html-wp && \ sudo -u www-data -s -- /usr/local/bin/wp core download --locale="$WP_LOCALE" RUN mkdir /var/lib/mysql-old RUN cp -a /var/lib/mysql/* /var/lib/mysql-old/ ADD run_wordpress.sh / RUN chmod 755 /*.sh RUN mkdir /var/www/backup |
The image code ends with volume, ports definitions and the code to run at container startup:
1 2 3 4 5 6 7 8 |
VOLUME ["/var/www/html/", "/var/log/apache2","/var/lib/mysql/","/var/www/backup"] WORKDIR /var/www/html EXPOSE 80 EXPOSE 443 CMD ["/run_wordpress.sh"] |
Run on boot: wordpress.sh
The script on boot is doing this things:
- Check if wordpress installation is already present, otherwise it begins the auto-installation with wpcli
- Check if duplicator restore is present in the /var/www/backup dir, then if no wordpress installation will present, it simply move duplicator files into web root (/var/www/html)
- Executes mysql and apache (this is always done to run wordpress install or excecute powercli)
This is the code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
#!/bin/bash # Vars FILE=/var/www/html/wp-content DB=/var/lib/mysql/mysql/db.frm DBWP=/var/lib/mysql/wordpress/wp_users.frm DIR_BCK=/var/www/backup WP_INST=false WP_RESTORE=false # Remove crashed container run pid rm /var/run/apache2/apache2.pid # Check DB then copy db files if [ -a $DB ]; then echo "DB exists" else echo "Copy DB" cp -a /var/lib/mysql-old/* /var/lib/mysql/ fi # Check wp is installed if [ -a $DBWP ]; then echo "DB wp exists" else echo "Must install wp" WP_INST=true fi ## MySQL start exec /etc/init.d/mysql start & # Wait for up system sleep 10 # Check for file if [ -f $FILE ]; then echo "WP Files present" else # Check for backup if [ "$(ls -A $DIR_BCK)" ]; then echo "Try restoring backup" cp -a /var/www/backup/* /var/www/html/ chown www-data /var/www/html/. WP_RESTORE=true WP_INST=false else echo "Installing wp" #cp -a /var/www/html-wp/* /var/www/html/ rm /var/www/html/index.html chown www-data /var/www/html/. fi fi if [ $WP_RESTORE == "true" ]; then echo "Executing restore create database" mysql -u $DB_ROOT_USER -e "create database $DB_NAME;" echo "Run installer via web" elif [ $WP_INST == "true" ]; then sudo -u www-data -s -- /usr/local/bin/wp core download --locale="$WP_LOCALE" mysql -u $DB_ROOT_USER -e "create database $DB_NAME;" sudo -u www-data -s -- /usr/local/bin/wp core config --dbname=$DB_NAME --dbuser=$DB_ROOT_USER sudo -u www-data -s -- /usr/local/bin/wp core install \ --url=<a href="http://$WP_IPFDQN/">http://$WP_IPFDQN/</a> \ --title=$WP_TITLE \ --admin_user=$WP_ADMIN_USER \ --admin_password=$WP_ADMIN_PWD \ --admin_email=$WP_ADMIN_EMAIL fi if [ -a /var/www/html/index.html ]; then rm /var/www/html/index.html fi if [ $WP_RESTORE == "false" ]; then if [ -a /var/www/html/installer.php ]; then rm /var/www/html/*.zip fi fi # Apache source /etc/apache2/envvars tail -F /var/log/apache2/* & exec apache2 -D FOREGROUND |
Usage
You could run this container specifying these parameters:
Param | default value | Note |
WP_IPFDQN | 127.0.0.1 | You must change this value with an domain name |
WP_TITLE | wordpress | Of course! change it with your app name |
WP_ADMIN_USER | admin | |
WP_ADMIN_PWD | admin | No extra comment! Must change it! |
WP_ADMIN_EMAIL | admin@email.tld | Change it with your own mail |
Simply create with
1 |
docker run –v <local_dir>:/var/www/backup linoproject/wordpress:latest |
if you plan to restore from backup… or
1 |
docker run –v <local_dir>:/var/www/html/ –v <mysql_local_dir>:/var/ib/mysql/ –e “WP_IPFDQN=<site.domain.tld>” –e “WP_TITLE=<my site name>” –e “WP_ADMIN_PWD=<my_secret_pwd>” linorpoject/wordpress:latest |
to create a wp instance from scratch