一、Docker Compose 背景
对于一个稍微完整的系统而言,一般都不会只有一个应用,比如说一个正常的应用系统,基本上都有容器应用(tomcat或者nginx)、mysql、redis等,对于微服务而言,又有更多了。
但是 Docker 是轻量级容器,一般每个容器只运行一个应用,搭建多个系统之间的交互和管理,命令是非常复杂的。
针对这种情况,就可以使用开发中最常使用的多容器定义运行软件 Docker Compose。
二、Docker Compose 介绍
如果说 Dockerfile 是将容器内运行环境的搭建固化下来,那么 Docker Compose 就是将多个容器运行的方式和配置固化下来。
在 Docker Compose 里,可以通过一个配置文件,将所有与应用系统相关的软件及它们对应的容器的配置定义到这个配置文件中,之后使用 Docker Compose 提供的命令进行启动,就能让 Docker Compose 执行配置中定义的运行流程与配置。
三、安装
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.22.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
# 查看版本
$ sudo docker-compose version
docker-compose version 1.22.0, build f46880fe
docker-py version: 3.4.1
CPython version: 3.6.6
OpenSSL version: OpenSSL 1.1.0f 25 May 2017
Docker Compose 是一个由 Python 编写的软件,在拥有 Python 运行环境的机器上,也可以通过 Python 的包管理工具 pip 来安装 Docker Compose:
$ sudo pip install docker-compose
四、Docker Compose 使用步骤
- 编写容器所需镜像的 Dockerfile(也可以使用现有的镜像)
- 编写用于配置容器的 docker-compose.yml
- 使用 docker-compose 命令启动应用
五、Docker Compose 配置文件
Docker Compose 的配置文件是一个基于 YAML 格式的文件,默认名称是 : docker-compose.yml
,例如:
# 当前 docker-compose.yml 文件内容所采用的版本
version: '3'
services:
webapp:
build: ./image/webapp
ports:
- "5000:5000"
volumes:
- ./code:/code
- logvolume:/var/log
links:
- mysql
- redis
redis:
image: redis:3.2
mysql:
image: mysql:5.7
environment:
- MYSQL_ROOT_PASSWORD=my-secret-pw
volumes:
logvolume: {}
在 Docker Compose 里不直接体现容器这个概念,里面的 services 代表的是一个应用集群的配置,services 由一个或多个 service 组成,把 service 作为配置的最小单元,每个 service 里的配置内容就像是在配置容器。
每个 service 定义的内容,可以通过特定的配置进行水平扩充,将同样的容器复制数份形成一个容器集群。而 Docker Compose 能够对这个集群做到黑盒效果,让其他的应用和容器无法感知它们的具体结构。
六、启动和停止
启动
启动 Docker Compose 的命令是 docker-compose up
,它会根据 docker-compose.yml 中配置的内容,创建所有的容器、网络、数据卷等等内容,并将它们启动。默认情况下 docker-compose up
会在“前台”运行,可以用 -d
选项使其“后台”运行:
$ sudo docker-compose up -d
docker-compose
命令默认会识别当前控制台所在目录内的 docker-compose.yml 文件,会以这个目录的名字作为组装的应用项目的名称。可以通过选项 -f
来修改 Docker Compose 配置文件,通过 -p
选项来定义项目名:
$ sudo docker-compose -f ./compose/docker-compose.yml -p myapp up -d
停止
停止所有对应的容器可以使用 docker-compose down
命令,并将它们删除,同时消除网络等配置内容,也就是几乎将这个 Docker Compose 项目的所有影响从 Docker 中清除。
$ sudo docker-compose down
建议在使用的时候随启随停,也就是在使用的时候通过 docker-compose up
进行,而短时间内不再需要时,通过 docker-compose down
清理它。
七、容器相关命令
1、查看其中某个容器主进程输出内容
$ sudo docker-compose logs 容器名
单独控制 Docker Compose 里面某个容器
# 创建容器
$ sudo docker-compose create 容器名
# 启动容器
$ sudo docker-compose start 容器名
# 停止容器
$ sudo docker-compose stop 容器名
八、指定镜像
每个服务都必须指定镜像,在 Docker Compose 里,有两种方式为服务指定镜像:
1、通过 image 配置
这种方式只需要指定镜像名就可以了:
version: "3"
services:
redis:
image: redis:3.2
# ....
2、采用 Dockerfile 来构建镜像
这种方式需要通过 build 定义构建的环境目录,这 docker build
中的环境目录是同一个含义。如果通过这种方式指定镜像,那么 Docker Compose 先会执行镜像的构建,之后再通过这个镜像启动容器。在 docker build
可以用的选项在 Docker Compose 里也可以使用:
version: "3"
services:
webapp:
build:
context: ./webapp
dockerfile: webapp-dockerfile
args:
- JAVA_VERSION=1.6
## ......
九、依赖声明
虽然在 Docker Compose 的配置文件里定义的服务是有定义顺序的,但实际在容器启动中,由于各种因素的存在,其顺序还是无法保障的。
所以,如果服务间有非常强的依赖关系,设置 Docker Compose 容器的先后启动顺序。只有当被依赖的容器完全启动后,Docker Compose 才会创建和启动对应容器。
通过 depends_on
选项配置项定义依赖,只需要通过它列出这个服务所有依赖的其他服务即可。在 Docker Compose 启动项目的时候,会检查所有依赖,形成正确的启动顺序并按这个顺序来依次启动容器。
version: "3"
services:
webapp:
# ...
nginx:
# ....
depends_on:
- webapp
# ...
这里的 nginx 就依赖 webapp。
十、文件挂载
Docker Compose 中的文件挂载基本上是与 Docker Engine 一样的,都是使用 volumes 配置,也可以像 Docker Engine 一样使用选项。
version: "3"
services:
redis:
# ...
volumes:
- ./redis/redis.conf:/etc/redis.conf:ro
# ...
在使用外部文件挂载的时候,除了使用绝对路径之外,也可以使用相对路径进行挂载,相对路径是相对于 docker-compose.yml 文件的目录。
由于有相对目录这样的机制,可以将 docker-compose.yml 和所有相关的挂载文件放置到同一个文件夹下,形成一个完整的项目文件夹。这样既可以很好的整理项目文件,也利于完整的进行项目迁移。
虽然 Docker 提倡将代码或编译好的程序通过构建镜像的方式打包到镜像里,但对于开发来说,每次修改程序进行简单测试都要重新构建镜像是很浪费时间的。所以在开发时建议直接将代码挂载到容器里,而不是通过镜像构建的方式打包成镜像。
同时,在开发过程中,对于程序的配置等内容,建议直接使用文件挂载的形式挂载到容器里,避免经常修改所带来的麻烦。
十一、使用数据卷
如果要在项目中使用数据卷来存放特殊的数据,也可以让 Docker Compose 自动完成对数据卷的创建。
如果想把属于 Docker Compose 项目以外的数据卷引入进来直接使用,可以将数据卷定义为外部引入,通过 external 这个配置就能完成这个定义。
## ......
volumes:
mysql-data:
external: true
## ......
在加入 external 定义后,Docker Compose 在创建项目时不会直接创建数据卷,而是优先从 Docker Engine 中已有的数据卷里寻找并直接采用。
十二、配置网络
在 Docker Compose 里,可以为整个应用系统设置一个或多个网络。要使用网络,必须先声明网络。声明网络的配置同样独立于 services 存在,是位于根配置下的 networks 配置。
version: "3"
services:
# ...
networks:
frontend:
backend:
# ...
除了简单的声明网络名称,让 Docker Compose 自动按默认形式完成网络配置外,还可以显式的指定网络的参数。
networks:
frontend:
# 定义了网络驱动的类型
driver: bridge
ipam:
driver: default
config:
# 指定子网段
- subnet: 10.10.1.0/24
## ......
在某一个 service 中指定网络:
version: "3"
services:
redis:
image: redis:3.2
networks:
- backend
# ...
十三、使用网络别名
直接使用容器名或服务名来作为连接其他服务的网络地址,因为缺乏灵活性,不能满足某些特定的需要。这时候可以为服务单独设置网络别名,在其他容器里将这个别名作为网络地址进行访问。
version: "3"
services:
database:
networks:
backend:
aliases:
- backend.database
## ......
webapp:
networks:
backend:
aliases:
- backend.webapp
frontend:
aliases:
- frontend.webapp
## ......
十四、端口映射
在 Docker Compose 中使用端口映射是与 Docker Engine 差不多的:
version: "3"
services:
redis:
# ...
ports:
- "6379:6379"
# ...
需要注意的是,由于 YAML 格式对 xx:yy 这种格式的解析有特殊性,在设置小于 60 的值时,会被当成时间而不是字符串来处理,所以最好使用引号将端口映射的定义包裹起来,避免歧义。
十五、使用 docker compose 管理 java web 项目
demo : https://blog.csdn.net/qq_37502106/article/details/103547492