Docker Compose 是 Docker 官方编排(Orchestration)项目之一,负责快速的部署分布式应用,它是由 python
编写。javascript
Compose
定位是定义和运行多个 Docker 容器的应用。java
Compose
有两个重点node
docker-compose.yml
compose
配置文件docker-compose
命令行工具在前面的教程中,咱们运行一个要一堆的参数,如 --network
, --volume
, -p
等等,若是有多个容器组合成一个项目,好比一个 webserver,数据库,缓存等等容器,咱们就须要一个个的定义网络等参数,而后一个个启动,有了 compose
咱们只须要一个简单的 docker-compose up
,它就会自动帮咱们构建镜像,配置网络等功能。python
windows 和 mac 中 docker-compose
在安装 docker
的时候就已经捆绑安装了。mysql
linux 中须要本身安装,不过很是的简单只须要几条命令就行linux
$ sudo curl -L https://github.com/docker/compose/releases/download/1.17.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
# 下载 docker-compose 到 /usr/local/bin/docker-compose 中
$ sudo chmod +x /usr/local/bin/docker-compose
# 给 docker-compose 执行权限
$ curl -L https://raw.githubusercontent.com/docker/compose/1.8.0/contrib/completion/bash/docker-compose > /etc/bash_completion.d/docker-compose
# bash 自动补全
复制代码
$ sudo rm /usr/local/bin/docker-compose
# 卸载 docker-compose
复制代码
使用 docker-compose
咱们主要的任务是编写 docker-compose.yml
文件。咱们能够看一个 WordPress
yaml文件模板。git
version: '3' # 定义版本,不指定默认为版本 1,新版本功能更多
services: # 容器,就像 docker run
db: # 名称,它也是 network 中 DNS 名称
image: mysql:5.7 # 镜像,若是像自定义镜像能够不指定这个参数,而用 build
volumes: # 定义数据卷,相似 -v
- db_data:/var/lib/mysql
- .:/aaa # 挂载当前目录到容器中的 /aaa 无需使用绝对路径
restart: always # 相似 --restart
# 'no' 默认,不自动重启,觉得 no 是 yaml 关键字因此加引号
# always 老是自动重启
# on-failure 当失败时自动重启,也就是 exit code 不为 0 时
# unless-stopped 除非手动中止,否者一直重启
environment: # 定义环境变量,相似 -e
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress: # 第二个容器
labels:
com.example.description: "This label will appear on all containers for the web service"
# 为容器添加 Docker 元数据(metadata)信息。例如能够为容器添加辅助说明信息。
depends_on: # 帮助 compose 理解容器之间的关系
# db 将会在 wordpress 以前被启动
# 关闭时 wordpress 将会在 db 以前关闭
# 咱们指定只启动 wordpress,db 也会跟着启动
- db
image: wordpress:latest
ports: # 端口,相似 -p
- "8000:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
volumes: # 可选,须要建立的数据卷,相似 docker volume create
db_data:
networks: # 可选,须要建立的网络,相似 docker network create
复制代码
若是不了解 yaml
文件,可使用在线 yaml
转换成 json
。github
咱们如今使用 nodejs
和 redis
写一个简单的,web 应用。web
咱们须要 nodejs
环境,而后新建一个文件夹执行redis
$ npm init -y # 新建 package.json 文件
$ npm i -S koa ioredis # 安装 koa 和 ioredis 依赖
# koa 用来编写 web 应用
# ioredis 用来链接 redis
复制代码
而后咱们新建 index.js
文件,写入以下代码
const Koa = require('koa');
const Redis = require('ioredis');
const app = new Koa();
const redis = new Redis({
host: 'redis',
});
app.use(async ctx => {
ctx.body = '计数:' + (~~(await redis.get('count')) + 1);
redis.incr('count');
});
app.listen(3000, () => {
console.log('app 正在监听 3000 端口');
});
复制代码
而后新建一个 .dockerignore
文件
.vscode
.idea
node_modules
npm-debug.log*
yarn-debug.log*
yarn-error.log*
复制代码
还有 Dockerfile
文件
FROM node:alpine
WORKDIR /app
COPY package.json . RUN npm i --registry=https://registry.npm.taobao.org && npm cache --force clean COPY . .
EXPOSE 3000
CMD ["node", "index.js"] 复制代码
最后就是编写 docker-compose.yml
文件啦
version: '3'
services:
redis:
image: 'redis'
app:
build: . # 至关于 docker build .
ports:
- '3000:3000'
depends_on:
- redis
复制代码
咱们上面要构建自定义镜像使用了 build
字段,若是要自定义 Dockerfile
咱们能够写做一个 map。
build:
context: ./dir # 指定上下文
dockerfile: Dockerfile.dev # 指定 Dockerfile
args: # 相似 Dockerfile 中的 ARG 指令。
# 定义变量,不一样于环境不按量只能在构建时访问
gitcommithash: cdc3b19
target: prod # docker build 中的 --target 参数
复制代码
如今咱们就可使用 docker-compose
命令行工具启动咱们这个应用了。
$ docker-compose up
# 启动咱们这个项目
# `-d` 相似 docker run -d
# `--build` 在启动容器以前构建镜像
# 若是咱们修改了 Dockerfile 从新运行项目时,不会从新构建
# 这时候就须要 --build 命令,或者 `docker-compose build` 命令
复制代码
而后咱们打开浏览器 127.0.0.1:3000
而后不断刷新,就会看到计数器不断增长。
$ docker ps
CONTAINER ID IMAGE COMMAND PORTS NAMES
782b26312c72 redis "docker-entrypoint.s…" 6379/tcp compose1_redis_1
af93df76b5a0 compose1_app "docker-entrypoint.s…" 0.0.0.0:3000->3000/tcp compose1_app_1
复制代码
咱们发现 docker-compose
自动生成容器名称,若是咱们像本身指定容器名,可使用
container_name: my-web-container
复制代码
docker-compose
还帮咱们生成了本身构建镜像的镜像名,咱们若是想自定义,能够在指定 build
的同时指定 image
字段。
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
66cccb01394d compose1_default bridge local
复制代码
咱们发现 docker-compose
自动新建了 compose1_default
虚拟网络
$ docker network inspect compose1_default
...
"Containers": {
"1e10e7af6bf78ef1ecdd979c1f5d386e9d5a8221d3be49df05a13cea1f40f655": {
"Name": "compose1_app_1",
"EndpointID": "b20772ce05b34fb528b2986946c9535d467c9d09a6d66aeba9fdb9c8809f0909",
"MacAddress": "02:42:ac:14:00:03",
"IPv4Address": "172.20.0.3/16",
"IPv6Address": ""
},
"95b1592f453dd57d091456b9e623fae1aadc180599c5b343c7133ef8c61f3605": {
"Name": "compose1_redis_1",
"EndpointID": "5a86cdb12a84fd49de4b586bed1281cdec61cd45dc08ad230f46db8562ced722",
"MacAddress": "02:42:ac:14:00:02",
"IPv4Address": "172.20.0.2/16",
"IPv6Address": ""
}
}
...
复制代码
而且自动将咱们两个容器加入到这个网络中。
$ docker container inspect compose1_redis_1
...
"Networks": {
"compose1_default": {
"IPAMConfig": null,
"Links": null,
"Aliases": [
"95b1592f453d",
"redis"
],
"NetworkID": "66cccb01394da77edbe008d18057b66b819389aaa2e98a967f8096a1bae46ae1",
"EndpointID": "5a86cdb12a84fd49de4b586bed1281cdec61cd45dc08ad230f46db8562ced722",
"Gateway": "172.20.0.1",
"IPAddress": "172.20.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:14:00:02",
"DriverOpts": null
}
}
...
复制代码
能够看到 compose1_redis_1
容器的 network alias
中包含了 redis
,这也是咱们在 docker-compose.yml
中定义的名称。这也解释了为何 index.js
中 redis
的 host
参数能够写作 redis
。
若是咱们启动项目时加了 -d
参数,那么咱们想中止项目时可使用 down
命令。
$ docker-compose down
# 它会删除容器和网络
# -v 删除数据卷
# --rmi all 删除全部 service 镜像
# --rmi local 删除没有自定义标签的镜像 image 字段
复制代码
$ docker-compose --help
# 咱们能够执行这个命令查看 docker-compose 支持命令
# 能够发现有不少命令都相似于 docker 命令
复制代码
更多 docker-compose
知识,能够查看 docker-compose 文档。
编写 docker-compose.yml
能够查看 这里。