• 8 hours
  • Medium

Free online content available in this course.

course.header.alt.is_certifying

Got it!

Last updated on 11/10/22

Create a Docker Compose File to Orchestrate Your Containers

Create Your docker-compose.yml File

In the last chapter, we saw how to use the command-line interface for Docker Compose. Now it’s time to learn how to create a  docker-compose.yml  file.

Our Docker Compose structure
Our Docker Compose structure

Start by creating a  docker-compose.yml  file at your project root. In this, describe all of the resources and services required to create your POC.

Describe Your First Service: db

Define the Version of Docker Compose

A  docker-compose.yml  file always starts with the following information:

version: '3'

The  version  argument tells Docker Compose which version we want to use. Here we’re using version three, which is currently the most widely-used version.

Declare the First Service and Its Image

We’re now going to declare our first service, which will create our WordPress stack!

services:
  db:
    image: mysql:5.7

Next, you need to describe your container. Here, we’re using the  image  argument which defines the Docker image that we want to use.

Define the Volume in Order to Persist Your Data

services:
  db:
    image: mysql:5.7
    volumes:
      - db_data:/var/lib/mysql

Remember, earlier we saw that Docker containers are not created to run stateful services, and that a database is by definition a stateful service. However, you can use the  volumes  argument, which lets you store all of the contents of the  /var/lib/mysql  folder in a persistent disk, thereby locally storing our data on our host.

This description is present in the line  db_data:/var/lib/mysql.  db_data  is a volume created directly by Docker which lets you write data to the host disk without specifying the exact location. You could also have used  /data/mysql:/var/lib/mysql, which would have worked just as well.

Define a Restart Policy for the Container

services:
  db:
    image: mysql:5.7
    volumes:
      - db_data:/var/lib/mysql
    restart: always

Since a container is, by definition, single-process, if it encounters a fatal error, it might just stop. In our example, if the MySQL server stops, it will restart automatically using the  restart: always  argument.

Define Environment Variables

services:
  db:
    image: mysql:5.7
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: somewordpress
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress

The MySQL image provided has several environment variables that you can use. For our example, we’re going to give the container the values of different passwords and users that should exist on this base. When you want to give environment variables to a container, you should use the  environment  argument, just like we have done in the  docker-compose.yml  file above.

Describe Your Second Service: WordPress

In the second service, we create a container that will contain everything we need to run our website with WordPress. This allows us to introduce two additional arguments.

services:
  wordpress:
    depends_on:
      - db
    image: wordpress:latest
    ports:
      - "8000:80"
    restart: always
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_DB_NAME: wordpress

The first argument (  depends_on  ) is for creating a dependency between two containers. This means that Docker will start the db service before starting the WordPress service. We want this to happen, as WordPress depends on the database to work correctly.

The second argument (  ports  ) tells Docker Compose that we want to expose a port from our host machine to our container, making it externally accessible.

Here is the docker-compose.yml file in its final version:

version: '3'
services:
  db:
    image: mysql:5.7
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: somewordpress
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress
    
  wordpress:
    depends_on:
      - db
    image: wordpress:latest
    ports:
      - "8000:80"
    restart: always
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_DB_NAME: wordpress

volumes:
  db_data: {}

Run Your Docker Compose Stack

When you run your containers with the  docker-compose up -d  command, you should get the following result:

$ docker-compose up -d
Creating network "my_wordpress_default" with the default driver
Pulling db (mysql:5.7)...
5.7: Pulling from library/mysql
efd26ecc9548: Pull complete
a3ed95caeb02: Pull complete
...
Digest: sha256:34a0aca88e85f2efa5edff1cea77cf5d3147ad93545dbec99cfe705b03c520de
Status: Downloaded newer image for mysql:5.7
Pulling wordpress (wordpress:latest)...
latest: Pulling from library/wordpress
efd26ecc9548: Already exists
a3ed95caeb02: Pull complete
589a9d9a7c64: Pull complete
...
Digest: sha256:ed28506ae44d5def89075fd5c01456610cd6c64006addfe5210b8c675881aff6
Status: Downloaded newer image for wordpress:latest
Creating my_wordpress_db_1
Creating my_wordpress_wordpress_1

When executing this command, Docker Compose starts by checking if we have the images required to run the stacks available locally. If not, it will download them from a registry, or build them via  docker build.

It will then launch two containers on your system. For our example, you can see the result by opening the following URL in your browser:  http://127.0.0.1:8000.

And your WordPress website is up and running!
And your WordPress website is up and running!

Let’s Recap!

You now know how to use the basic commands in Docker Compose, and create a  docker-compose.yml  file to manage your Docker containers.

Here’s a recap of the arguments we’ve looked at in this chapter:

  • image  for specifying the source image for the container

  • build  for specifying the source Dockerfile to create the container image

  • volume  for specifying the mountpoints between the host system and the containers

  • restart  to define how the container behaves if the process is stopped

  • environment  to define the environment variables

  • depends_on  to state that the container depends on another container

  • ports  to define the available ports between the host machine and the container

Join me in the next chapter to practice using Docker Compose.

Example of certificate of achievement
Example of certificate of achievement