Go back

Get started with Docker Compose

Docker

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

Lorenzo

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.