参考视频:狂神说的Docker进阶篇 https://www.bilibili.com/video/BV1kv411q7Qc

简介

  • 我们自定义使用 Docker 时,需先编写 Dockerfile 文件,再使用 docker builddocker run 等命令操作容器。然而微服务架构的应用系统一般包含若干个微服务,每个微服务一般都会部署多个实例,如果每个微服务都要手动操作,那么维护量会很大而且效率会很低。
  • 使用 Docker Compose 可以轻松、高效的管理容器。

官网相关介绍:

Compose是一个用于定义和运行多容器Docker应用程序的工具。使用Compose,我们可以使用YAML文件来配置应用程序的服务。然后,只需一个命令,就可以从配置中创建并启动所有服务。

使用Compose基本上分为三步:

  1. 使用Dockerfile定义应用程序的环境,以便可以在任何地方复制。

  2. docker compose.yml中定义组成应用程序的服务,以便它们可以在隔离的环境中一起运行。

  3. 运行docker compose updocker compose命令启动并运行整个应用程序。我们也可以使用docker compose二进制文件运行docker compose up

Compose:重要概念

  • 服务services: 容器应用(web、redis、mysql…)
  • 项目project: 一组关联的容器

安装

下载:

1
2
3
4
5
# 官网提供 (没有下载成功)
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

# 推荐使用国内地址
curl -L https://get.daocloud.io/docker/compose/releases/download/1.29.2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

可到官网查看最新版本号

下载成功可在/usr/local/bin/目录下看到 docker-compose

授权:

1
2
#使docker-compose成为可执行文件
sudo chmod +x /usr/local/bin/docker-compose

查看版本号:

1
2
3
4
5
[root@nanzx bin]# docker-compose version
docker-compose version 1.29.2, build 5becea4c
docker-py version: 5.0.0
CPython version: 3.7.10
OpenSSL version: OpenSSL 1.1.0l 10 Sep 2019

体验

配置

定义应用程序依赖项。

在此页面上,将构建一个在 Docker Compose 上运行的简单 Python Web 应用程序。该应用程序使用 Flask 框架并在 Redis 中维护一个命中计数器。

1.为项目创建一个目录:

1
2
$ mkdir composetest
$ cd composetest

2.在composetest项目目录中创建一个名为app.py的文件并粘贴以下内容的文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import time

import redis
from flask import Flask

app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)

def get_hit_count():
retries = 5
while True:
try:
return cache.incr('hits')
except redis.exceptions.ConnectionError as exc:
if retries == 0:
raise exc
retries -= 1
time.sleep(0.5)

@app.route('/')
def hello():
count = get_hit_count()
return 'Hello World! I have been seen {} times.\n'.format(count)

3.在项目目录中创建另一个文件requirements.txt并粘贴以下内容的文件:

1
2
flask
redis

创建一个 Dockerfile

在此步骤中,将编写一个用于构建 Docker 映像的 Dockerfile。该图像包含 Python 应用程序所需的所有依赖项,包括 Python 本身。

在项目目录中,创建一个名为Dockerfile并粘贴以下内容的文件(注意:文件名一定要大小写一致):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#从 Python 3.7 映像开始构建映像
FROM python:3.7-alpine

#将工作目录设置为/code
WORKDIR /code

#设置flask命令使用的环境变量
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0

#安装 gcc 和其他依赖项
RUN apk add --no-cache gcc musl-dev linux-headers

#复制requirements.txt并安装 Python 依赖项
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt

#侦听端口 5000
EXPOSE 5000
#将.项目中的当前目录复制到.镜像中的workdir
COPY . .
#将容器的默认命令设置为flask run
CMD ["flask", "run"]

在 Compose 文件中定义服务

docker-compose.yml在项目目录中创建一个名为的文件并粘贴以下内容:

1
2
3
4
5
6
7
8
version: "3.9"
services:
web:
build: .
ports:
- "5000:5000"
redis:
image: "redis:alpine"

这个 Compose 文件定义了两个服务:web 和 redis

web服务使用从Dockerfile当前目录中构建的映像。然后它将容器和主机绑定到暴露的端口5000, 此示例服务使用 Flask Web 服务器的默认端口5000

redis服务使用 从 Docker Hub 注册表中提取的公共Redis映像。

使用 Compose 构建并运行应用程序

在项目目录,通过docker-compose up运行启动应用程序。

启动成功可以通过访问主机地址:5000看到:Hello World! I have been seen 1 times. 刷新页面数字应该递增。

切换到另一个终端窗口,然后键入docker image ls以列出本地镜像。

1
2
3
4
5
[root@nanzx ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
composetest_web latest 712a70388fb3 15 minutes ago 184MB
whyour/qinglong latest af93ec71ba86 5 days ago 364MB
python 3.7-alpine a436fb2c575c 5 days ago 41.9MB

通过键入docker ps以列出正在运行的容器:

  • 默认的服务名:项目目录名_ 服务名 _num
  • 多个服务器、集群:_num 副本数量(集群状态下,服务不可能只有一个运行实例)
1
2
3
4
[root@nanzx ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b2e8d7af2c81 composetest_web "flask run" 13 minutes ago Up 13 minutes 0.0.0.0:5000->5000/tcp, :::5000->5000/tcp composetest_web_1
dd96803c2f4a redis:alpine "docker-entrypoint.s…" 13 minutes ago Up 13 minutes 6379/tcp composetest_redis_1

通过键入docker network ls以列出docker的网络:

  • 项目中的服务都在同个网络下,可以通过容器名进行访问
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
[root@nanzx ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
cb43c4e5baa2 bridge bridge local
09c06a901a32 composetest_default bridge local
c5f5efea2089 host host local
b9e8be9bb948 none null local

[root@nanzx ~]# docker network inspect composetest_default
[
{
"Name": "composetest_default",
"Id": "09c06a901a3215d2c4d03b47f51ade034a22212bb8251133c5a32f41c605bc00",
"Created": "2021-09-13T22:31:16.22202105+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
}
]
},
"Internal": false,
"Attachable": true,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"b2e8d7af2c81f67962bc036878ef7df07ce8774ec38e53cd7bc45e857ba3ef62": {
"Name": "composetest_web_1",
"EndpointID": "4ee462ebcfe96a083593a10964651240023b1ea1b5a0610615935f733a80a9df",
"MacAddress": "02:42:ac:12:00:03",
"IPv4Address": "172.18.0.3/16",
"IPv6Address": ""
},
"dd96803c2f4ac049e50a555504b01d4706e5e6a57cb686202bcc11e1349bee76": {
"Name": "composetest_redis_1",
"EndpointID": "4d33c44c5dbe12084bff474af9f11e0a67b4bb8c3a32c81782410615e7b4f680",
"MacAddress": "02:42:ac:12:00:02",
"IPv4Address": "172.18.0.2/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {
"com.docker.compose.network": "default",
"com.docker.compose.project": "composetest",
"com.docker.compose.version": "1.29.2"
}
}
]

停止应用程序可以使用docker-compose down 或 Ctrl + C

小结:以前都是单个 docker run 启动容器,现在可以通过docker-compose一键启动和停止所有服务。

yaml规则

官网地址的右侧栏目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#yaml可以大致分为3层

# 1.版本
version: ''

# 2.服务
services:
服务1: web
#服务配置
images
build
network
...
服务2: redis
...

# 3.其他配置:网络/卷、全局配置等
volumes:
networks:
configs:

depends_on

表示服务之间的依赖关系。服务依赖会导致以下行为:

  • docker-compose up按依赖顺序启动服务。在下面的例子中,在 启动web之前先启动dbredis
  • docker-compose up SERVICE自动包含SERVICE的依赖项。在下面的示例中,docker-compose up web还创建并启动dbredis
  • docker-compose stop按依赖顺序停止服务。在以下示例中,webdbredis之前停止。

简单的例子:

1
2
3
4
5
6
7
8
9
10
11
version: "3.9"
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgres

使用时有几点需要注意:

  • depends_onweb启动之前不会等待dbredis“准备好”,仅在它们启动之前。
  • 在使用版本 3 Compose 文件以 swarm 模式部署堆栈时,将忽略depends_on该选项 。

一键部署WordPress博客

  1. 创建项目目录mkdir my_wordpress,进入目录cd my_wordpress

  2. 创建一个docker-compose.yml文件来启动 WordPress博客和一个单独的MySQL实例,该实例具有用于数据持久性的卷挂载:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    version: "3.9"

    services:
    db:
    image: mysql:5.7
    volumes:
    - db_data:/var/lib/mysql
    restart: always
    environment:
    MYSQL_ROOT_PASSWORD: somewordpress
    MYSQL_DATABASE: wordpress
    MYSQL_USER: wordpress
    MYSQL_PASSWORD: wordpress

    wordpress:
    depends_on:
    - db
    image: wordpress:latest
    volumes:
    - wordpress_data:/var/www/html
    ports:
    - "8000:80"
    restart: always
    environment:
    WORDPRESS_DB_HOST: db:3306
    WORDPRESS_DB_USER: wordpress
    WORDPRESS_DB_PASSWORD: wordpress
    WORDPRESS_DB_NAME: wordpress
    volumes:
    db_data: {}
    wordpress_data: {}

    注意事项:WordPress Multisite 仅适用于端口80443

  3. 通过docker-compose up -d运行启动应用程序,-d 参数可以在后台启动

  4. 通过访问主机地址:8000就可以访问博客

未完