You may be familiar with Docker already, but of course in order to run any app successfully you will also need to juggle more than one container. The easiest way to handle this is using Docker Compose. Once the structure of your application is defined, you can then simultaneously create and initiate those containers with one simple command.
In this article we’ll closely review how all of this works together by using a WordPress container along with a MySQL 8.0 container that is separate from the host MySQL instance.
Installing
If you’re on Linux or Mac, you’ll need to install Docker Compose in order to use it. If you’re on Windows, you’re in luck as it is already included with Docker Desktop.
You can check the latest version by going to the github repo here.
At the time of the publishing this article, the latest version is 1.26.2, and the latest version can be downloaded using curl:
sudo curl -L "https://github.com/docker/compose/releases/download/1.26.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
Make sure that Docker Compose has executable permissions:
sudo chmod +x /usr/local/bin/docker-compose
You can test to make sure that the latest version of Docker Compose is installed:
docker-compose -v
The response should be something along the lines of:
docker-compose version 1.26.2, build eefe0d31
Defining docker-compose.yml
Next, we can create our first project along with its docker-compose.yml file to test out a fairly simple and common set- up:
version: '3.8' services: wp_mysql: image: mysql:8 container_name: wp_mysql ports: - "3336:3306" volumes: - db_data:/var/lib/mysql restart: always command: --default-authentication-plugin=mysql_native_password environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: wpdb MYSQL_USER: wpuser MYSQL_PASSWORD: wppass wp: depends_on: - wp_mysql image: wordpress:latest container_name: wp ports: - "8888:80" restart: always environment: WORDPRESS_DB_HOST: wp_mysql WORDPRESS_DB_NAME: wpdb WORDPRESS_DB_USER: wpuser WORDPRESS_DB_PASSWORD: wppass WORDPRESS_DEBUG: 1 volumes: db_data:
This sets up two docker containers — one for the MySQL database, and another for the WordPress installation.
First, we need to define the Docker Compose version. As of the writing of this post, “3.8” is the latest, which maps to the Docker Engine 19.03.0+. If you use an older version, it can still successfully run on newer versions of Docker.
version: '3.8'
Following that, we have the “services” section, where we define each of our containers. Inside that, we have two sections.
First, let’s see the database that we have named wp_mysql. This is important so we can reference this container later on.
wp_mysql:
image: mysql:8
container_name: wp_mysql
ports:
- "3336:3306"
volumes:
- db_data:/var/lib/mysql
restart: always
command: --default-authentication-plugin=mysql_native_password
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: wpdb
MYSQL_USER: wpuser
MYSQL_PASSWORD: wppass
We base the container on the mysql:8 image which maps to the latest version of MySQL 8.
The ports are only important if you want to be able to easily access this database from your host. This maps the 3306 port to the host’s 3336.
Next, we have the volumes list where we map the db_data volume to the /var/lib/mysql location within the MySQL container.We have restart: always which will ensure that our container is always running and even if something causes it to fail, it will automatically restart.
Do note that we need to include the following command:
command: --default-authentication-plugin=mysql_native_password
This makes it possible for WordPress to connect to our MySQL 8 database, changing the default authentication setting to the native MySQL password, which is what WordPress uses.Lastly, we have the environment settings that define the database, user, and passwords. Make sure that you use the same settings later when configuring the WordPress container.
Next, we define the WordPress container:
depends_on:
- wp_mysql
image: wordpress:latest
container_name: wp
ports:
- "8888:80"
restart: always
environment:
WORDPRESS_DB_HOST: wp_mysql
WORDPRESS_DB_NAME: wpdb
WORDPRESS_DB_USER: wpuser
WORDPRESS_DB_PASSWORD: wppass
WORDPRESS_DEBUG: 1
Do note the depends_on list that in our case only asks for wp_mysql to be running. Without the database, we do not want WordPress running.
The ports section is also important to
take note of since 8888:80 makes sure that localhost:8888 points to our WordPress container so we can actually access it once it’s running.
The environment settings are very simple. In this case, WORDPRESS_DB_HOST points to our database which we previously defined (make sure the name is the same), and then enter the database name, user, and password.
Lastly, we activate debugging.
Finally, we have the volumes section where we keep track of all the volumes that we previously assigned to our containers.
In our case, we’re only using a MySQL volume, so that’s all we’re going to need for now.
Initializing our Docker containers
Once we have our docker-compose.yml file ready to go, we can test it using the following command:
docker-compose up -d
This retrieves the images from Docker Hub if we don’t have them locally and then starts the containers. The -d option allows the containers to run in the background.
Since we mapped the MySQL’s 3306 port to the host port 3336 we can now access it from our host’s console:
mysql -u wpuser -pwppass -h 127.0.0.1 -P 3336 -D wpdb
This will connect to our MySQL container and give us full access to the database.Navigating the browser to the http://localhost:8888 URL we should be able to see the WordPress installation page.Once that’s done, you have your WordPress up and running without any need to locally install PHP or MySQL.
Shutting down our Docker Containers
After that’s completed, both containers will be running and if we want to shut them down at any point, we can use the following command:
docker-compose down
Do note that this will keep the MySQL volume,so when you start your containers again you will not be asked to install WordPress a second time. If you want to remove it completely, you’ll need to add the –volumes option.
Next
Following this, we could take this a step further in completion by adding a volume for WordPress. This can be done in two ways. First, by creating a volume and assigning it a name, like we did with MySQL.
volumes:
- wpfiles:/var/www/html
Remember that if you do this, you’ll need to add the wpfiles volume to the list of volumes. It should look like this:
volumes:
db_data:
wpfiles:
Alternatively, we could bind a folder in our host machine, and the easiest solution would be to point the local folder to the WordPress installation:
volumes:
- ./:/var/www/html
This maps the local folder to the WordPress /var/www/html, allowing us to easily edit the files afterwards.
For more information on Docker Compose, you can check the official documentation here.
About the Author
Lorenzo Sauchelli is a creative Front-End developer who specializes in JavaScript, HTML, WordPress, and PHP technologies. He is a passionate developer who is always looking for new challenges.