【深入浅出Docker原理及实战】「原理实战体系」零基础+全方位带你学习探索Docker容器开发实战指南(Docker-compose使用全解 一)

Compose介绍

Docker Compose是一款用于定义和运行复杂应用程序的Docker工具。在使用Docker容器的应用中,通常由多个容器组成。使用Docker Compose可以摆脱使用shell脚本来启动容器的繁琐过程。

Compose的作用和职能

Compose通过一个配置文件来管理多个Docker容器。在配置文件中,我们使用services来定义所有的容器。然后,使用docker-compose脚本来启动、停止和重启应用,以及与应用中的服务和所有依赖的容器进行交互。这种方式非常适合开发阶段中组合使用多个容器的场景。

Compose和Docker兼容性

常用的Docker Compose文件格式版本和对应的Docker引擎版本。对于较旧的Docker引擎版本,可能不支持较新的Compose文件格式版本。因此,在选择Compose文件格式版本时,请确保与您使用的Docker引擎版本兼容。

Docker Compose文件格式版本 对应的Docker引擎版本
1 Docker 1.8.0+
2 Docker 1.10.0+
2.1 Docker 1.12.0+
2.2 Docker 1.13.0+
3 Docker 17.06.0+
3.1 Docker 17.12.0+
3.2 Docker 18.02.0+
3.3 Docker 18.06.0+
3.4 Docker 18.09.0+
3.5 Docker 19.03.0+
3.6 Docker 20.10.0+
3.7 Docker 20.10.0+
3.8 Docker 20.10.0+
3.9 Docker 20.10.2+

参考:docs.docker.com/compose/ove...

安装docker-compose

从github上下载docker-compose二进制文件安装,可以使用以下命令来下载最新版本的Docker Compose

shell 复制代码
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

你也可以使用:$ sudo curl -L github.com/docker/comp... -s-uname -m` -o /usr/local/bin/docker-compose

授予Docker Compose执行权限。运行以下命令来为Docker Compose设置执行权限:

shell 复制代码
   sudo chmod +x /usr/local/bin/docker-compose

验证安装。运行以下命令来验证Docker Compose是否成功安装:

shell 复制代码
docker-compose --version
docker-compose version 1.xx.1, build xxxxx

如果成功安装,将显示Docker Compose的版本信息。

添加可执行权限

shell 复制代码
$ sudo chmod +x /usr/local/bin/docker-compose

Docker Compose常用配置

在Compose配置文件中,services部分用来定义所有的容器服务。每个服务都有一个唯一的名称,并包含了需要运行该服务的相关配置信息,包括镜像、端口映射、环境变量等。通过定义services部分,可以轻松地组织和管理复杂的多容器应用程序。

image

yml 复制代码
services:
  web:
    image: java-app
  • services 标签下的第二级标签是web,这个名字是用户自己自定义,它就是服务名称。
  • image 则是指定服务的镜像名称或镜像 ID。如果镜像在本地不存在, Compose 将会尝试拉取这个镜像。

例如下面这些格式都是可以的:

yml 复制代码
image: redis
image: ubuntu:14.04
image: a4bc65fd

标明image的ID,这个image ID可以是本地也可以是远程的,如果本地不存在,Compose会尝试去pull下来。

build

除了可以基于指定的镜像启动服务,Compose还提供了基于Dockerfile构建镜像的功能。通过使用build标签,可以指定Dockerfile所在文件夹的路径,Compose将会自动构建镜像并将其用于启动服务容器。

build: /path/to/build/dir: 也可以是相对路径,只要上下文确定就可以读取到Dockerfile。

context上下文

build: ./dir:设定上下文根目录,然后以该目录为准指定Dockerfile。 dockerfile:制定相对的目录信息控制。

yml 复制代码
build:
  context: ../
  dockerfile: path/of/Dockerfile

build构建镜像的方式给予了更大的灵活性,可以根据自己的需求来定制镜像,可以在Dockerfile中定义所需的操作,如安装软件包、配置环境变量等。当使用up命令启动服务时,Compose会自动执行构建任务,生成镜像,并使用该镜像来启动服务容器。

注意:build 都是一个目录,如果你要指定Dockerfile文件需要在build标签的子级标签中使用dockerfile 标签指定,如上面的例子

指定镜像名

如果同时指定了image 和 build 两个标签,那么Compose会构建镜像并且把镜像命名为image后面的那个名字。

yml 复制代码
build: ./dir
	image: appName:tag

args构建环境变量

既然可以在 docker-compose.yml 中定义构建任务,那么一定少不了 args 这个标签,就像 Dockerfile 中的 ARG 指令,它可以在构建过程中指定环境变量,但是在构建成功后取消,在 docker-compose.yml 文件中也支持这样的写法:

yml 复制代码
build:
  context: .
  args:
    KEY: VALUE

此外,Dockerfile中也支持一种更易读的ARG指令的写法,尤其适合提高文件的可读性。

yml 复制代码
build:
  context: .
  args:
    - KEY=1
    - VALUE=2

与ENV指令不同,ARG指令允许在构建过程中接受空值,从而可以在构建过程中动态地将值赋予它们。

yml 复制代码
args:
  - KEY
  - VALUE

使用ARG指令定义的参数允许为空值。在构建过程中,可以使用--build-arg选项将值赋予该参数,或者在构建命令中使用--build-arg参数指定值。这种特性允许在构建过程中根据需要动态地传递参数值,使得构建过程更加灵活和可配置。

注意:YAML 的布尔值(true, false, yes, no, on, off)必须要使用引号引起来(单引号、双引号均可),否则会当成字符串解析。

command

在Compose配置文件中,使用command可以覆盖容器启动后默认执行的命令。通过指定command来指定容器启动后要执行的自定义命令。

例如,command: tailf -n 200 xx.log 将容器的默认执行命令替换为tailf -n 200 xx.log,这表示容器启动后将执行该命令。

注意,command也可以写成类似Dockerfile中的格式,使用一个数组来表示命令及其参数。例如,command: [tailf -n 200 xx.log]与上述的写法效果是一样的

使用command可以灵活地覆盖和定制容器的启动命令,以满足特定的需求。这使得Compose配置更加灵活,能够适应不同的应用场景。

depends_on

在使用Compose时,最大的优势之一是减少了启动命令的繁琐性。然而,一般情况下,项目中容器的启动顺序是有一定要求的。直接按照配置文件中的顺序从上到下启动容器可能会导致容器依赖关系的问题,从而引发启动失败的情况。

举例来说,如果在启动应用容器之前未启动数据库容器,应用容器会因为找不到数据库而退出。为了规避这种情况,我们需要引入一个关键标签,即depends_on。这个标签解决了容器之间的依赖关系和启动顺序的问题。

yml 复制代码
示例
#指定版本号
version: '2'
#指定网络
networks:
  testNetWork
#指定服务
services:
  #服务一
  test-app:
    image: "ts/app:1.0" #从镜像生成
    networks: #指定该服务的网络
      - testNetWork
    depends_on: #指定服务的依赖
      - db
    ports:
      - "8080:8080" # 指定端口的映射
  
  nginx:
    build: nginx #指定镜像的构建
    networks:
      - testNetWork
    depends_on:
      - test-app
    ports:
      - "80:80"

  db:
    image: "mysql"
    networks:
      - testNetWork
    environment: # 指定环境变量
      MYSQL_ROOT_PASSWORD: 123456
      MYSQL_DATABASE: testPassword
    volumes:
      - $PWD/data:/var/lib/mysql
    ports:
      - "3306:3306"

通过在Compose配置文件中使用depends_on标签,可以明确指定容器之间的启动顺序。这确保了在启动某个服务之前,所依赖的服务已经成功启动。这种方式有效地解决了容器启动顺序的管理问题,提高了整个应用系统的可靠性。

ports

在Compose配置中,端口信息的暴露是一个重要的配置项。常见的简单格式包括使用"宿主:容器"(HOST主机:CONTAINER容器)格式或者仅仅指定容器的端口(宿主将会随机选择端口)。

这样的端口映射配置允许定义容器与宿主之间的通信端口关系,确保服务能够正确地被访问。通过合理配置端口映射,可以满足不同应用场景下的需求,提高Compose配置的灵活性。

yml 复制代码
ports:
 - "3000"
 - "8000:8000"
 - "49100:22"
 - "127.0.0.1:8001:8001"
  • "3000":这表示将容器的端口3000映射到宿主机的随机端口。系统会动态选择一个可用的宿主机端口进行映射。

  • "8000:8000":这表示将容器的端口8000映射到宿主机的8000端口。访问宿主机的8000端口将转发到容器的8000端口。

  • "49100:22":这表示将容器的22端口(SSH端口)映射到宿主机的49100端口。这是一个非标准的映射,可能用于特定的网络配置。

  • "127.0.0.1:8001:8001":这表示将容器的8001端口映射到宿主机的127.0.0.1(本地回环地址)的8001端口。这种配置将使得只能通过宿主机本地访问容器的8001端口。

通过这些映射配置,可以方便地在宿主机与容器之间建立网络连接,实现容器服务的对外访问。这样可以确保容器中运行的服务能够接收来自网络的请求,并将其转发到相应的容器内部端口。

特殊映射关系

yml 复制代码
ports:
 - "3000-3005"
 - "9090-9091:8080-8081"
 - "127.0.0.1:5000-5010:5000-5010"
 - "6060:6060/udp"
  • "3000-3005":这表示将容器的端口3000到3005范围内的端口映射到宿主机的随机端口。系统会动态选择一个可用的宿主机端口进行映射。

  • "9090-9091:8080-8081":这表示将容器的8080端口映射到宿主机的9090端口,同时将容器的8081端口映射到宿主机的9091端口。这样可以一一对应地映射多个端口。

  • "127.0.0.1:5000-5010:5000-5010":这表示将容器的5000到5010范围内的端口映射到宿主机的127.0.0.1地址,对应的端口范围也是5000到5010。这允许在宿主机上通过这个范围的端口访问容器内的服务。

  • "6060:6060/udp":这表示将容器的UDP端口6060映射到宿主机的6060端口。UDP是一种无连接的协议,这样的配置适用于需要使用UDP协议的服务。

注意,当使用"HOST:CONTAINER"格式来映射端口时,如果容器端口小于60,可能会导致错误的结果,因为YAML将解析"xx:yy"这种数字格式为60进制。因此,建议采用字符串格式来避免潜在的问题。

volumes

在Compose配置中,挂载目录或已存在的数据卷容器可以采用类似 [HOST:CONTAINER] 或 [HOST:CONTAINER:ro] 的格式。后者中的":ro"表示该数据卷对于容器是只读的,从而有效地保护了宿主机文件系统的完整性。

Compose中,数据卷的指定路径可以是相对路径,允许使用 "." 或 ".." 来指定相对目录,提高配置的灵活性。

数据卷的格式支持多种形式,其中一些可能包括:

  1. [HOST:CONTAINER]:将宿主机上的路径挂载到容器中的指定路径。

  2. [HOST:CONTAINER:ro]:将宿主机上的路径以只读方式挂载到容器中的指定路径,以增加对宿主机文件系统的保护。

这样的挂载配置允许容器与宿主机之间共享数据,同时通过只读设置,确保容器无法对挂载的数据进行写操作,从而提高文件系统的安全性。

yml 复制代码
volumes:
  // 只是指定一个路径,Docker会自动在创建一个数据卷(这个路径是容器内部的)。
  - /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

environment

在Compose配置中,您可以通过两种形式(数组或字典)来添加环境变量。请注意以下建议的优化和润色:

  1. 使用数组或字典形式:可以使用数组或字典来定义环境变量。数组形式适用于单个键-值对,而字典形式适用于多个键-值对。例如:

    • 数组形式:

      yaml 复制代码
      environment:
        - KEY1=value1
        - KEY2=value2
    • 字典形式:

      yaml 复制代码
      environment:
        KEY1: value1
        KEY2: value2
  2. 引号括起布尔值:对于布尔类型的变量(如truefalseyesno),为确保不被YML解析器转换为True或False,建议用引号括起来。例如:

    yaml 复制代码
    environment:
      - BOOL_VAR="true"
      - OTHER_VAR="no"

    这样可以确保布尔值在解析时保持不变。

  3. 只指定变量名:如果只给出变量名而没有指定具体的值,则Compose会自动获取该变量在主机上的值。这种方式可以用来防止不必要的敏感数据泄露。例如:

    yaml 复制代码
    environment:
      - USERNAME
      - PASSWORD

    在运行时,Compose会自动获取主机上对应环境变量的值,并将其注入到容

注意:如果你的服务指定了build选项,那么在构建过程中通过environment定义的环境变量将不会起作用。 将使用build的args子选项来定义构建时的环境变量

Docker Compose命令详解

命令 用途
build [serviceName] 进行组合构建 [单个服务]
up [-d] 创建并且启动容器 [后台启动]
start [serviceName] 启动容器
stop [serviceName] 停止所有服务 [单个服务]
restart [serviceName] 重启所有服务 [单个服务]
rm [serviceName] 删除容器中的所有容器 [单个服务]
logs [serviceName] 观察所有容器的日志 [单个服务]
ps [serviceName] 列出相关的容器状态 [单个服务]

启动

shell 复制代码
docker-compose up -d 

注:使用命令docker-compose ps查看运行状况

Docker Compose案例实战

一份标准的Compose配置文件应该包含三个主要部分:version、services和networks。其中,最关键的是services和networks两个部分。接下来,让我们先来了解一下services部分的书写规则。

yml 复制代码
version: '2'
services:
  web:
    image: dockercloud/hello-world
    ports:
      - 8080
    networks:
      - front-tier
      - back-tier
  redis:
    image: redis
    links:
      - web
    networks:
      - back-tier
  lb:
    image: dockercloud/haproxy
    ports:
      - 80:80
    links:
      - web
    networks:
      - front-tier
      - back-tier
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock 
networks:
  front-tier:
    driver: bridge
  back-tier:
driver: bridge

除了基本的服务配置外,您还可以使用其他功能,如依赖关系、扩展性配置、容器间通信等,来满足具体应用的需求。

相关推荐
Cosolar3 分钟前
下一代 Python Web 框架?FastAPI 全面解析与实战对比
后端·python
用户4822137167751 小时前
C++——复合数据类型(数组、字符串)
后端
用户903700167151 小时前
分布式阻塞式限流学习及分享
后端
熊猫片沃子1 小时前
Mybatis中进行批量修改的方法
java·后端·mybatis
养鱼的程序员1 小时前
零基础搭建个人网站:从 Astro 框架到 GitHub 自动部署完全指南
前端·后端·github
白应穷奇1 小时前
编写高性能数据处理代码 01
后端·python
杨充2 小时前
03.接口vs抽象类比较
前端·后端
一只叫煤球的猫2 小时前
基于Redisson的高性能延迟队列架构设计与实现
java·redis·后端
卡尓2 小时前
使用 Layui 替换 Yii 基础模板的默认 Bootstrap 样式并尝试重写导航栏组件
后端
WhyWhatHow2 小时前
JEnv:新一代Java环境管理器,让多版本Java管理变得简单高效
java·后端