Docker compose introduction
Docker Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application’s services. Then, with a single command, you create and start all the services from your configuration.
The features of Docker Compose that make it effective are:
Multiple isolated environments on a single host
Preserve volume data when containers are created
Only recreate containers that have changed
Variables and moving a composition between environments
Prerequisites
Install Docker Compose: Installing Docker Engine and Docker Compose
Understand images and containers basics: Your first Docker Hub image from scratch
Understand NGINX basics: Install and configure Nginx
Docker Compose file structure
Docker Compose files work by applying multiple commands that are declared within a single docker-compose.yml configuration file. The basic structure of a Docker Compose YAML file looks like this:
version: "X" #optional since v1.27.0
services:
...
volumes:
...
networks:
...
Services: refer to containers' configuration. Multiple settings can be applied here
Volumes: physical areas of disk space shared between the host and a container
Networks: communication rules between containers and between a container and the host
Let's focus on setting up containers using the services section. Here are some of the common directives used to set up and configure containers:
image: sets the image and the version that will be used to build the container. Using this directive assumes that the specified image already exists either on the host or on Docker Hub
build: this directive can be used instead of image. Specifies the location of the Dockerfile that will be used to build this container
container_name: defines a name for the container, which corresponds to the name of the service
volumes: mounts a linked path on the host machine that can be used by the container
environment: define environment variables to be passed to the container
depends_on: sets a service as a dependency, so that some services get loaded before other ones
port: maps a port from the container to the host using the structure host_ip:container_ip
links: link this service to any other services in the Docker Compose file by specifying their names here
The docker-compose command works on a per-directory basis. You can have multiple groups of Docker containers running on one machine — just make one directory for each container and one docker-compose.yml file for each directory.
Docker Compose file example
Let's create a Docker Compose configuration file to run NGINX server with PHP-FPM and have MySQL as database.
We've defined three services in our docker-compose.yml configuration file: nginx, php and mysql. All of them are built using official images available in Docker Hub repository:
services:
nginx:
image: nginx:1.21.4
container_name: hibit_nginx
ports:
- "80:80"
- "443:443"
volumes:
- ./repo:/var/www
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx/ssl:/etc/nginx/ssl/
working_dir: /var/www
links:
- php
php:
image: php:8.1.0-fpm
container_name: hibit_php
volumes:
- ./repo:/var/www
working_dir: /var/www
links:
- mysql
mysql:
image: mysql:5.7.36
container_name: hibit_mysql
ports:
- "3306:3306"
volumes:
- ./mysql:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=root_password
Let's analyse and understand each of the services:
nginx: we are pulling official NGINX (v1.21.4) and calling the container hibit_nginx. Port forwarding is done for both type of connections: standard and secure. We've also defined three volumes: for the project code, the NGINX site configuration and NGINX SSL configuration. Working directory in the container is set to /var/www and link with php service is created.
php: we are pulling official PHP-FPM (v8.1) and calling the container hibit_php. There is only one volume defined, for the project code. Working directory in the container is set to /var/www and link with mysql service is created.
mysql: we are pulling official MySQL (v5.7.36) and calling the container hibit_mysql. Defined volume persists the contents of the /var/lib/mysql folder present inside the container on the host. This allows you to stop and restart the database service without losing data. Finally, we define an environment variable MYSQL_ROOT_PASSWORD to correctly establish the connection.
Docker Compose commands
Once our configuration file is ready, startup Docker Compose from the same directory (this commands includes the build and run and can be used separately):
docker-compose up -d
After the first time, however, we can simply use start to start the services:
docker-compose start -d
Note: the -d flag starts the container in detached mode.
At this point, you can visit localhost in your browser and it will load the project you have in repo folder:
To show your Docker containers (including stopped ones), use the following command:
docker-compose ps -a
Note: if a container is stopped, the State will be listed as Exited.
To make a change to the filesystem inside some container, you’d take its ID (or easier the name) and use docker exec to start a shell inside the container:
docker exec -ti [CONTAINER_ID|CONTAINER_NAME] bash
Note: the flag -t opens up a terminal and the -i makes it interactive.
Replace the CONTAINER_ID or CONTAINER_NAME with the corresponding value. In the example below, we access the PHP container and check the version we have installed inside:
docker exec -ti hibit_php bash
To stop the active services preserving containers, volumes and networks, along with every modification made to them we must use the stop command:
docker-compose stop
In the case you want to discard the changes and destroy everything, run:
docker-compose down
Conclusion
You’ve now installed Docker Compose, tested an example and explored some basic commands. Of course, Docker Compose has advanced configurations that makes it very powerful tool to use.
0 Comments