Ultimate WordPress Docker setup guide
Learn how to use Docker to host WordPress websites and blogs in this comprehensive guide. Docker is the perfect platform to host WordPress websites but it’s not without its complications. This guide will put you on the right track from the start.
WordPress Docker Benefits
My WordPress Docker guide has these features if you follow it through:
- Setup multiple websites/blogs on even modest Virtual Private Servers (VPS)
- Use the NGINX reverse proxy, so you don’t have to use different ports (80,8080,8081 etc.) for each site
- Every site gets SSL encryption, this protects your wp-admin login and looks good for your visitors
- Certificates issued that should be renewed automatically with Let's Encrypt
- Uses MariaDB for efficiency and low resource usage
- Each site gets the latest version of WordPress and its own environment to install themes and plug-ins
- WordPress upload limit raised from the 2MB default, that would otherwise interfere with the website/blog operation
- Data is kept separately in Docker data volumes, that will persist outside the container
- Each site is separate with its own dedicated WordPress and database containers, making cross-site contamination less likely
- WordPress, themes and plugins can be updated using the built-in WordPress update mechanism as usual
- Option to backup your WordPress volume and database
Like anything, if you find parts of this useful here, adapt it for your own needs, Docker makes that very easy to do.
With this guide and the power of Docker you could setup several sites in a short space of time, 30 minutes or less most likely.
What you don't get (yet!)
While I hope the above features constitute what I have called the ultimate guide, there are some things I will revisit when possible and aren’t covered currently:
- MariaDB updates
- Resource controls
- Caching and tuning
Many of these things you would have to look at anyway at some point, irrespective of using Docker or not.
New April 2016:
See my "How to update docker containers" post for instructions on updating MariaDB and WordPress
Also I assume you know how to update your DNS to point your domains to the server as well how to install Docker and Docker-Compose.
WWW vs non-WWW for your site
You should decide how you want your site to be referenced with your domain name and site. Do you want your site to be www.mydomain.com or without the www part which is called a 'naked domain'.
This is important as it can effect how search engines like Google identify your site and what may be seen as duplicate content, which you can get penalized for.
If you make this choice upfront it's a lot simpler, it's also has some relevance to nginx and certificates as well as WordPress itself.. We want visitors to be able to visit the site whether they use www or not and have the same experience. The best practice is also to let Google know via the Google Webmaster Tools how you reference your site.
For more information on this topic, check out this page - WWW vs non-WWW – Which is Better For WordPress SEO?
Docker alternative for WordPress - rtCamp's EasyEngine
While you can get up-to-speed with Docker very quickly, another option I’d draw attention to is rtCamp’s EasyEngine. This is a more conventional means of setting up websites and blogs in minutes. EasyEngine can setup WordPress on NGINX in a single command, with their script taking care of everything else
I like EasyEngine and it’s a great option but I prefer the separation that Docker provides from the underlying OS. If you don’t want to get too involved in Docker, EasyEngine is well worth looking into.
How to setup WordPress with Docker
Hopefully this doesn't sound overly complicated but these are the basic steps:
- Create the required folders
- Setup NGINX
- Setup MariaDB and WordPress
- Create data volume containers
- Create vhost.d and uploads.ini files
- Start containers
Bear in mind, most of these steps just involve copying and pasting commands or creating files with the contents included here.
You may have to play around with some of these commands if you get unexpected results. I am assuming you have a properly configured server with the latest versions of Docker and Docker Compose installed.
Note - I haven't tested this setup with Docker Toolbox.
First to get started create some folders that we will need later. Put these in a folder of your choice, like the home folder. Create these folders as follows:
mkdir yourdomain2com (optional)
Give the domain folder(s) meaningful names, as Docker Compose will use them to distinguish the containers. These are all top level folders.
In the nginx folder, create a docker-compose.yml file. I assume you are using the nano text editor for these steps, substitute it with your preferred editor if needed.
Paste this to build into your yml file. Change the <username> portion, to your actual home folder or wherever you decide to create these folders in the previous step .
Note: Indentation is very important in docker-compose.yml, all code has to line up exactly or when you come to start the containers, it may produce errors.
In the folder you created earlier for your domain, create a new docker-compose.yml file with the following configuration. Change the MYSQL password to something secure and unique.
- LETSENCRYPT_HOST= yourdomain.com,www.yourdomain.com
- yourdomain _mariadb_data
Steps 1-3 Demo
Rather than just talk about this configuration I can show you this in action as well with asciinema.org:
This is with my test domain bocker.xyz and setup using the root account.
Now we need the data volumes, so our WordPress and MariaDB containers can store their data independently of the corresponding container itself.
docker create --name yourdomain_mariadb_data -v /var/lib/mysql mariadb
docker create --name yourdomain_wordpress_data -v /var/www/html wordpress
We are almost done! We now have a Docker Compose files, that will create nginx and a companion containers for certificates. Then we have MariaDB and WordPress containers to host our site.
Now we create a file in the vhost.d folder from step 1, it must be named exactly after the VIRTUAL_HOST, we specified in step 3
Then add these commands
You have to do the same again for each hostname e.g www.yourdomain.com, creating a corresponding file with the above contents. This means nginx will understand either address for your site.
Here is our uploads.ini, that overrides some rather limiting default PHP based WordPress settings. Without these tweaks you couldn't upload images, themes or plugins over 2 MB's in size!
Create the uploads.ini file in the yourdomain1com folder created in step 1.
file_uploads = On
memory_limit = 64M
upload_max_filesize = 64M
post_max_size = 64M
max_execution_time = 1800
You can now start the containers, first nginx and then WordPress/MariaDB.
docker-compose up -d
docker-compose up -d
All being well, the containers will start up, if in doubt run docker-compose logs in the respective folder. This will show you the combined logs of the containers, which will give you some clues on activity and any potential errors.
You can now visit https://www.mydomain.com or https://mydomain.com depending on how you decided to setup your site. This may take a few minutes, while a certificate is issued via Let's Encrypt and the containers are ready.
If everything has worked you will get the standard WordPress installation screen. You can set the site title, the admin username and password, as well as an email address. If you got this far, you will now have a working WordPress site!
Steps 4-6 Demo
Again, here is the demo, that hopefully makes this process more understandable:
WordPress Backups with Docker
As you spend time on your site you are going to want a way to back it up. There could be several ways to this but I am going to show you one way.
First lets backup the WordPress volume, specify the WordPress data volume from Step 4 and name the tar file after your domain to give it meaning.
Here the container we run only exists for as long it takes to backup the WordPress volume.
docker run --rm --volumes-from mydomaincom_wordpress_data -v $(pwd):/backup wordpress tar cvf /backup/mydomaincom_wordpress.tar /var/www/html
Then we are going to backup the MariaDB WordPress database, changing mydomaincom and the strong password. Note there is no space between this switch -pyourpassword. This is the password from Step 3 - 'MYSQL_ROOT_PASSWORD'. This is executing a backup command in our MariaDB container.
docker exec -i mydomaincom_mariadb_1 mysqldump -u root -p<strongassword> wordpress > mydomaincom_mysql.sql
On your host in the backup folder, you will be left with two files - a .tar file and a .sql file giving a backup of your site. This could be used to recover your site, or indeed move it to say another host.
Finishing up - Docker and WordPress a match made in heaven?
There may well be a few typos that have sneaked in but I'll be double checking to eliminate them if there are any!
What I can say is, I have used the configuration on this very site, which has gone well so far. I have also run a second site alongside this, working well together by repeating steps 3-5 before starting everything up in step 6.
I hope this post has been of interest, I have tried to bring us much information together in one place to get you started with WordPress on Docker. I will be revising the content, if there is anything else I can add value. I'll have more Docker posts in the near future!