Docker Compose
参考视频:编程不良人的Docker-Compose实战教程 https://www.bilibili.com/video/BV1ZT4y1K75K?p=24
简介
Compose是 Docker 官方的开源项目,可以轻松、高效的管理容器,实现对Docker容器集群的快速编排。定位是定义和运行多个Docker容器的应用。
我们自定义使用 Docker 时,需先编写 Dockerfile 文件,再使用
docker build
、docker run
等命令操作容器。然而微服务架构的应用系统一般包含若干个微服务,每个微服务一般都会部署多个实例,如果每个微服务都要手动操作,那么维护量会很大而且效率会很低。Compose项目由Python编写,实际上调用了Docker服务提供的API对容器进行管理。
官网相关介绍:
Compose是一个用于定义和运行多容器Docker应用程序的工具。使用Compose,我们可以使用YAML文件来配置应用程序的服务。然后,只需一个命令,就可以从配置中创建并启动所有服务。
使用Compose基本上分为三步:
使用
Dockerfile
定义应用程序的环境,以便可以在任何地方复制。在
docker compose.yml
中定义组成应用程序的服务,以便它们可以在隔离的环境中一起运行。运行
docker compose up
和docker compose命令启动并运行整个应用程序。我们也可以使用docker compose二进制文件运行docker compose up
。
Compose的重要概念:
- 服务(services): 应用容器(web、redis、mysql、nginx…)
- 项目(project): 由一组关联的应用容器组成的一个完整业务单元,在docker-compose.yml文件中定义
Compose的默认管理对象是项目,通过子命令对项目的一组容器进行便捷的生命周期管理。
安装与卸载
下载:
1 | 官网提供 (没有下载成功) |
可到官网查看最新版本号
下载成功可在/usr/local/bin/目录下看到 docker-compose
授权:
1 | 使docker-compose成为可执行文件 |
查看版本号:
1 | [root@nanzx bin]# docker-compose version |
卸载:
1 | sudo rm /usr/local/bin/docker-compose |
体验
配置
定义应用程序依赖项。
在此页面上,将构建一个在 Docker Compose 上运行的简单 Python Web 应用程序。该应用程序使用 Flask 框架并在 Redis 中维护一个命中计数器。
1.为项目创建一个目录:
1 | mkdir composetest |
2.在composetest
项目目录中创建一个名为app.py
的文件并粘贴以下内容的文件:
1 | import time |
3.在项目目录中创建另一个文件requirements.txt
并粘贴以下内容的文件:
1 | flask |
创建一个 Dockerfile
在此步骤中,将编写一个用于构建 Docker 映像的 Dockerfile。该图像包含 Python 应用程序所需的所有依赖项,包括 Python 本身。
在项目目录中,创建一个名为Dockerfile
并粘贴以下内容的文件(注意:文件名一定要大小写一致):
1 | #从 Python 3.7 映像开始构建映像 |
在 Compose 文件中定义服务
docker-compose.yml
在项目目录中创建一个名为的文件并粘贴以下内容:
1 | version: "3.9" |
这个 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 | [root@nanzx ~]# docker images |
通过键入docker ps
以列出正在运行的容器:
- 默认的服务名:项目目录名_ 服务名 _num
- 多个服务器、集群:_num 副本数量(集群状态下,服务不可能只有一个运行实例)
1 | [root@nanzx ~]# docker ps |
通过键入docker network ls
以列出docker的网络:
- 项目中的服务都在同个网络下,可以通过容器名进行访问
1 | [root@nanzx ~]# docker network ls |
停止应用程序可以使用docker-compose down
或 Ctrl + C
小结:以前都是单个 docker run 启动容器,现在可以通过docker-compose一键启动和停止所有服务。
常用模板指令
官网:version参考中间栏目,yaml规则具体参考右侧栏目
中文参考手册:https://docker_practice.gitee.io/zh-cn/
yaml模板
默认的模板文件名称为 docker-compose.yml
,格式为 YAML 格式。
1 | #yaml可以大致分为3层 |
注意:
- 每个服务都必须通过
image
指令指定镜像或build
指令(需要 Dockerfile)等来自动构建生成镜像。 - 如果使用
build
指令,在Dockerfile
中设置的选项(例如:CMD
,EXPOSE
,VOLUME
,ENV
等) 将会自动被获取,无需在docker-compose.yml
中重复设置。
container_name
指定容器名称。默认将会使用 项目名称_服务名称_序号
这样的格式。
1 | version: "3" |
注意: 指定容器名称后,该服务将无法进行扩展(scale),因为 Docker 不允许多个容器具有相同的名称。
image
指定为镜像名称或镜像 ID。如果镜像在本地不存在,Compose
将会尝试拉取这个镜像。
1 | image: ubuntu #REPOSITORY,不加版本号拉取最新版:latest |
build
指定 Dockerfile
所在文件夹的路径(可以是绝对路径,或者相对 docker-compose.yml 文件的路径)。 Compose
将会利用它自动构建这个镜像,然后使用这个镜像。
1 | version: '3' |
你也可以使用 context
指令指定 Dockerfile
所在文件夹的路径。
使用 dockerfile
指令指定 Dockerfile
文件名。
使用 arg
指令指定构建镜像时的变量。
1 | version: '3' |
ports
暴露端口信息。使用宿主端口:容器端口 (HOST:CONTAINER)
格式,或者仅仅指定容器的端口(宿主将会随机选择端口)都可以。
1 | ports: |
注意:当使用 HOST:CONTAINER
格式来映射端口时,如果你使用的容器端口小于 60 并且没放到引号里,可能会得到错误结果,因为 YAML
会自动解析 xx:yy
这种数字格式为 60 进制。为避免出现这种问题,建议数字串都采用引号包括起来的字符串格式。
volumes
数据卷所挂载路径设置。可以设置为宿主机路径(HOST:CONTAINER
)或者数据卷名称(VOLUME:CONTAINER
),并且可以设置访问模式 (HOST:CONTAINER:ro
)。
该指令中路径支持相对路径。
1 | volumes: |
如果路径为数据卷名称,必须在文件中配置数据卷。
1 | version: "3" |
networks
配置容器连接的网络。
1 | version: "3" |
environment
设置环境变量,可以使用数组或字典两种格式。
只给定名称的变量会自动获取运行 Compose 主机上对应变量的值,可以用来防止泄露不必要的数据。
1 | version: "3" |
如果变量名称或者值中用到 true|false,yes|no
等表达 布尔 含义的词汇,最好放到引号里,避免 YAML 自动解析某些内容为对应的布尔语义。这些特定词汇,包括:
1 | y|Y|yes|Yes|YES|n|N|no|No|NO|true|True|TRUE|false|False|FALSE|on|On|ON|off|Off|OFF |
env_file
从文件中获取环境变量,可以为单独的文件路径或列表。
如果通过
docker-compose -f FILE
方式来指定 Compose 模板文件,则env_file
中变量的路径会基于模板文件路径。如果有变量名称与
environment
指令冲突,则按照惯例,以后者为准。文件需要以
.env
结尾。
1 | version: "3" |
环境变量文件中每一行必须符合格式,支持 #
开头的注释行。
1 | # common.env: Set development environment |
command
覆盖容器启动后默认执行的命令。
1 | version: "3" |
depends_on
表示服务之间的依赖关系。服务依赖会导致以下行为:
docker-compose up
按依赖顺序启动服务。在下面的例子中,在 启动web
之前先启动db
和redis
。docker-compose up SERVICE
自动包含SERVICE
的依赖项。在下面的示例中,docker-compose up web
还创建并启动db
和redis
。docker-compose stop
按依赖顺序停止服务。在以下示例中,web
在db
和redis
之前停止。
简单的例子:
1 | version: "3.9" |
注意:
web
不会等待db
和redis
「完全启动」之后才启动。
healthcheck
通过命令检查容器是否健康运行。
有关如何进行健康检查的详细信息,请参阅 HEALTHCHECK Dockerfile 指令中的文档。
可通过docker-compose ps
的state查看健康检查的状态
1 | healthcheck: |
sysctls
配置容器内核参数。
1 | sysctls: |
ulimits
指定容器的 ulimits 限制值。
例如,指定最大进程数为 65535,指定文件句柄数为 20000(软限制,应用可以随时修改,不能超过硬限制) 和 40000(系统硬限制,只能 root 用户提高)。
1 | ulimits: |
常用命令
说明
命令对象与格式:
对于 Compose 来说,如果没有特别的说明,命令对象将是项目,这意味着项目中所有的服务都会受到命令影响。对象既可以是项目本身,也可以指定为项目中的服务或者容器,如:docker-compose mysql up
执行 docker-compose [COMMAND] --help
或者 docker-compose help [COMMAND]
可以查看具体某个命令的使用格式。
docker-compose
命令的基本的使用格式是
1 | docker-compose [-f=<arg>...] [options] [COMMAND] [ARGS...] |
命令选项:
-f, --file FILE
指定使用的 Compose 模板文件,默认为docker-compose.yml
,可以多次指定。-p, --project-name NAME
指定项目名称,默认将使用所在目录名称作为项目名。--x-networking
使用 Docker 的可拔插网络后端特性--x-network-driver DRIVER
指定网络后端的驱动,默认为bridge
--verbose
输出更多调试信息。-v, --version
打印版本并退出。
up
格式为 docker-compose up [options] [SERVICE...]
。
该命令十分强大,它将尝试自动完成包括构建镜像,(重新)创建服务,启动服务,并关联服务相关容器的一系列操作。
链接(依赖)的服务都将会被自动启动,除非已经处于运行状态。
可以说,大部分时候都可以直接通过该命令来启动一个项目。
默认情况,
docker-compose up
启动的容器都在前台,控制台将会同时打印所有容器的输出信息,可以很方便进行调试。当通过
Ctrl-C
停止命令时,所有容器将会停止。如果使用
docker-compose up -d
,将会在后台启动并运行所有的容器。一般推荐生产环境下使用该选项。默认情况,如果服务容器已经存在,
docker-compose up
将会尝试停止容器,然后重新创建(保持使用volumes-from
挂载的卷),以保证新启动的服务匹配docker-compose.yml
文件的最新内容
down
docker-compose down
- 此命令将会停止
up
命令所启动的容器,并移除网络(external的不会移除,自动创建的就会)
exec
docker-compose exec 服务名
- 进入指定的容器,不能指定容器id。
ps
格式为 docker-compose ps [options] [SERVICE...]
。
列出项目中目前的所有容器。
选项:
-q
只打印容器的 ID 信息。
restart
格式为 docker-compose restart [options] [SERVICE...]
。
重启项目中的服务。
选项:
-t, --timeout TIMEOUT
指定重启前停止容器的超时(默认为 10 秒)。
rm
格式为 docker-compose rm [options] [SERVICE...]
。
删除所有(停止状态的)服务容器。推荐先执行 docker-compose stop
命令来停止容器。
选项:
-f, --force
强制直接删除,包括非停止状态的容器。一般尽量不要使用该选项。-v
删除容器所挂载的数据卷。
start
格式为 docker-compose start [SERVICE...]
。
启动已经存在的服务容器。
stop
格式为 docker-compose stop [options] [SERVICE...]
。
停止已经处于运行状态的容器,但不删除它。通过 docker-compose start
可以再次启动这些容器。
选项:
-t, --timeout TIMEOUT
停止容器时候的超时(默认为 10 秒)。
top
docker-compose top
- 查看各个服务容器内运行的进程。
unpause
docker-compose unpause [SERVICE...]
。恢复处于暂停状态中的服务。
logs
docker-compose logs [SERVICE...]
。不加服务名查看全部日志。
一键部署WordPress博客
创建项目目录
mkdir my_wordpress
,进入目录cd my_wordpress
创建一个
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
31version: "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 仅适用于端口
80
和443
通过
docker-compose up -d
运行启动应用程序,-d 参数可以在后台启动通过访问主机地址:8000就可以访问博客