Docker Compose

Cards (21)

    • Docker Compose, in summary, allows multiple containers (or applications) to interact with each other when needed while running in isolation from one another.
    • You may have noticed a problem with Docker so far. More often than not, applications require additional services to run, which we cannot do in a single container. For example, modern - dynamic - websites use services such as databases and a web server. For the sake of this task, we will consider each application as a “microservice”.
  • While we can spin up multiple containers or “microservices” individually and connect them, doing so one by one is cumbersome and inefficient. Docker Compose allows us to create these “microservices” as one singular “service”. 
    • This illustration shows how containers are deployed together using Docker Compose Vs. Docker:
  • Before we demonstrate Docker Compose, let’s cover the fundamentals of using Docker Compose.
    1. We need Docker Compose installed (it does not come with Docker by default). Installing it is out of scope for this room, as it changes depending on your operating system and other factors. You can check out the installation documentation.
    2. We need a valid docker-compose.yml file
    3. A fundamental understanding of using Docker Compose to build and manage containers.
  • up
    • This command will (re)create/build and start the containers specified in the compose file.
    • Example: docker-compose up
  • start
    • This command will start (but requires the containers already being built) the containers specified in the compose file.
    • Example: docker-compose start
  • down
    • This command will stop and delete the containers specified in the compose file.
    • Example: docker-compose down
  • stop
    • This command will stop (not delete) the containers specified in the compose file.
    • Example: docker-compose stop
  • build
    • This command will build (but will not start) the containers specified in the compose file.
    • Example: docker-compose build
  • Now, we could manually run the two containers via the following:
    1. Creating the network between the two containers: docker network create ecommerce
    2. Running the Apache2 webserver container: docker run -p 80:80 --name webserver --net ecommerce webserver
    3. Running the MySQL Database server: docker run --name database --net ecommerce webserver
  • Instead, we can use Docker Compose via docker-compose up to run these containers together, giving us the advantages of:
    1. One simple command to run them both
    2. These two containers are networked together, so we don’t need to go about configuring the network.
    3. Extremely portable. We can share our docker-compose.yml file with someone else, and they can get the setup working precisely the same without understanding how the containers work individually.
    4. Easy to maintain and change. We don’t have to worry about specific containers using (perhaps outdated) images.
  • Docker-compose.yml files 101
    • One file to rule them all. The formatting of a docker-compose.yml file is different to that of a Dockerfile. It is important to note that YAML requires indentation (a good practice is two spaces which must be consistent!).
  • Docker-compose.yml files 101
    • version
    • This is placed at the top of the file and is used to identify what version of Compose the docker-compose.yml is written for.
    • Example: '3.3'
  • Docker-compose.yml files 101
    • services
    • This instruction marks the beginning of the containers to be managed.
    • Example: services:
  • Docker-compose.yml files 101
    • name (replace value)
    • This instruction is where you define the container and its configuration. "name" needs to be replaced with the actual name of the container you want to define, i.e. "webserver" or "database".
    • Example: webserver
  • Docker-compose.yml files 101
    • build
    • This instruction defines the directory containing the Dockerfile for this container/service. (you will need to use this or an image).
    • Example: ./webserver
  • Docker-compose.yml files 101
    • ports
    • This instruction publishes ports to the exposed ports (this depends on the image/Dockerfile).
    • Example: '80:80'
  • Docker-compose.yml files 101
    • volumes
    • This instruction lists the directories that should be mounted into the container from the host operating system.
    • Example: './home/cmnatic/webserver/:/var/www/html'
  • Docker-compose.yml files 101
    • environment
    • This instruction is used to pass environment variables (not secure), i.e. passwords, usernames, timezone configurations, etc.
    • Example: MYSQL_ROOT_PASSWORD=helloworld
  • Docker-compose.yml files 101
    • image
    • This instruction defines what image the container should be built with (you will need to use this or build).
    • Example: mysql:latest
  • Docker-compose.yml files 101
    • networks
    • This instruction defines what networks the containers will be a part of. Containers can be part of multiple networks (i.e. a web server can only contact one database, but the database can contact multiple web servers).
    • Example: ecommerce
  • With that said, let’s look at our first docker-compose.yml file. This docker-compose.yml file assumes the following:
    1. We will run one web server (named web) from the previously mentioned scenario.
    2. We will run a database server (named database) from the previously mentioned scenario.
    3. The web server is going to be built using its Dockerfile, but we are going to use an already-built image for the database server (MySQL)
    4. The containers will be networked to communicate with each other (the network is called ecommerce).
    5. Our directory listing looks like the following:
    6. docker-compose.yml
    7. web/Dockerfile