When you use Docker and you have to handle many different containers, their management is complicated. You need to manage the configuration and the functioning of each container separately. When you need to use your containers in a specific environment, you’ll set a specific configuration for each of your containers. Docker Compose promises to solve this problem.
What is Docker Compose?
First what is Docker Compose? Compose is a tool. This tool defines and runs multi-container Docker applications. This means they are run via one single command. You can also easily start and stop multi-containers with one single command. This tool has different features which make it effective.
How to use it?
Before you can use it, you need to install Docker and Docker Compose. For the installation on your system you can refer to the official documentation of Docker.
Now you need to either define a
dockerfile that defines the environment of your application or to use an already existing container.
Secondly, you need to define a yaml configuration file. It contains the information of the configuration.
The yaml configuration file is a file that contains rules for Docker Compose. These rules are easily readable by machines and human beings. The file has a specific structure. You need to specify the version of the compose file format and at least one service. Information about the volumes and networks are optional.
Services are a direct reference to the configuration of the container. For example, a dockerized web application has a front end service, a back end service and a database. In your configuration, it will be separated like in the below configuration:
services: frontend: image: angular-app backend: image: springboot-app db: image: store/oracle/database-enterprise:184.108.40.206
In the services, there are different settings. The image name is used when the service is already published in https://hub.docker.com/ or in another Docker Registry. You need to refer to the service by specifying the name and tag of the image.
Services: db: image: store/oracle/database-enterprise:220.127.116.11
When you need to build an image from the source code via Dockerfile, the build setting needs a path or a URL to the
services: db: build: /path/to/dockerfile
The network setting allows you to define the port that is accessible from the container to other services or with the host directly. The difference between the two cases is the keyword expose for the communication between containers.
services: network-example-service: image: karthequian/helloworld:latest expose: - "80"
For the second case you need the keyword ports to access a container from the host.
services: network-example-service: image: karthequian/helloworld:latest ports: - "80 :80"
The first number defines the port that is visible on the host, the second number defines the port inside the container.
Volumes are storage areas of disk space shared between the host machine and a container, or between containers. It is a shared directory on the host. In the same way, the networks define how the communication is routed between the container and the host machine.
For the volumes, there are three types: anonymous, named and host. Anonymous and named volumes will automatically mount themselves in self-generated directories on the host.
The last one allows you to specify an existing folder on the host. You can mount a volume in read-only mode by appending “:ro”.
volumes: - /oradata:/ORCL - /home/user/sql_exports:/dbscripts
The keyword depends_on allows you to create a dependency chain between the different services. So some services will be loaded before other ones.
The keyword environment allows you to define static environment variables for the container.
For example, an environment for an Oracle container:
environment: - DB_SID=XE - DB_PDB=MYPDB - DB_MEMORY=8GB
Lastly, run on the command line:
An example yaml configuration file looks like this:
version: '2' services: web: build: . ports: - "5000:5000" volumes: - .:/code redis: image: redis
Here are all functions of Docker-Compose:
The most important commands are down, logs, start, stop, and up.
Compose has different features. The principal ones are the following:
- Uses different environments on the same host
When you work in a project, you have different environments in the most cases. Compose uses a project name to isolate environments from each other. The default project name is the base name of the project directory. You can set a specific project name by using the option “-p projectName”.
- Keeps volume data on the creation of containers
Compose keeps all data used by your services. When you create and start your containers, if the tool finds any containers from previous runs it copies the information of the old container to the new one. So it is ensured that any previous data created in volumes isn’t lost.
- Only recreates containers if they are changed
The tool only recreates containers if they were changed. In other cases, it will re-use the existing containers.
- Customizes your composition for each environment
The means that you can have the same configuration file that can be overridden for each environment.
First you have a base file that defines the canonical configuration for the services.
web: image: example/my_web_app:latest depends_on: - db - cache db: image: postgres:latest cache: image: redis:latest
In this example, the specific configuration exposes some ports.
web: build: . volumes: - '.:/code' ports: - 8883:80 environment: DEBUG: 'true' db: command: '-d' ports: - 5432:5432 cache: ports: - 6379:6379
When you run docker-compose up, it reads this file automatically.
To use this configuration in production environment, you need another override file.
web: ports: - 80:80 environment: PRODUCTION: 'true' cache: environment: TTL: '500'
To use this compose file you can run this command:
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
The previous section shows an example of the usage of this tool. This example demonstrates the possibility of working in an isolated environment and interact with it. This tool can be used in many different ways.
In an isolated environment, you can run your test suite. Compose provides a way to create and destroy this environment. By defining a Compose file, you can create/destroy these environments with a few commands.
You can use Compose to deploy to a remote Docker Engine. The Docker Engine may be a single instance provisioned with Docker Machine or an entire Docker Swarm cluster.