hudada-cli
Version:
专为程序员准备的本地文档搜索,快捷开发工具
394 lines (250 loc) • 18.1 kB
Markdown
# Docker-Compose安装与使用
## 为何要使用Docker-Compose?
默认情况下,docker 每次执行命令,只能负责单个镜像文件的构建、单个容器的管理,但一个实际应用程序中,可能需要同时运行多个容器一起工作,例如 Web后端项目通常需要:Koa + MongoDB,并且两个容器之间进行通信,此时若继续使用 docker 来运行管理则相对显得复杂繁琐一些。
Docker-Compose 就是专门用来管理多个 docker 容器的工具,它弥补了 docker 不易管理多容器的缺陷,提高协助 docker 做好运维工作。
事实上,比 Docker-Compose 更加灵活,功能更强大、对集群、负载平衡更好的程序是 k8s (Kubernetes)。相信日后一定会学习 k8s 的,但是暂时先学习使用 Docker-Compose。
## 安装与卸载
Docker Compose 是在 Docker 基础上运行的,因此在安装 Docker Compose 之前请确保已安装了 docker 。
### 安装 Docker-Compose
Windows系统:Docker-Compose 已默认集成在 Docker Desktop 版本中,因此无需额外安装。
Linux系统:本质上 Docker-Compose 是一个独立的可运行文件,因此只需要下载,并赋予可执行权限即可。
**第1步:下载**
下载地址:https://github.com/docker/compose/releases
下载方式1:直接通过浏览器访问,找到合适自己的的版本文件,下载,然后通过 xftp 上传到服务器中。
下载方式2:使用 curl 命令请求并保存文件
```
curl -L "https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
```
> 上述 curl 命令解释:
>
> 1. -L 表明若目标网址发生重定向,则返回重定向后的 URL 内容
> 2. 请求网址中,使用了 Linux 中的 uname 命令,`uname -s` 得到操作系统名称(例如:Linux),`uname -m` 得到电脑硬件类型(例如:x86_64),本人的服务器为腾讯云服务器,所以上述 URL 最终得到的值是`https://github.com/docker/compose/releases/download/1.27.4/docker-compose-Linux-x86_64`
> 3. -o /usr/local/bin/docker-compose 表明将目标内容保存为指定的本地目标文件。`/usr/local/bin/docker-compose` 意味着将请求返回的内容保存到`/usr/local/bin/`目录中 ,并且文件名命名为`docker-compose`
**第2步:赋予可执行权限**
```
chmod +x /usr/local/bin/docker-compose
```
**第3步:创建软连接**
```
```
**第4步:检查是否可执行**
```
docker-compose --version
```
> 若正确输出 docker-compose 版本号即表示可以正常执行。
**强调说明:**
在上面安装示例代码中,都是默认将 docker-compose 安装到 `/usr/local/bin/` 中,但事实是可以修改为其他任意目录中的。
## Docker-Compose配置文件
### 配置文件简介
dockerfile 是负责构建某一个镜像文件的配置文件,而 docker-compose.yml 则是用来配置 Docker-Compose 启动运行配置的。
> 也可以将配置文件名更改为:docker-compose.yaml,文件后缀名 .yml 或 .yaml 都可以。
> .yml 是 YAML 格式文件后缀,与XML形式不同,YAML 主要遵循以下几个书写原则:
>
> 1. YAML文件内容以空格来进行缩进,以表达层级关系
> 2. 值键对使用 参数名+冒号+1个空格+参数值 的形式。
> 3. 在 YAML 中字母是区分大小写的
> 4. 关于 YAML 相关使用规则,请参阅 [YAML学习笔记](https://github.com/puxiao/notes/blob/master/YAML%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0.md)
### 文件内容格式
docker-compose.yml 文件内容结构,大致为 3 个部分:版本声明、启动服务(容器列表)、创建网络列表
```
version: '3'
services:
xxx01:
xx: xxx
xx: xxx
xxx02:
xx: xxx
xx: xxx
networks:
default:
driver:xxx
frontend:
name:xxx
driver:xxx
backend:
name:xxx
driver:xxx
```
##### 第1部分:配置文件版本声明
文档最开始声明的 `version: '3'` 是用来告诉 docker-compose 应该以哪种版本来解析运行此配置文件的。
docker-compose.yml 版本对应 的 docker 版本号
| version: 'xxx' | 对应 docker engine 版本号 |
| -------------- | ------------------------- |
| 3.8 | 19.03.0+ |
| 3.7 | 18.06.0+ |
| 3.6 | 18.02.0+ |
| 3.5 | 17.12.0+ |
| 3.4 | 17.09.0+ |
| 3.3 | 17.06.0+ |
| 3.2 | 17.04.0+ |
| 3.1 | 1.13.1+ |
| 3.0 | 1.13.0+ |
根据 docker engine 的不同版本,更加精准的是应该填写 3.6、3.7、3.8 等值,但是通常不需要精准到小数点后一位,简单写成 '3' 即可。
##### 第2部分:启动服务(容器列表)
文档中 `services` 即 docker-compose 要运行的多个服务内容(多个容器),每个服务(容器)依次对应自定义的容器名字和该容器具体配置项。
> 在上面的示例中,容器名字定义为 xxx01、xxx02,在实际中应该定义成更加容易理解的字面意思,例如 web、db、cache 等。
##### 第3部分:创建网络列表
文档中 `networks` 即 docker-compose 要创建的网络列表。若没有该项,则默认启动 1个 网络,默认名字为 default 。
若 docker-compose 需要运行多个网络,则可以多次定义 networks 中的值。
若 要修改默认网络相关配置,则在 networks 中添加 default 的相关配置。
> 以下补充内容未经实际测试,所以不保证一定正确
**关于 docker-compose 创建的网络补充说明:**
docker-compose 默认的网络模式为 bridge,在这个模式下 创建一个 docker 网卡,宿主机分配到的 IP 为:172.17.0.1,然后 docker-compose 中运行的服务(容器),依次对应的IP为:172.17.0.2、172.17.0.3...
然后 服务(容器) 之间就靠着 同一网段 不同 IP 来进行通信,docker-compose 与宿主机通过创建的 docker 网卡 转发(不同端口之间的转发)进行通信。
> 如果添加 docker-compose 网络配置,不使用 bridge 模式,而是使用 host (宿主机网络) 模式,则不会有上面的内容。
**如何查看容器内部运行的网卡和IP**
1. 进入容器中:docker exec -it xxx bash
2. 容器中不能使用 netstat 或 ipconfig 命令,只能通过查看 host 配置文件来查看
### 服务(容器)配置参数
在配置文件中,services 下面每一个服务(容器)都需要根据需求添加对应的设置,docker-compose 中每一个服务(容器)的参数和 dockerfile 相似,但又有不同。
> 为了更加容易理解,下面内容中将 `服务` 都以 `容器` 这个词来替代。
每一个服务,即每一个容器,具体设置参数如下:
| 参数名 | 值类型 | 对应含义 |
| -------------- | ------ | ------------------------------------------------------------ |
| build | 字符串 | 构建镜像的 dockerfile 文件路径<br />(通常情况下不要这样操作,而是通过 image 参数指定镜像名) |
| image | 字符串 | 镜像文件名<br />(通常情况下直接使用镜像名,而不使用 build 参数构建镜像) |
| container_name | 字符串 | 创建容器的名字 |
| working_dir | 字符串 | 容器中的工作根目录 |
| volumes | 数组 | 服务器实际目录与容器目录映射关系,可以设置多条映射关系<br />(服务器实际目录:容器虚拟目录) |
| ports | 数组 | 服务器端口与容器内部端口映射关系,可设置多条映射关系<br />(服务器实际端口:容器虚拟端口) |
| depends_on | 数组 | 本容器运行依赖的其他容器<br />docker-compose 会优先启动运行依赖的容器,之后再启动本容器<br />例如 web 容器依赖于数据库(db)容器,因此先启动 db 容器,再启动 web 容器 |
| tty | 布尔值 | 表明是否以后台运行 |
| command | 字符串 | 执行的命令 |
| restart | 字符串 | docker-compose 重启时,容器是否也跟着重启,通常会设置值为:always<br />(注意是 docker-compose restart,而不是 docker-compose up) |
| environment | 数组 | 环境变量(数组中每个元素都为 key=value,这些变量是给容器使用的,并且优先级高于在 dockerfile 中定义的变量) |
| env_file | 数组 | 配置变量的文件列表(env文件中定义的变量是给 docker-compose.yml 使用的) |
### 多个配置文件
就好像 webpack 这样的配置设置一样,docker-compose 也支持定义多个配置文件,通常可以定义:基础环境、调试环境、生产环境,然后可以根据当前的实际需求,进行:基础环境 + 调试环境、基础环境 + 生产环境
无论调用 配置文件的哪种形式,都支持添加多个 配置文件。例如:
```
docker-compose -f docker-compose.yml -f docker-compose.prod.yml -up -d
```
### 配置文件使用继承
假设之前定义过一个配置文件 common-services.yml,其中该配置文件代码片段为:
```
services:
webapp:
image: 'puxiao'
ports:
- '8000:8000'
volumes:
- '/data'
```
此时再新建另外一个配置文件 docker-compose.yml,在该文件中,可以通过 extends 关键词来实现对 docker-services.yml 中 webapp 的继承(相当于复制并粘贴进来),示例代码:
```
web:
extends:
file: common-services.yml
service:webapp
```
使用 extends 关键词,继承自 common-services.yml 文件中的 service 中的 webapp,那么最终 docker-compose.yml 中 web 实际上的值等同于 common-services.yml 中的 webapp。
## 环境变量声明
在编写 docker-compose.yml 文件内容时,若某些值将来可能出现频繁修改,或 该值被多次使用,那么都可以将该值不写死在 docker-compose.yml 中,而是将该值作为引用变量的形式来使用,env-file 就是用来定义和存放 这些变量的文件。
#### 调用 env 文件的3种方式
**第1种:使用 --env-file 参数**
可以自己定义 env-file 文件名,然后在 docker-compose 执行命令配置选项中,--env-file PATH 配置 env-file 路径。
**第2种:使用 env_file 配置项**
在 docker-compose.yml services 中的某个容器中,设置 env_file 属性,并设置正确的值。
```
web:
env_file:
- web-variables.env
```
**第3种:使用 .env 文件**
最简单直接的办法,就是在 docker-compose.yml 同级目录中创建 .env 的文件,docker-compose 会自动找到并使用该文件。
> 对于同一个变量名,以上方式的优先级是:--env-file > env_file > .env
#### .env变量格式
环境变量 .env 文件中,对于定义变量的格式,遵循以下几个原则:
1. 每一个变量占一行,形式为:key=value
2. #开头即表示该行为注释
3. 空行会被忽略
4. 引号并不会被处理,因此若 key 或 value 中有引号,则意味着该引号其实是 key 或 value 本身的内容
5. 为了明确区分出引用变量,通常会在定义变量的时候,采用全大写字母的形式
以下为 .env 一个简单示例:
```
#环境变量配置,推荐将变量名使用全大写字母形式
NAME=puxiao
AGE=34
```
> 在 docker-compose.yml 中引用 NAME 的形式和 JavaScript 中字符串模板的用法一样,采用 ${NAME} 的形式
## Docker-Compose命令
#### 命令格式
docker-compose 命令格式为:docker-compose [-f <arg\>] [options] [COMMAND] [ARGS]
>[-f <arg\>]:配置文件(docker-compose.yml)路径,也可以在 [options] 中设置,若都不设置则默认为当前目录下的 docker-compose.yml
>
>[options]:其他配置选项
>
>[COMMAND]:命令
>
>[ARGS]:命令的参数
#### 配置项
| 配置项 | 对应值 | 对应含义 |
| --------------------- | ---------- | ------------------------------------------------------------ |
| -f \| --file | 路径 | 配置文件路径,默认为当前目录下的 docker-compose.yml |
| -p \| --project-name | 名称 | 配置项目别名,默认为当前目录名 |
| -c \| --context | 名称 | 配置内容名称 |
| --verbose | 不需要设置 | 显示更多输出内容(详细细节) |
| --log-level | 5选1 | 配置日志的级别,值为:<br />DEBUG(调试)、INFO(信息)、WARNING(警告)、ERROR(错误)、CRITICAL(严重) |
| --no-ansi | 不需要设置 | 不打印显示 ANSI 字符 |
| -v \| --version | 不需要设置 | 打印当前 docker-compose 版本并退出 |
| -H \| --host | host值 | 守护进程 docket 连接的 host |
| --tls | 不需要设置 | 使用 TLS 协议 (安全传输层协议),参数 --tlsverify 默认会设置该值 |
| --tlscacert | 路径 | 仅相信由此 CA 签署的证书 |
| --tlscert | 路径 | TLS 证书路径 |
| --tlskey | 路径 | TLS 证书key 路径 |
| --tlsverify | 不需要设置 | 使用 TLS 并验证远程 |
| --skip-hostname-check | 不需要设置 | 跳过证书检查 |
| --project-directory | 路径 | 配置目录的别名,默认使用 docker-compose.yml 所在的目录名 |
| --compatibility | 不需要设置 | 如果设置该项,则将尝试将 配置文件中的 deploy 秘钥转化为他们的非swarm 等价项 |
| --env-file | 路径 | 配置环境参数(定义的环境变量)文件路径 |
#### 全部命令
| 命令 | 对应含义 |
| ------- | ------------------------------------------------------------ |
| build | 构建或重建服务 |
| bundle | 从 配置文件(docker-compose.yml) 生成多个容器(容器束) |
| config | 验证和查看配置文档 |
| create | 创建服务 |
| down | 停止并删除容器、网络、镜像、映射关系 |
| events | 从容器接收实时事件 |
| exec | 在正在运行的容器中执行命令 |
| help | 获得命令帮助 |
| images | 查看镜像列表 |
| kill | 杀死容器 |
| logs | 查看容器的输出内容 |
| pause | 暂停服务 |
| port | 查看内部端口映射的本机端口 |
| ps | 查看容器列表 |
| pull | 拉取镜像 |
| push | 推送镜像 |
| restart | 重启服务 |
| rm | 移除已停止的容器 |
| run | 执行一次性命令 |
| scale | 设置容器数量 |
| start | 启动服务 |
| stop | 停止服务 |
| unpause | 显示正在运行的容器(非暂停容器) |
| up | 创建并启动容器 |
| version | 显示 docker-compose 版本号,以及 docker-compose 依赖其他模块的版本号<br />(docker-compose -v 仅打印 docker-compose 的版本号) |
> 可以通过 https://docs.docker.com/compose/reference/overview/ 查看每一个命令对应的不同参数
为了运行方便,通常情况下都不会每次手工书写这么多参数,而是会选择把需要的各个参数都写入到 docker-compose.yml 中,然后仅执行:docker-compose -f xxx up
> 就好像我们启动 mongodb 服务时,通常会将配置参数写入到 mongod.conf 文件中,然后以该文件为启动配置项:mongod -f mongod.conf
## 常用命令示例
#### 创建并启动容器:up
通过 -f 来指定 docker-compose.yml 文件路径,通过 -d 来设置以后台模式运行
```
docker-compose -f xxxx.yml up -d
```
若当前已经进入保存 docker-compose.yml 文件的目录,则上述命令还可以简化为:
```
docker-compose up -d
```
#### 进入某容器:exec
当执行完创建并启动容器后,可以通过 `docker-compose ps` 或 `docker ps`来查看正在运行的容器列表。
假设某容器的名字为 mymongo,那么如果想进入该容器,则执行:
```
docker exec -it mymongo bash
```
> 1. 请注意上面代码中是 docker 而不是 docker-compose
> 2. `-it` 的意思是:显示命令交互界面
> 3. `bash` 的意思是:以 bash(shell 命令) 方式进行交互
> 4. 退出该容器,执行:exit