Posted in:

Installing WordPress the Manual Way

Every now and then I want to set up an installation of WordPress to experiment with. The trouble is this is not a particularly simple task. Here’s the steps I typically go through:

  1. Create a virtual machine
  2. Install Ubuntu server on it, and set up the LAMP stack
  3. Connect to MySQL and set up a new database and user
  4. Install WordPress by downloading a tar file and extracting it
  5. Install a bunch of other stuff it turns out I need like php5-db and libssh2-php
  6. Configure WordPress by creating and editing a wp-config.php file
  7. Do various linuxy file permissions stuff with various sudo chown commands
  8. Google to discover what Hyper-V network settings I need for my VM actually allow me to connect to it from outside

Even following a good set of instructions like these, the last time I attempted this it took me several hours to get it running.

So I decided that now that I have Docker for Windows installed on my development machine, how hard would it be to get a WordPress installation up and running using Docker?

Installing WordPress with Docker Compose

A WordPress installation consists of two components – the WordPress website itself, and a MySQL database. Now while it’s certainly possible to have both of those running in one Docker container, the recommended way of working with Docker is to have one container per component. And with Docker Compose that’s really easy to achieve.

In fact, if we look at the official WordPress Docker image on Docker Hub, it gives us a docker-compose.yml file that we can cut and paste, simply replacing the password with one of our choosing. Here’s my docker-compose.yml file:

version: '2'

services:

  wordpress:
    image: wordpress
    ports:
      - 8080:80
    environment:
      WORDPRESS_DB_PASSWORD: wfehxi148s

  mysql:
    image: mariadb
    environment:
      MYSQL_ROOT_PASSWORD: wfehxi148s

As you can see, it’s so simple that you can probably guess how it works even if you’ve never used Docker Compose before. We have two containers, or “services”, one which we call “wordpress”, which uses the “wordpress” image from Docker Hub, and one called “mysql” which uses the “mariadb” image from Docker Hub (MariaDb is a MySQL compatible database).

Each image configures one environment variable, which contains the root MySQL database password. And the “wordpress” container will expose it’s internal port 80 on port 8080, so when this is up and running, I’ll be able to connect to WordPress by using http://localhost:8080.

Docker Compose assumes that these two containers need to talk to each other, so automatically configures a network allowing them to communicate, using their container names.

So having created this docker-compose.yml file, what’s involved in running it?

Well, all we need to do is make sure our Docker for Windows is in Linux container mode (right-click the Docker icon in the system tray and say “Switch to Linux containers”) and then in the same folder as our docker-compose.yml file, enter the command:

docker-compose up

What will happen next is that the “wordpress” and “mariadb” Docker images will need to be downloaded first time which might take a minute or two, but once you have them, the two containers will start up, and before you know it you’ll have a fully working WordPress system.

Just navigate to http://localhost:8080 and you’ll be ready to start customising your brand new WordPress installation.

starting up

Pretty straightforward. Compared to the hours of pain I used to go through whenever I tried to manually install WordPress on a VM, this is ridiculously easy. If I want to experiment with a new WordPress theme or plugin, I can do it in minutes in a sandboxed environment I can throw away if necessary.

When I’m done I can tear down the whole thing with docker-compose down, or just stop it temporarily with docker-compose stop.

Low-Level Container Access

Now, you might be wondering, what happens if I need to get direct access to these containers and make my own customizations? For example, I wanted to import the contents of another WordPress site into my container, but couldn’t do so because the PHP upload_max_filesize setting wasn’t set to a large enough value.

Well the great thing is that you can very easily get access inside your containers with docker exec. I used docker ps to find the identifier of my WordPress container, then docker exec -it b12a bash got me into a bash prompt inside the container.

From there I was able to install a Linux text editor I can actually save and exit with (unlike vi which I seem incapable of learning), and edit my .htaccess file:

apt-get update
apt-get install nano
nano /var/www/.htaccess

And that’s just one example of the power of docker exec. We could also connect to the MySQL container to query the database. We can even customise our docker-compose.yml file to mount local folders into our containers. So as well as having a really quick setup experience, we still have the power to be able to dive in at a low level if we want.

The next step is of course to host this WordPress Docker installation in the cloud. But that’s a subject for a future blog-post.

Comments

Comment by Sorcerer

I am in Windows environment running Docker (Win8.1 using Toolbox, Win10pro running Docker for Windows).
Have problems running Wordpress setup.
First, how do you configure your system to use localhost:8080 for your wordpress?
By default, when Docker starts up (in Windows), it issues a local IP, which in my case always is: 192.168.xx.xxx
I can run images using this IP and not localhost.
Second, running your Wordpress example is fine. But when I closed the Docker, everything is gone.
I want data persistent. So I modified the yml file a bit. But I ran into an error.
My .yml file looks like this:
version: '2'
services:
wordpress:
depends_on:
- db
image: wordpress:latest
restart: always
volumes:
- ./wp-content:C:\MyProjectDevelopments\Docker\WordpressEx02
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_PASSWORD: miw5oxty
ports:
- 80:80
- 443:443
networks:
- back
db:
image: mysql:latest
restart: always
volumes:
- db_data:C:\MyProjectDevelopments\Docker\WordpressEx02/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: miw5oxty
networks:
- back
I placed the yml file in "C:\MyProjectDevelopments\Docker\WordpressEx02"
I navigated into this directory and issued: docker-compose up -d
It came back with an error:
ERROR: Named volume "db_data:C:\MyProjectDevelopments\Docker\WordpressEx02/var/lib/mysql:rw" is used in service "db" but no declar
ation was found in the volumes section.
Can you advise how to tackle this problem wrt volume?
As I want data to persist in this local directory even after I close Docker.
What should I change in this script wrt specifying the location of the database data?

Sorcerer
Comment by Mark Heath

On docker for windows 10, I can access linux containers with localhost, so not sure what issue youre running into there.
As for the mysql volume, I'm not a docker-compose expert, but I think your volumes syntax isn't quite right. Check out this example: https://stackoverflow.com/a...

Mark Heath