Implementation of Docker Compose multi-container deployment

Implementation of Docker Compose multi-container deployment

1. WordPress deployment

Here we take the deployment of wordpress as an example to introduce Docker Compose. The deployment of wordpress requires the images of wordpress and mysql:

1. Prepare the environment

1. Pull the wordpress image

[root@docker-node1 /]# docker pull wordpress

2. Pull the mysql image

[root@docker-node1 /]# docker pull mysql

3. Mirror list

[root@docker-node1 /]# docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
wordpress latest 0947f14b932b 25 hours ago 540MB
mysql latest 791b6e40940c 43 hours ago 465MB

(II) Run the image

1. Run mysql image

root@docker-node1 /]# docker run -d --name mysql -v mysql-data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=wordpress mysql
b6e7a57a5fcec79f436d3f65240adf833340b4a9640e3b4f9282870078fb8e57

In the above command, -v specifies the storage volume, MYSQL_ROOT_PASSWORD sets the database password, and MYSQL_DATABASE specifies the name of the created database. For details, refer to: https://hub.docker.com/_/mysql

View the started container:

[root@docker-node1 /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b6e7a57a5fce mysql "docker-entrypoint.s…" 6 minutes ago Up 6 minutes 3306/tcp, 33060/tcp mysql

2. Start the wordpress image

[root@docker-node1 /]# docker run --name wordpress -e WORDPRESS_DB_HOST=mysql:3306 --link mysql -p 8080:80 -d wordpress
6cf0c0fc2ef332728a3ea2bf2dbee65299441b26751d5c64f0a66b329f2679f6

In the above command, WORDPRESS_DB_HOST is the database to be connected, and the specified one is the MySQL container just created. No environment information such as the password of WORDPRESS_DB_USER and WORDPRESS_DB_PASSWORD is entered here, because the default username and password of the MySQL container are used. For details, see: https://hub.docker.com/_/wordpress.

Then view the container information:

[root@docker-node1 /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6cf0c0fc2ef3 wordpress "docker-entrypoint.s…" 3 minutes ago Up 3 minutes 0.0.0.0:8080->80/tcp wordpress
b6e7a57a5fce mysql "docker-entrypoint.s…" 20 minutes ago Up 20 minutes 3306/tcp, 33060/tcp mysql

Now both containers are up and you can access port 8080 of the host.

Docker Compose

From the above deployment, we can see the following problems:

  • You need to pull multiple containers separately and deploy them one by one
  • Need to manage multiple containers at the same time (including starting, stopping, etc.)

So is there a way similar to batch processing that does not require such a cumbersome process? This is where Docker Compose comes in.

1. Introduction to Docker Compose

1. What is Docker Compose?

Docker Compose is a tool

This tool can define multi-container applications through yml files

With one command, you can create and manage multiple containers according to the definition of the yml file.

2. docker-compose.yml file

A very important part of Docker Compose is the docker-compose.yml file, which contains three very important concepts: services, networks, and volumes.

services

A service is a container. This container can come from an image in Dockerhub or from an image created from a local Dockerfile. Starting a service is similar to starting a docker run. When we use docker run, we can specify the network and volume parameters for it. Similarly, we can also specify the network and volume for the service.

For example:

services:
  db:
    image:postgres:9.4
    volumes:
      -"db-data:/var/lib/postgresql/data"
    networks:
      -back-tier

The above yml file defines a service, which is equivalent to the following command:

docker run -d --network back-tier -v db-data:/var/lib/postgresql/data postgres:9.4

networks

networks:
  back-tier:
    driver:bridge

The above yml file defines a network, which is equivalent to the following command:

docker network create -d bridge back-tier

volumes

volumes:
  db-data:

The above yml file defines a volume, which is equivalent to the following command:

docker volume create db-data

(II) Docker Compose environment preparation

Docker Cmpose is a tool, so it needs to be installed. For installation details, refer to: https://docs.docker.com/compose/install/.

1. Download the executable file

sudo curl -L "https://github.com/docker/compose/releases/download/1.25.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

2. Set permissions

sudo chmod +x /usr/local/bin/docker-compose

3. Check the version

[root@docker-node1 ~]# docker-compose --version
docker-compose version 1.24.1, build 4667896

4. Common commands in docker-compose

[root@docker-node1 compose-wordpress]# docker-compose --help
Define and run multi-container applications with Docker.

Usage:
 docker-compose [-f <arg>...] [options] [COMMAND] [ARGS...]
 docker-compose -h|--help

Options:
 -f, --file FILE Specify an alternate compose file
               (default: docker-compose.yml)
 -p, --project-name NAME Specify an alternate project name
               (default: directory name)
 --verbose Show more output
 --log-level LEVEL Set log level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
 --no-ansi Do not print ANSI control characters
 -v, --version Print version and exit
 -H, --host HOST Daemon socket to connect to

 --tls Use TLS; implied by --tlsverify
 --tlscacert CA_PATH Trust certs signed only by this CA
 --tlscert CLIENT_CERT_PATH Path to TLS certificate file
 --tlskey TLS_KEY_PATH Path to TLS key file
 --tlsverify Use TLS and verify the remote
 --skip-hostname-check Don't check the daemon's hostname against the
               name specified in the client certificate
 --project-directory PATH Specify an alternate working directory
               (default: the path of the Compose file)
 --compatibility If set, Compose will attempt to convert keys
               in v3 files to their non-Swarm equivalent

Commands:
 build Build or rebuild services
 bundle Generate a Docker bundle from the Compose file
 config Validate and view the Compose file
 create Create services
 down Stop and remove containers, networks, images, and volumes
 events Receive real time events from containers
 exec Execute a command in a running container
 help Get help on a command
 images List images
 kill Kill containers
 logs View output from containers
 pause Pause services
 port Print the public port for a port binding
 ps List containers
 pull Pull service images
 push service images
 restart Restart services
 rm Remove stopped containers
 run Run a one-off command
 scale Set number of containers for a service
 start Start services
 stop Stop services
 top Display the running processes
 unpause Unpause services
 up Create and start containers
 version Show the Docker-Compose version information

docker-compose up

Used to start the service to create a container and execute the yml file

docker-compose -d

Background execution container service

docker-compose ps

Show running containers

docker-compose stop

Stop the running container service

docker-compose down

Stop the container service and remove the container, image, network, and volume.

docker-compose images

Display the image list of the container service created by docker-compose up

docker-compose exec container(Names) bash

Enter a container and perform operations inside the container

Docker Compose in action

1. WordPress

Write the docker-compose.yml file

version: '3' #docker-compose.yml version services: #Define multiple container services wordpress: #wordpress container name image: wordpress #Image source ports: #Port mapping - 8080:80
  environment: #Environment variables WORDPRESS_DB_HOST: mysql #The database to connect to is the name of the mysql container below WORDPRESS_DB_PASSWORD: root #Database password networks: #The network used is my-bridge defined in the networks below
   -my-bridge

 mysql: #mysql container nameimage: mysql #mysql imagecommand: --default-authentication-plugin=mysql_native_password #Solve the database password encryption problemenvironment: #Environment variableMYSQL_ROOT_PASSWORD: root
   MYSQL_DATABASE: wordpress
  volumes: #Define the storage volume, which is defined in the volumes below - mysql-data:/var/lib/mysql
  networks:
   -my-bridge

volumes:
 mysql-data:

networks:
 my-bridge:
  driver: bridge

Start the container in services

[root@docker-node1 compose-wordpress]# ls
docker-compose.yml
[root@docker-node1 compose-wordpress]# docker-compose up

Start the container by docker-compose up. This command executes the docker-compose.yml file in the current directory by default. You can also write the full command as docker-compose -f docker-compose.yml up

2. Flask Web

Create three files: app.py docker-compose.yml Dockerfile

[root@docker-node1 compose-flask]# ls
app.py docker-compose.yml Dockerfile

Write the app.py file

from flask import Flask
from redis import Redis
import os

app = Flask(__name__)
redis = Redis(host=os.environ.get('REDIS_HOST'),port=6379)

@app.route('/')
def hello():
  return 'Hello World'

if __name__ == "__main__":
  app.run(host="0.0.0.0",port=5000,debug=True)

Writing a Dockerfile

FROM python:2.7
COPY ./app/
WORKDIR /app/
RUN pip install flask redis
EXPOSE 5000
CMD ["python","app.py"]

Write the docker-compose.yml file

version: "3"

services:

 redis:
  image: redis

 web:
  build:
   context: .
   dockerfile: Dockerfile
  ports:
   - 8080:5000
  environment:
   REDIS_HOST: redis

Start the container service

[root@docker-node1 compose-flask]# docker-compose up

Access Services

4. Horizontal expansion and load balancing

1. Scale

The flask application deployment is completed above through Docker Compose. The currently running container is:

[root@docker-node1 compose-flask]# docker-compose ps
    Name Command State Ports     
---------------------------------------------------------------------------------------
compose-flask_redis_1 docker-entrypoint.sh redis ... Up 6379/tcp       
compose-flask_web_1 python app.py Up 0.0.0.0:8080->5000/tcp

Through the docker-compose --help command, you can see that there is a scale parameter:

[root@docker-node1 compose-flask]# docker-compose --help
  scale Set number of containers for a service

This means that multiple application containers can be enabled:

[root@docker-node1 compose-flask]# docker-compose up --scale web=3 -d

But this obviously goes wrong, why? Because the port mappings of the three containers are the same, the remaining two application containers will inevitably report port occupied errors. At this point, you need to modify the docker-compose.yml file to remove the port configuration of the web application:

version: "3"

services:

 redis:
  image: redis

 web:
  build:
   context: .
   dockerfile: Dockerfile
  ports: #Remove this item - 8080:5000
  environment:
   REDIS_HOST: redis

That's it.

[root@docker-node1 compose-flask]# docker-compose up --scale web=3 -d
Recreating compose-flask_web_1 ... 
Recreating compose-flask_web_1 ... done
Recreating compose-flask_web_2 ... done
Recreating compose-flask_web_3 ... done

View the container:

[root@docker-node1 compose-flask]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d0ae3307eb9e compose-flask_web "python app.py" 51 seconds ago Up 46 seconds 5000/tcp compose-flask_web_1
67483b8decd3 compose-flask_web "python app.py" 52 seconds ago Up 47 seconds 5000/tcp compose-flask_web_2
741766d49902 compose-flask_web "python app.py" 52 seconds ago Up 47 seconds 5000/tcp compose-flask_web_3
be3800004658 redis "docker-entrypoint.s…" 5 hours ago Up 6 minutes 6379/tcp compose-flask_redis_1

But obviously this can only be accessed within the container because the port is not mapped, so what should we do next?

We can do this next, use an HAProxy container to receive requests, and then forward them to different web servers through ports, which solves the following problems:

  • Cannot be accessed from outside, can only be accessed from within the container
  • Load Balancing

2. Horizontal expansion and load balancing

File Structure

[root@docker-node1 compose-flask]# ls
app.py docker-compose.yml Dockerfile

Write app.py

from flask import Flask
from redis import Redis
import os

app = Flask(__name__)
redis = Redis(host=os.environ.get('REDIS_HOST'),port=6379)

@app.route('/')
def hello():
  return 'Hello World'

if __name__ == "__main__":
  app.run(host="0.0.0.0",port=80,debug=True)

Writing a Dockerfile

FROM python:2.7
COPY ./app/
WORKDIR /app/
RUN pip install flask redis
EXPOSE 80
CMD ["python","app.py"]

Write the docker-compose.yml file

version: "3"

services:

 redis:
  image: redis

 web:
  build:
   context: .
   dockerfile: Dockerfile
  environment:
   REDIS_HOST: redis

 lb:
  image: dockercloud/haproxy
  links:
   - web
  ports:
   -8080:80
  volumes:
   - /var/run/docker.sock:/var/run/docker.sock

run

[root@docker-node1 compose-flask]# docker-compose up -d
Creating network "compose-flask_default" with the default driver
Creating compose-flask_web_1 ... done
Creating compose-flask_redis_1 ... done
Creating compose-flask_lb_1 ... done

You can see that three containers are started:

[root@docker-node1 compose-flask]# docker-compose ps
    Name Command State Ports        
---------------------------------------------------------------------------------------------------
compose-flask_lb_1 /sbin/tini --dockercloud- ... Up 1936/tcp, 443/tcp,        
                                 0.0.0.0:8080->80/tcp       
compose-flask_redis_1 docker-entrypoint.sh redis ... Up 6379/tcp             
compose-flask_web_1 python app.py Up 5000/tcp

We can see that there is only one web application at present, and multiple ones can be started to handle requests:

[root@docker-node1 compose-flask]# docker-compose up --scale web=5 -d
compose-flask_redis_1 is up-to-date
Starting compose-flask_web_1 ... done
Creating compose-flask_web_2 ... done
Creating compose-flask_web_3 ... done
Creating compose-flask_web_4 ... done
Creating compose-flask_web_5 ... done
compose-flask_lb_1 is up-to-date

As you can see, five containers are started directly for the web application to share the requests from HAProxy.

This is the end of this article about the implementation of Docker Compose multi-container deployment. For more information about Docker Compose multi-container deployment, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope you will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Detailed example of Docker Compose's rapid deployment of multi-container services
  • Implementation of master-slave replication in docker compose deployment
  • Using Docker Compose to build and deploy ElasticSearch configuration process

<<:  Implementation of scheduled backup in Mysql5.7

>>:  Analysis of the Principles of MySQL Slow Query Related Parameters

Recommend

3 simple ways to achieve carousel effects with JS

This article shares 3 methods to achieve the spec...

A brief discussion on CSS blocking merging and other effects

Non-orthogonal margins When margin is used, it wi...

An article to understand the usage of typeof in js

Table of contents Base Return Type String and Boo...

Analysis of idea compiler vue indentation error problem scenario

Project scenario: When running the Vue project, t...

How to delete extra kernels in Ubuntu

Step 1: View the current kernel rew $ uname -a Li...

Introduction to installing and configuring JDK under CentOS system

Table of contents Preface Check and uninstall Ope...

Example code for using text-align and margin: 0 auto to center in CSS

Use text-align, margin: 0 auto to center in CSS W...

This article will help you understand JavaScript variables and data types

Table of contents Preface: Kind tips: variable 1....

JS realizes the front-end paging effect

This article example shares the specific code of ...