Docker - Compose



Docker Compose is a tool specifically designed to simplify the management of multi-container Docker applications. It uses a YAML file in which the definition of services, networks, and volumes that an application requires is described.

Basically, through the docker-compose.yml file, we define the configuration for each container: build context, environment variables, ports to be exposed, and the relationship between services. Running all the defined services can be done by one command, the docker-compose up command, ensuring they work together accordingly.

Key Concepts of Docker Compose

Docker Compose introduces several essential concepts that are necessary to understand and be able to use the tool effectively. These consist of the architecture of a Docker Compose file written in YAML, services, networks, volumes, and environment variables. Lets discuss each of these concepts.

Docker Compose File Mechanism (YAML)

Ordinarily, the Docker Compose file would be a docker-compose.yml file using YAML. The file describes the configuration your application might require regarding services, networks, and volumes. It gives a guide on spinning up the environment the application will run under. Understanding the structure of this file is crucial for effectively using Docker Compose.

Key Elements of YAML File

  • Version − This defines the format of the Docker Compose file so that it ensures compatibility with different Docker Compose features.
  • Services − Contains lists of all services (containers) composing the application. Each service is described with uncounted configuration options.
  • Networks − It will specify custom networks for inter-container communication and may specify the configuration options and network drivers.
  • Volumes − Declares shared volumes that are used to allow persistent storage. Volumes can be shared between services or used to store data outside the container's lifecycle.

Example

version: '3.8'
services:
   web:
      image: nginx:latest
      ports:
         - "80:80"
      volumes:
         - web-data:/var/www/html
      networks:
         - webnet

   database:
      image: mysql:latest
      environment:
         MYSQL_ROOT_PASSWORD: example
      volumes:
         - db-data:/var/lib/mysql
      networks:
         - webnet

networks:
   webnet:
      driver: bridge

volumes:
   web-data:
   db-data:
Docker Compose File Mechanism (YAML)

Docker Compose Services

Services in Docker Compose represent the containers comprising the user's application. Each service is defined in the `services` section of the `docker-compose.yml` file and has its configuration such as a Docker image to use, variables within the environment, ports, volumes, and network settings.

Key Service Configuration Options

  • Image − This field specifies the Docker image that should be used for the service.
  • Build − Specifies the directory for a build context, thus allowing the specification to make an image or not pull from a registry.
  • Ports − maps host ports to the container.
  • Volumes − Attach volumes to your service for persistent storage.
  • Environment − Services environment variables.
  • Depends_on − Defines service dependencies so they are started in the appropriate order.

Example

services:
   app:
      image: myapp:latest
      build: .
      ports:
         - "8080:80"
      volumes:
         - app-data:/usr/src/app
      environment:
         - NODE_ENV=production
      depends_on:
         - db

   db:
      image: postgres:latest
      environment:
         POSTGRES_PASSWORD: example

Docker Compose Networks

Docker Compose networks allow for communication between services. By default, Docker Compose defines a single network for all services described under docker-compose.yml. However, you can define your custom networks to better control inter-service communication.

Best Network Configuration Options

  • driver − This specifies the driver to be used in the network (e.g., bridge, overlay).
  • driver_opts − Options for the network driver.
  • ipam − Specifies the IP address management configurations like subnets and IP ranges.

Example

networks:
   frontend:
      driver: bridge
   backend:
      driver: bridge

services:
   web:
      networks:
         - frontend

   api:
      networks:
         - frontend
         - backend

   db:
      networks:
         - backend

Docker Compose Volumes

Docker Compose uses volumes to persist data created or consumed by Docker containers. The volumes section in the docker-compose.yml file defines all the volumes attached to services for storing data in a way that its lifecycle exists outside of the container.

Key Volume Configuration Options

  • External − Indicates whether the volume is created outside Docker Compose.
  • Driver − Specifies the volume driver to use.
  • Driver_opts − Options to configure the volume driver.

Example

volumes:
   db-data:
   app-data:
      external: true

services:
   database:
      image: postgres:latest
      volumes:
         - db-data:/var/lib/postgresql/data

   app:
      image: myapp:latest
      volumes:
         - app-data:/usr/src/app

Docker Compose Environment Variables

Environment variables can be used in Docker Compose to pass configuration settings into services. These can be defined within a service's configuration as part of the `environment` section or loaded from an external file.

Basic Ways to Set Environment Variables

  • Inline − Register environment variables within your service definition.
  • env_file − This command allows environment variables to be loaded from an external file.

Example

services:
   web:
      image: myapp:latest
      environment:
         - NODE_ENV=production
         - API_KEY=12345

   database:
      image: postgres:latest
      env_file:
         - .env

In .env file −

POSTGRES_USER=myuser
POSTGRES_PASSWORD=mypassword
POSTGRES_DB=mydatabase

With a solid understanding of these basic principles, developers are well equipped to use Docker Compose in managing and orchestrating applications that are pretty complex and huge in terms of the number of Docker containers.

Important Docker Compose Commands

Docker Compose is a tool to manage Docker applications with useful commands and operations like start, stop, build, run, or execute another operation on one or several containers. In this section, lets understand the necessary Docker Compose commands, that are accompanied by an example.

Docker Compose Up Command

The docker-compose up command brings up and runs the entire application, as defined in the docker-compose.yml file while creating and starting all the services, networks, and volumes. In addition, if images of this service have never been built, it builds the necessary Docker images.

Example

$ docker-compose up
Docker Compose Up Command

Docker Compose Down Command

The command `docker-compose down` stops and removes all the containers, networks, and volumes defined in the `docker-compose.yml` file. So, this command helps in cleaning up the resources that your app has taken so far, in the sense that you're sure no residual container or network continues running somewhere.

$ docker-compose down
Docker Compose Down Command

Docker Build Command

This command is used to build or rebuild Docker images for services defined in the docker-compose.yml file. It runs when changes are made in a Dockerfile or source code; new images need to be created.

Example

$ docker-compose build

Docker Compose Start, Stop, Restart Commands

  • `docker-compose start` will start the already created containers without recreating them, bringing up previously stopped services.
  • `docker-compose stop` stops the currently running containers, without discarding them; thus, it is possible to restart the services later.
  • `docker-compose restart` is useful if you've brought changes to the environment or configuration and want to restart them.

Example

$ docker-compose start
$ docker-compose stop
$ docker-compose restart
Docker Compose Start, Stop, Restart Commands

Docker Compose Status Command

The docker-compose ps command shows the status of all services defined in the docker-compose.yml file, pointing out containers' statuses, their names, states, and ports. This command is used to inspect the current state of the services.

Example

$ docker-compose ps
Docker Compose Status Command

Docker Compose Logs Command

The command `docker-compose logs` gets and displays the bundle of all logs that define services in `docker-compose.yml`. It is essential for debugging and monitoring the application because this will primarily involve real-time output from executing containers.

Example

$ docker-compose logs
Docker Compose Logs Command

Docker Compose Exec Command

The docker-compose exec command runs arbitrary commands in a running service container. This can be handy for running system commands inside your application or executing scripts directly within the container.

Example

$ docker-compose exec <service_name> <command>
$ docker-compose exec web bash
Docker Compose Exec Command

Conclusion

In conclusion, Docker Compose is an indispensable tool for managing multi-container Docker applications, offering both simplicity for basic setups and powerful features for more complex scenarios.

Whether you are developing locally, deploying to production, or integrating with CI/CD pipelines, Docker Compose provides the flexibility and control needed to efficiently manage containerized applications.

FAQs on Docker Compose

1. How does Docker Compose handle dependencies between services?

Docker Compose automatically resolves dependencies between services when the depends_on property is used in the yml file. If one depends on another (for example, a web server and a database), Compose starts the dependant first, ensuring that the dependencies are up and running before starting the dependent service. That means no manual intervention is needed, and your app's startup is smooth.

2. Can I use Docker Compose in production environments?

While Docker Compose is primarily designed for development and testing, it can be used in production with some caveats. Compose does make it simple to deploy and scale applications, but it lacks capabilities needed for very large-scale production environments: such things as load balancing and rolling updates. Consider using tools like Docker Swarm or Kubernetes for orchestrating and managing large-scale, highly available containerized applications in a production situation.

Advertisements