Docker Compose with examples

Docker Compose

Docker Compose is a tool that simplifies the process of managing multi-container Docker applications. It provides a way to define and run multiple Docker containers as a single application, with configuration options to manage the various components of the application. In this article, we will discuss in depth about Docker Compose, its architecture, how it works, and its benefits.

Architecture:

Docker Compose architecture consists of two parts: the client and the server. The client is the command-line interface (CLI) tool that allows you to interact with Docker Compose. The server is the Docker daemon that runs on the host machine.

Docker Compose uses YAML files to define the services, networks, and volumes for the application. These YAML files are used to create a Docker Compose project. A project can contain multiple services, networks, and volumes.

How it works:

Docker Compose uses a declarative approach to define the application. You specify the desired state of the application, and Docker Compose will manage the resources required to achieve that state. The YAML file contains the configuration options for each service, network, and volume.

To create a Docker Compose project, you define the services that make up the application. Each service is defined in a separate YAML file. The YAML file contains information about the image, environment variables, ports, volumes, and other configuration options for the service.

Once you have defined the services, you can use the Docker Compose CLI to create and manage the containers. The CLI provides commands to start, stop, and restart the containers, as well as to view logs and status information.

Let's take an example of a multi-container application that consists of a web server and a database.

First, we would create two separate YAML files, one for the web server and one for the database. Here's an example of what the YAML file for the web server might look like:

version: '3'

services:

  web:

    image: nginx:latest

    ports:

      - "8080:80"

 

This YAML file defines a service called "web" that uses the latest version of the nginx image and maps port 8080 on the host to port 80 in the container.

Next, we would create a YAML file for the database service. Here's an example of what that file might look like: 

version: '3'

services:

  db:

    image: mysql:latest

    environment:

      MYSQL_ROOT_PASSWORD: mypassword

      MYSQL_DATABASE: mydatabase

    volumes:

      - ./db-data:/var/lib/mysql

 

This YAML file defines a service called "db" that uses the latest version of the MySQL image and sets environment variables for the root password and database name. It also creates a named volume called "db-data" that maps to the "/var/lib/mysql" directory in the container.

Finally, we would use the Docker Compose CLI to start the containers. Here's the command we would use:

docker-compose up

This command reads the YAML files and starts the containers for the web server and database services. We can view the logs for the containers by running:

docker-compose logs

And we can stop the containers by running:

docker-compose down

This is just a simple example, but Docker Compose can be used to define and manage much more complex applications with multiple services, networks, and volumes.

 

Here are some examples of Docker Compose commands

  1. docker-compose up

$ docker-compose up

Starting myapp_db_1 ... done

Starting myapp_app_1 ... done

Attaching to myapp_db_1, myapp_app_1

db_1   | MySQL init process done. Ready for start up.

app_1  | Listening on http://0.0.0.0:8000/

This command starts all the containers defined in the Docker Compose file. In this example, we have a database service and an app service. The output shows that both services have been started and are running.

  1. docker-compose down

$ docker-compose down

Stopping myapp_app_1 ... done

Stopping myapp_db_1 ... done

Removing myapp_app_1 ... done

Removing myapp_db_1 ... done

Removing network myapp_default 

This command stops and removes all the containers, networks, and volumes defined in the Docker Compose file. In this example, we have two services, an app service and a database service. The output shows that both services have been stopped and removed, and the network has been removed.

  1. docker-compose ps

$ docker-compose ps

      Name              Command           State              Ports

--------------------------------------------------------------------------

myapp_app_1   python manage.py runserver   Up      0.0.0.0:8000->8000/tcp

myapp_db_1    docker-entrypoint.sh mysqld   Up      0.0.0.0:3306->3306/tcp

This command lists the status of all the containers defined in the Docker Compose file. In this example, we have an app service and a database service. The output shows the name of each container, the command used to start it, its current state, and the ports that are being forwarded.

  1. docker-compose logs

$ docker-compose logs

Attaching to myapp_app_1, myapp_db_1

app_1  | Performing system checks...

db_1   | 2022-03-12 17:16:50+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.34-1debian10 started.

app_1  |

app_1  | System check identified no issues (0 silenced).

db_1   | 2022-03-12 17:16:50+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'

db_1   | 2022-03-12 17:16:50+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.34-1debian10 started.

app_1  | March 12, 2022 - 17:16:51

app_1  | Django version 3.2.10, using settings 'myapp.settings'

db_1   | 2022-03-12 17:16:50+00:00 [Note] [Entrypoint]: Initializing database files

... 

This command displays the logs for all the containers defined in the Docker Compose file. In this example, we have an app service and a database service. The output shows the logs from each container, including any errors or informational messages.

 

  1. docker-compose exec

$ docker-compose exec app python manage.py createsuperuser

Username (leave blank to use 'root'): admin

Email address: admin@example.com

Password:

Password (again):

Superuser created successfully.

This command allows you to execute a command inside a running container. In this example, we are running the command python manage.py createsuperuser inside the app container. This command creates a superuser for a Django application.

  1. docker-compose build

$ docker-compose build

Building app

Step 1/6 : FROM python:3.9-slim-buster

 ---> 74698c2d4338

...

Successfully built 1e70c09b0d92

Successfully tagged myapp_app:latest

This command builds the images for the services defined in the Docker Compose file. In this example, we have an app service that is built from a Dockerfile. The output shows the progress of the build and the resulting image ID and tag.

  1. docker-compose stop

$ docker-compose stop

Stopping myapp_app_1 ... done

Stopping myapp_db_1 ... done

This command stops all the containers defined in the Docker Compose file without removing them. In this example, we have an app service and a database service. The output shows that both services have been stopped.

  1. docker-compose rm

$ docker-compose rm

Going to remove myapp_app_1, myapp_db_1

Are you sure? [yN] y

Removing myapp_app_1 ... done

Removing myapp_db_1 ... done

This command removes all the containers defined in the Docker Compose file. In this example, we have an app service and a database service. The output shows that both services will be removed and asks for confirmation before proceeding.

These are just a few more examples of Docker Compose commands and their output. Docker Compose provides a rich set of commands that allow you to manage multi-container applications in a simple and consistent way.

Comments