基本介绍
使用一个Dockerfile模板文件,可以很方便的定义一个适合自己使用的自定义镜像。但在工作中经常会碰到需要多个容器相互配合来完成某项任务或运行某个项目的情况。例如要运行一个django项目,除了django容器本身,往往还需要再加上后端的数据库服务容器,甚至还包括负载均衡容器等,此时我们就需要使用到Docker-Compose了。
Docker-Compose项目是Docker官方的开源项目,负责实现对Docker容器集群的快速编排。Docker-Compose项目由Python编写,调用Docker服务提供的API来对容器进行管理和编排。因此只要所操作的平台支持Docker API,就可以在其上利用Docker-Compose来进行Docker容器的编排和管理。
Docker-Compose将所管理的Docker容器分为三层,分别是工程(project),服务(service)以及容器(container)。
Docker-Compose允许我们开发者通过一个单独的docker-compose.yml配置文件(YAML 格式)来定义一组相关联的docker容器为一个工程(project)。一个工程至少有一个服务,一个服务下至少有一个容器。
Docker-Compose运行指定目录下的所有关联文件组成一个工程(工程名默认为当前目录名)。一个工程当中可包含多个服务,每个服务中可以定义Docker容器运行的镜像,参数,环境依赖等信息。
Docker-Compose的工程配置文件默认为docker-compose.yml,也可以通过-f 参数来指定成其他的配置文件名。
安装
安装docker-compose,这种安装方式是基于Linux操作系统的源来决定安装版本的,所以往往版本会比较低。
apt install -y docker-compose
下载最新版本
安装地址:Overview of installing Docker Compose | Docker Docs
发布地址:Releases · docker/compose · GitHub
查看安装的版本
docker-compose version
卸载
sudo rm /usr/local/bin/docker-compose
sudo rm /usr/bin/docker-compose
常用命令
基本命令格式
docker-compose [-f <arg>...] [options] [COMMAND] [ARGS...]
命令选项如下
bash
-f --file FILE指定Compose模板文件,默认为当前目录下docker-compose.yml
# -p --project-name NAME 指定项目名称,默认使用当前所在目录为项目名
# --verbose 输出更多调试信息
# -v,-version 打印版本并退出
# --log-level LEVEL 定义日志等级(DEBUG, INFO, WARNING, ERROR, CRITICAL)
docker-compose up
根据容器编排配置文件docker-compose.yml,进行编排和启动容器。相当于docker run
的增强版。
bash
docker-compose up [options] [--scale SERVICE=NUM...] [SERVICE...]
选项包括:
-f 指定compose模板文件名
-d 在系统守护进程的方式批量运行服务容器
# 常用写法:
# docker-compose up # 以占据终端的方式批量启动docker-compose.yml中配置的所有容器
# docker-compose up -d # 以系统守护进程的方式批量启动docker-compose.yml中配置的所有容器,不会占据终端
# docker-compose -f docker-compose.yaml up -d
docker-compose down
停止运行并删除docker-compose.yml配置的容器、网络、卷。相当于 docker stop
与 docker rm
的组合
bash
docker-compose down [options]
选项包括:
-f 指定compose模板文件名
# 常用写法:
# docker-compose down
# docker-compose -f docker-compose.yml down
docker-compose logs
列出当前工程项目中运行容器过程中的运行日志。相当于docker logs
bash
docker-compose logs [options] [SERVICE...]
选项包括:
-f 跟踪日志输出
# 常用写法:
docker-compose logs # 查看整个docker-compose.yml配置中所有的容器的运行日志,不占据终端
docker-compose logs -f # 监控整个docker-compose.yml配置中所有的容器的运行日志,占据终端
模板配置入门
Compose模板文件是一个定义服务、网络和逻辑卷的YAML文件。Compose模板文件默认路径是当前目录下的docker-compose.yml,可以使用.yml或.yaml作为文件扩展名。
Docker-Compose标准模板文件应该包含version、services、networks 三大部分,最关键的是services和networks两个部分。networks是可选参数。
例如,我们要一次性启动3个ubuntu容器运行各自不同的配置下。
docker-compose.yml,注释版本,代码:
python
# 目前我们使用的基本都是Version3版本,最新版本是3.9。
version: "3.8"
# 声明接下来开始配置服务容器
services:
# 服务名,开发者自定义的,
ubuntu1:
# image 当前服务容器的基本依赖镜像,如果本地没有该镜像,则会自动从官网pull拉取
# image 也可以是自己本地基于Dockerfile编译后产生的定制镜像,但是必须是已经build编译好的
# 如希望在docker-compose up启动容器服务时自动编译Dockerfile,则必须增加配置项build指定Dockerfile
# 文件的所在路径,如果不指定,则可能出现从官网拉取镜像失败的情况,build配置项写法如下:
# build: .
# 如使用了build配置项时还声明了image配置项,则基于build所在的Dockerfile编译的镜像名为image指定名字。
# build: .
# image: djdemo:1.0.0
image: ubuntu:20.04
# container_name 指定当前服务容器启动以后的容器名
container_name: "ubuntu1"
# networks 指定网络,可以分配容器在一个或多个网络,如果不指定,则默认分配在docker的default网络中
networks:
- dev
ubuntu2:
image: ubuntu:20.04
container_name: "ubuntu2"
networks:
- dev
- pro
ubuntu3:
image: ubuntu:20.04
container_name: "ubuntu3"
networks:
- pro
# 网络配置
networks:
# 指定网络名称,相当于网卡名
dev:
# driver 网卡驱动:bridge 桥接模式,网卡驱动有三种模式:bridge、host、none
# 查看网络:docker network ls
driver: bridge
pro:
driver: bridge
完成上面的配置以后,可以通过以下命令,批量创建ubuntu容器。
bash
# 批量启动容器
docker-compose up
# 查看当前目录下的docker-compose.yml配置的容器
docker-compose ps
# 删除docker-compose.yml配置的容器
docker-compose down
docker-compose up -d
docker-compose ps
docker-compose down
配置项说明
image
image是指定服务的镜像名称或镜像ID。如果镜像在本地不存在,Compose将会尝试拉取镜像。
注意:如果镜像有版本号,则镜像名和版本号之间不能出现空格!否则报错!!!
yaml
services:
ubuntu1:
image: ubuntu:20.04
build
服务除了可以基于指定的基础镜像,还可以基于一份Dockerfile的自定义镜像,在使用docker-compose up启动时执行docker容器的构建任务,构建标签是build,可以指定Dockerfile所在文件夹的路径。Compose将会利用Docker自动构建镜像,然后使用镜像启动服务容器。
yaml
services:
web:
build: /home/docker # 指定Dockerfile文件的路径,如果与docker-compose.yml在同一个目录,则可以使用 . 表示当前目录
也可以是相对路径,只要上下文确定就可以读取到Dockerfile。
yaml
services:
web:
build: ../docker
设定上下文根目录,然后以该目录为准指定Dockerfile。
yaml
services:
web:
build:
context: ../docker
dockerfile: Dockerfile
build都是一个目录,如果要指定Dockerfile文件需要在build标签的子级标签中使用dockerfile标签指定。
如果同时指定image和build两个标签,那么Compose会构建镜像并且把镜像命名为image值指定的名字。
yaml
services:
web:
image: djdemo:1.0.0
build:
context: /home/docker
dockerfile: Dockerfile
python
context选项可以是Dockerfile的文件路径,也可以是到链接到git仓库的url,当提供的值是相对路径时,被解析为相对于撰写文件的路径,此目录也是发送到Docker守护进程的context
dockerfile选项可以指定context对应目录下的Dockerfile文件来构建,必须指定构建路径
command
使用command可以覆盖容器启动后默认执行的命令。相当于 docker
命令的末尾参数。
compose的command会覆盖Dockerfile里面的CMD的值。
yaml
command: shell命令
container_name
Compose的容器名称格式是:<项目名称><服务名称><序号>,相当于 docker [选项] --name
可以自定义项目名称、服务名称,但如果想完全控制容器的命名,可以使用标签指定:
yaml
container_name: app
restart
指定容器是否在操作系统重启以后,docker启动以后,是否容器也自动重启。相当于 docker --restart=always
yaml
restart: always
environment
指定服务容器中的环境变量,可以多个环境变量,每个环境变量就一个成员,相当于 docker -e
yaml
version: '3.7'
services:
mysql:
image: mysql:8.0.26
restart: always
container_name: mysql
networks:
- mysql
environment:
- "MYSQL_ROOT_PASSWORD=root"
- "MYSQL_USER=luffycity"
- "MYSQL_PASSWORD=luffycity"
- "MYSQL_DATABASE=luffycity"
- "TZ=Asia/Shanghai"
depends_on
在使用Compose时,最大的好处就是少打启动命令,但一般项目中多个容器的启动,顺序是有要求的,如果直接从上到下启动容器,必然会因为容器依赖问题而启动失败。例如在没启动数据库容器的时候启动应用容器,应用容器会因为找不到数据库而退出。depends_on标签用于解决容器的依赖、启动先后顺序的问题
yaml
version: '3.7'
services:
django:
build: .
depends_on:
- mysql
- redis
redis:
image: redis:6.0
mysql:
image: mysql:8.0.26
上述YAML文件定义的容器会先启动redis和db两个服务,最后才启动django服务。
ports
ports用于映射端口的标签。
使用HOST:CONTAINER格式或者只是指定容器的端口,宿主机会随机映射端口。相当于docker -p
yaml
ports:
- "3000" # 等价于 "3000:3000"
- "8000:8000"
- "49100:22"
当使用HOST:CONTAINER格式来映射端口时,如果使用的容器端口小于60可能会得到错误得结果,因为YAML将会解析xx:yy这种数字格式为60进制。所以建议采用字符串格式。
volumes
挂载一个目录或者一个已存在的数据卷容器,可以直接使用 [HOST:CONTAINER]格式,或者使用[HOST:CONTAINER:ro]格式,后者对于容器来说,数据卷是只读的,可以有效保护宿主机的文件系统。
Compose的数据卷指定路径可以是相对路径,使用 . 或者 ... 来指定相对目录。
相当于 docker run 终端命令选项-v参数
数据卷的格式可以是下面多种形式
yaml
volumes:
# 只是指定一个路径,Docker 会自动在创建一个数据卷(这个路径是容器内部的)。
# 相当于 /var/lib/mysql:/var/lib/mysql
- /var/lib/mysql
# 使用绝对路径挂载数据卷
- /opt/data:/var/lib/mysql
# 以 Compose 配置文件为中心的相对路径作为数据卷挂载到容器。
- ./cache:/tmp/cache
# 使用用户的相对路径(~/ 表示的目录是 /home/<用户目录>/ 或者 /root/)。
- ~/configs:/etc/configs/:ro
# 已经存在的命名的数据卷。
- datavolume:/var/lib/mysql
如果不使用宿主机的路径,可以指定一个volume_driver。
volume_driver: mydriver
volumes_from
从另一个服务或容器挂载其数据卷:
yaml
volumes_from:
- service_name
- container_name
dns
自定义DNS服务器。可以是一个值,也可以是一个列表。
yaml
dns:8.8.8.8
dns:
- 8.8.8.8
- 9.9.9.9
expose
暴露端口,但不映射到宿主机,只允许能被连接的服务访问。仅可以指定内部端口为参数,如下所示:
yaml
expose:
- "3000"
- "8000"
links
链接到其它服务中的容器。使用服务名称(同时作为别名),或者"服务名称:服务别名"(如 SERVICE:ALIAS),例如:
yaml
links:
- db
- db:database
- redis
net
设置网络模式。
yaml
net: "bridge"
net: "none"
net: "host"