How to Use Docker Compose and YAML for Multi-Container Applications | Day 18 of 90 Days Of DevOps

Ajit Fawade
7 min readAug 10, 2023

--

Photo by Prometheus 🔥 on Unsplash

In this blog, I’ll show you how to use Docker Compose, a tool that allows you to define and run multi-container applications with Docker. Docker Compose is based on YAML, a human-readable data serialization language that is often used for configuration files.

Introduction to Docker Compose

Docker Compose is a tool that lets you create and manage complex applications that consist of multiple containers. With Docker Compose, you can write a YAML file that specifies the services, networks, volumes, and other options for your application. Then, with a single command, you can build, run, and scale your application as a whole.

Docker Compose is useful for developing, testing, and deploying applications that have multiple components or microservices. For example, you can use Docker Compose to create a web application that consists of a web server, a database, and a cache. You can also use Docker Compose to orchestrate the communication and dependencies between different containers.

What is YAML?

YAML stands for Yet Another Markup Language or YAML Ain’t Markup Language (a recursive acronym), depending on whom you ask. YAML is a data serialization language that is designed to be easy to read and write by humans. YAML is commonly used for writing configuration files and in applications where data is being stored or transmitted.

YAML has a simple syntax that uses indentation, colons, dashes, and brackets to represent the structure and values of data. YAML supports scalars (such as strings, numbers, and booleans), lists (or sequences), and maps (or dictionaries). YAML also allows you to define custom data types and aliases for reusing data.

Here is an example of a YAML file that defines some information about a person:

name: John Doe
age: 42
gender: male
hobbies:
- reading
- hiking
- gardening
address:
street: 123 Main Street
city: Springfield
state: IL
zip: 62701

Learn how to use the docker-compose.yml file

In this task, you will learn how to use the docker-compose.yml file to set up the environment, configure the services and links between different containers, and also to use environment variables in the docker-compose.yml file.

The docker-compose.yml file is the main file that defines your application using Docker Compose. It follows the YAML syntax and has a specific format that you can find at Compose file reference.

A typical docker-compose.yml file looks something like this:

version: "3.9" # specify the version of the compose file format

services: # define the services or containers that make up your application

web: # name of the first service
image: nginx # name of the image to use for this service
ports: # list of ports to expose on the host machine
- "80:80"
depends_on: # list of services that this service depends on
- app

app: # name of the second service
build: ./app # path to the directory containing the Dockerfile for this service
environment: # list of environment variables to pass to this service
- DB_HOST=db
- DB_USER=root
- DB_PASS=secret
- DB_NAME=todos
volumes: # list of volumes to mount on this service
- ./app:/app

db: # name of the third service
image: mysql # name of the image to use for this service
environment: # list of environment variables to pass to this service
- MYSQL_ROOT_PASSWORD=secret
- MYSQL_DATABASE=todos

volumes: # define any named volumes used by the services
db_data: # name of the volume for persisting database data

networks: # define any custom networks used by the services
default: # name of the default network
driver: bridge # driver to use for this network

This file defines an application that consists of three services:

  • web: A web server that uses the nginx image and exposes port 80 on the host machine. It depends on the app service.
  • app: A web application that uses a custom image built from the Dockerfile in the ./app directory. It passes some environment variables related to the database connection and mounts the ./app directory as a volume on the container.
  • db: A database server that uses the mysql image and passes some environment variables related to the database creation and password. It uses a named volume called db_data to persist its data.

The file also defines a named volume called db_data and a default network using the bridge driver.

To run this application using Docker Compose, you need to navigate to the directory where your docker-compose.yml file is located, and then run this command:

docker compose up

This will create and start all the services defined in your file. You can also use the -d flag to run the services in detached mode, which means they run in the background.

To stop and remove the services, you can run this command:

docker compose down

This will stop and remove the containers, networks, volumes, and images created by docker compose up.

Pull a pre-existing Docker image and run it on your local machine

In this task, you will pull a pre-existing Docker image from a public repository (e.g. Docker Hub) and run it on your local machine. You will also run the container as a non-root user, inspect its processes and ports, view its logs, and stop and remove it.

To pull a pre-existing Docker image from a public repository, you need to use the docker pull command with the name of the image. For example, if you want to pull the hello-world image from Docker Hub, you can use this command:

docker pull hello-world

This will download the image and its layers to your local machine. You can also use the docker images command to see the list of images on your machine.

To run a container from an image, you need to use the docker run command with the name of the image. For example, if you want to run a container from the hello-world image, you can use this command:

docker run hello-world

This will create and start a container from the image and display its output. You can also use the docker ps command to see the list of running containers on your machine.

To run a container as a non-root user, you need to use the -u or — user flag with the docker run command and specify the user ID or name. For example, if you want to run a container from the ubuntu image as a user with ID 1000, you can use this command:

docker run -u 1000 ubuntu

This will create and start a container from the image and run it as a user with ID 1000. You can also use the id command inside the container to verify the user ID.

To inspect a container’s running processes and exposed ports, you need to use the docker inspect command with the name or ID of the container. For example, if you want to inspect a container named my-container, you can use this command:

docker inspect my-container

This will display a JSON output that contains detailed information about the container, such as its ID, name, state, network settings, mounts, etc. You can also use filters or formats to display specific fields or values. For example, if you want to display only the processes and ports of a container named my-container, you can use this command:

docker inspect --format '{{.State.Pid}} {{.NetworkSettings.Ports}}' my-container

This will display the process ID and port mappings of the container.

To view a container’s log output, you need to use the docker logs command with the name or ID of the container. For example, if you want to view the logs of a container named my-container, you can use this command:

docker logs my-container

This will display the standard output and standard error of the container. You can also use flags such as -f or — follow to stream the logs continuously, or -t or — timestamps to add timestamps to each line.

To stop and start a container, you need to use the docker stop and docker start commands with the name or ID of the container. For example, if you want to stop and start a container named my-container, you can use these commands:

docker stop my-container
docker start my-container

These will stop and start the container gracefully. You can also use docker kill and docker restart commands to force-stop and restart a container.

To remove a container, you need to use the docker rm command with the name or ID of the container. For example, if you want to remove a container named my-container, you can use this command:

docker rm my-container

This will remove the container from your machine. You can also use flags such as -f or — force to remove a running container, or -v or — volumes to remove any anonymous volumes associated with the container.

Conclusion

In this blog, I have shown you how to use Docker Compose and YAML to define and run multi-container applications with Docker. I have also shown you how to pull an existing Docker image from a public repository and run it on your local machine as a non-root user. I have also shown you how to inspect, log, stop, start, and remove containers using Docker commands.

I hope you have learned something new and useful from this blog. If you have any questions or feedback, please feel free to leave a comment below

--

--

Responses (1)