BASHing the WordPress Docker Container in to shape.Written by Bunkers on March 1, 2017
This is the last post (for now) in my series documenting how I've setup a WordPress development environment with Docker. It really took shape yesterday when we got the full set of containers running. We've now got an environment that runs PHP code.
To finish up and get WordPress running we need to turn our attention back to the
data container and its
entrypoint.sh script. The full script is pretty involved, and there's a large amount that's lifted from the official WordPress Docker images, so I thought it's probably best to give you a [link to download it](link to download it), and just talk through the major points of interest!
In case you missed the links you can [download](link to download it) it and the rest of the files from GitHub here.
Dockerfile we downloaded and extracted WordPress to the
/usr/src/wordpress directory. In this first section of the script we copy it over along with the database search and replace tool, if it's not already found. You'll nearly always get the warning about the directory not being empty as we've setup a link to the
wp-content directory. I'm therefore considering removing that, or at least making the check more useful.
file_env function is again taken from the WordPress image. I've seen it in a number of other Docker image entry point scripts, and allows environment variables to be setup from file names. The next section uses this to setup environment variables for the database.
We edit the
wp-config.php file using the escape functions that follow. The WordPress official container is again the source for these! But the next section is new and looks for an environment value for
WORDPRESS_MULTISITE. If found then the associated multisite configuration settings are setup from environment variables too.
The rest of the script sets up the
wp-config.php if it's not found. The changes I've made from the official image script add in the settings for multisite if required. When setting up the file for the first time we add in the PHP
define statements. When the
wp-config already exists we use the
set_config function to update the values as necessary. I haven't covered the situation where you want to turn multisite off in this script. The best solution would be to remove the container and have it rebuilt with the new configuration.
set_config function updates all the other configuration options to finish the script. The one change I made here was regarding the unique keys and salts values. I wanted them to be more like the values you receive from the WordPress generator. Probably not necessary for a development environment but there's no harm in using it and it's one less thing to change for the production environment.
The change is with this line:
set_config "$unique" "$(LC_ALL=C tr -cd '\41-\46\50-\133\135-\176' < /dev/urandom | head -c 64)"
set_config with our salt/key name, and the tr command filters the string of characters from the /dev/urandom device to remove non-printable characters. I know it gets escaped but I also filter out the apostrophe to avoid problems with it terminating the PHP string. The value used is the first 64 characters from this stream taken with the
head command at the end. It's a small thing but creates a much more satisfyingly random string!
And that's the
entrypoint.sh file for our
data container. Feel free to suggest improvements. My BASH scripting skills are definitely not l33t standard.
There's a couple more things to add and update. Firstly we need another environment file called
wp.env to contain our WordPress settings. This lives in the
site directory for our
data container and looks like:
or if you're using multisite:
WORDPRESS_SUBDOMAIN_INSTALL=false WORDPRESS_DOMAIN_CURRENT_SITE=tutorial.bunkers WORDPRESS_PATH_CURRENT_SITE=/ WORDPRESS_SITE_ID_CURRENT_SITE=1 WORDPRESS_BLOG_ID_CURRENT_SITE=1 WORDPRESS_MULTISITE=1 WORDPRESS_ALLOW_MULTISITE=1 WORDPRESS_TABLE_PREFIX=wordpress_
You add this file in to the
docker-compose.yml file by updating the
data: build: ./site env_file: - ./db.env - ./site/wp.env volumes: - /var/www/html - ./wp-content:/var/www/html/wp-content
These settings allow our container access to the database connection details and any additional WordPress config in the
wp.env file. You may not have any additional WordPress configuration, in which case you don't need to bother with linking it in.
While we're editing it, there's one more change in the
docker-compose.yml file that allows the PHP container to see our web container with the right domain name. This is important for upgrades as WordPress hits URLs on the site itself. Change the
php section to:
php: #image: php:7-fpm build: ./php volumes_from: - data links: - percona:wpdb - web:tutorial.bunkers env_file: ./db.env
We're linking our web server container to the PHP one with the domain name we're using so any requests to it get routed to the web server. The database environment variables are also added in for using the search and replace tool from the command line.
The last change is to our NGINX
site.conf file. WordPress uses Apache's
mod_rewrite to provide pretty URLs for posts. The rewriting rules are different for NGINX. They're also more complicated for multisite installs. Thankfully I discovered that the multisite setup will work fine for a single site install, so we can use the same configuration for both.
It's a big update to the file, so again just download it and don't forget to change the domain to fit your environment.
There we have it! You can now place a backup of the site in your
wp-content directory and a backup of the database in the
percona/tmp folder, bring up the containers with:
docker-compose up --build -d
This forces a rebuild of our images with the new
Load in the database using our
load-db script, and you'll have a working development version of your WordPress site. Alternatively just start up the containers and when you go to your development URL you'll go through the WordPress install process for setting up a new site.
I'm sure I'll revisit this over time. I want to setup these images in a Docker registry so setting it all up is just configuration - a
docker-compose.yml file and some environment variable files. I'd also like to expand it for use in a production environment, so if you're interested, watch this space!