Dockerizing Wordpress in a multi-container architecture
Overview
This document explains how to build a multi-container docker environment that presents a blank Wordpress install to the local network. The project will be given the random name Bilbo to make it obvious when an object is related to this example. This document has additional features as well:
- How to install Wordpress to operate behind a reverse proxy (apache shown)
- How to configure Wordpress to get downloads through a corporate proxy
- How to build a simple Wordpress docker container with persistent storage
Building the environment
Docker Compose can be used to build multi-container architecture easily.
Assembling the files
Make a work directory.
mkdir ~/bilbo
cd ~/bilbo
docker-compose.yml
cat <<EOF > docker-compose.yml
version: '2'
services:
db:
image: mariadb:latest
volumes:
- "/var/bilbo/db:/var/lib/mysql"
restart: always
environment:
MYSQL_ROOT_PASSWORD: wordpress
MYSQL_DATABASE: bilbo
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wpmod:
depends_on:
- db
#image: wordpress:latest
build:
context: .
dockerfile: Dockerfile
links:
- db
ports:
- "8000:80"
restart: always
volumes:
- "/var/bilbo/www:/var/www/html"
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_PASSWORD: wordpress
http_proxy: http://proxy.example.com:8080/
https_proxy: http://proxy.example.com:8080/
WP_HOME: http://kim.example.com/bilbo
WP_SITEURL: http://kim.example.com/bilbo
EOF
Observe that the proxy commands will allow Wordpress to download updates if the docker host is authenticated to the corporate proxy.
Dockerfile
cat <<EOF > Dockerfile
FROM wordpress:latest
MAINTAINER bgstack15@gmail.com
COPY entrymod.sh /entrymod.sh
RUN chmod +x /entrymod.sh
CMD ["/entrymod.sh","apache2","-DFOREGROUND"]
EOF
Entrymod.sh
This script wraps around the normal docker wordpress image entrypoint.sh file. It waits for the wp-config file to exist and then updates it with the right information provided in the docker-compose file. Basically it dynamically hard-codes the wordpress base URLs.
cat <<'EOFENTRYMOD' > entrymod.sh
#!/bin/bash
# File: entrymod.sh
# Purpose: Adds a few key elements to wp-config.php
# History 2016-06-20 changed to make entrymod the entry point and it just points to entrypoint.sh at the end
# Reference: https://wordpress.org/support/topic/wordpress-behind-reverse-proxy-1
infile1=/var/www/html/wp-config.php
tmpfile1=/tmp/295816928f7597.tmp
tmpfile2=/tmp/295816928f7598.tmp
WP_BLOGDIR=$( echo "${WP_HOME}" | sed 's!https\?://[^/]*!!;' )
function dotask {
rm -rf ${tmpfile1} ${tmpfile2} >/dev/null 2>&1
{
sed -n -e '1,/.*define.*DB_NAME.*/p;' ${infile1}
echo "# BEGIN ADDITIONS"
[[ -n "${WP_HOME}" ]] && echo "define('WP_HOME','${WP_HOME}');"
[[ -n "${WP_SITEURL}" ]] && echo "define('WP_SITEURL','${WP_SITEURL}');"
[[ -n "${WP_BLOGDIR}" ]] && {
echo "\$_SERVER['REQUEST_URI'] = '${WP_BLOGDIR}' . \$_SERVER['REQUEST_URI'];"
echo "\$_SERVER['SCRIPT_NAME'] = '${WP_BLOGDIR}' . \$_SERVER['SCRIPT_NAME'];"
#echo "\$_SERVER['PHP_SELF'] = '${WP_BLOGDIR}' . $_SERVER['PHP_SELF'];"
}
cat <<'EOF'
$_SERVER['HTTP_HOST'] = $_SERVER['HTTP_X_FORWARDED_HOST'];
$_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
# END ADDITIONS
EOF
tac ${infile1} | sed -n -e '1,/^define.*DB_NAME.*\|^\# END ADDITIONS/{/^define.*DB_NAME.*\|^\# END ADDITIONS/!p;}' | tac
} > ${tmpfile1}
chmod 0644 ${tmpfile1}
mv ${tmpfile1} ${infile1} >/dev/null 2>&1
}
{ while [[ ! -f ${infile1} ]]; do echo "waiting for ${infile1} to exist. Sleeping 3." && sleep 3; done; dotask;} &
exec /entrypoint.sh "$@"
EOFENTRYMOD
I learned that here-documents can employ variable names without being parsed by bash if you put the end string in quotes, as shown in this script file. Reference: Weblink 5
Running the wordpress install
Now start up the docker-compose.
sudo docker-compose up
Configuring Apache as a reverse proxy
Enable these mods. For ubuntu apache2:
a2enmod xml2enc headers rewrite proxy_http proxy_html proxy
Here is a virtualhost directive.
<VirtualHost *:80>
ServerName kim.example.com
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
RewriteEngine On
ProxyPass /frodo http://kim.example.com:8001
ProxyPassReverse /frodo http://kim.example.com:8001
ProxyPass /bilbo http://kim.example.com:8000
ProxyPassReverse /bilbo http://kim.example.com:8000
</VirtualHost>
Appendices
Commands used during my building and testing
Aliases in ~/.bashrc.local
alias dc='/usr/bin/sudo docker-compose'
alias docker='/usr/bin/sudo docker'
Command lines
dc down && docker rmi bilbo_wpmod && sudo rm -rf /var/bilbo
watch 'head -n58 /var/bilbo/www/wp-config.php | tail -n 17'
Adding vim to a docker container
In the wordpress container, to get to the local organization mirror for ubuntu. Need 3 apt keys, two of which are the main ubuntu keys.
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3B4FE6ACC0B21F32 40976EAF437D05B5
curl http://mirror.example.com/ubuntu/my-debian/my-debian.gpg > /root/my-debian.gpg
apt-key add /root/my-debian.gpg
apt-get update
apt-get install -y vim
References
Weblinks
- Apt-key commands https://chrisjean.com/fix-apt-get-update-the-following-signatures-couldnt-be-verified-because-the-public-key-is-not-available/
- http://www.apachetutor.org/admin/reverseproxies
- https://codex.wordpress.org/Changing_The_Site_URL
- https://pressable.com/blog/2015/10/15/reverse-proxy-plugin-for-using-a-hosted-wordpress-site-in-a-subdirectory/
- http://www.tldp.org/LDP/abs/html/here-docs.html#HERELIT
Reverse proxy for wordpress
I spent the most research time on getting wordpress to work behind a reverse proxy. I ended up writing my own Dockerfile to make my own image based on the wordpress image, because the entrypoint was not sufficient.
- One of the first pages you hit https://wordpress.org/support/topic/wordpress-behind-reverse-proxy-1?replies=4
- Eventually I got to the point where main site would work, but the wp-admin pages would redirect to host.example.org/ and not include the /blog directory, like this guy who didn't get it solved. https://wordpress.org/support/topic/stop-rewrites-to-reverse-proxy-for-wp-admin?replies=5
- Similar problems to this guy. He also provided his nginx reverse proxy config. https://wordpress.org/support/topic/wordpress-behind-a-reverse-proxyssl-endpoint-slightly-borked?replies=6
- At some point I had the wp-admin page working but the main site just wasn't loading at all.
- The holy grail is found here by this Wordpress genius. https://wordpress.org/support/topic/wordpress-strips-subdirectory-at-some-wp-admin-pages-with-and-reverse-proxy?replies=11#post-2445234
- I didn't use this, but this might be needed in the future: a .htaccess file that I saw referenced in at least one other location. https://gist.github.com/neverything/7675846
Internal documents
- Dockerizing Wordpress in One Container with Apache.docx
- Adding the service httpd.docx
Comments