2-8-Docker-Compose

熊 0 阅读 容器

1. docker compose概述

当在宿主机启动较多的容器时候 , 如果都是手动操作会觉得比较麻烦而且容易出错 , 此时推荐使用docker单机编排工具docker-compose

docker-compose是docker容器的一种单机编排服务 , docker-compose是一个管理多个容器的工具 , 比如 : 可以解决容器之间的依赖关系 , 就像启动一个nginx 前端服务的时候会调用后端的tomcat , 那就得先启动tomcat , 但是启动tomcat容器还需要依赖数据库 , 那就还得先启动数据库 , docker-compose可以用来解决这样的嵌套依赖关系 , 并且可以替代docker命令对容器进行创建、启动和停止等手工的操作。

因此 , 如果说docker命令就像linux的命令 , docker compse就像shell脚本 , 可以自动的执行容器批量操作 , 从而实现自动化的容器管理 , 或者说docker命令相当于ansible命令 , 那么docker compose文件 , 就相当于ansible-playbook的yaml文件

docker-compose项目是Docker官方的开源项目 , 负责实现对Docker容器集群的快速编排 , docker-compose将所管理的容器分为三层 , 分别是工程 ( project ) , 服务 ( service ) 以及容器 ( container )

  • 服务 ( service ) : 一个应用的容器 , 实际上可以包括若干运行相同镜像的容器实例。

  • 项目(project) : 由一组关联的应用容器组成的一个完整业务单元 , 在docker-compose.yml文件中定义。

github地址 : https://github.com/docker/compose

官方地址 : https://docs.docker.com/compose/

2. 安装与准备

2.1 安装docker-compose

  • 方式1 : 通过pip安装

    python-pip包将安装一个pip的命令 , pip命令是一个pyhton安装包的安装工具 , 其类似于ubuntu的apt或者redhat的yum , 但是pip只安装python相关的安装包 , 可以在多种操作系统安装和使用pip

    此方式当前安装的版本较新 , 推荐使用

    Ubuntu :  
    # apt  update 
    # apt  install -y  python-pip 
    Centos :  
    # yum install epel-release 
    # yum install -y python-pip 
    # pip install --upgrade pip

    范例:

    [root@ubuntu1804 ~]#apt -y install python-pip
    [root@ubuntu1804 ~]#pip install docker-compose
    [root@ubuntu1804 ~]#docker-compose --version
    docker-compose version 1.25.3, build unknown
  • 方式2 : 直接从github中下载

    参看说明 : https://github.com/docker/compose/releases

    此方法安装版本可方便指定 , 推荐方法 , 但网络下载较慢

    [root@centos7 ~]# curl -L https://github.com/docker/compose/releases/download/1.25.3/docker-compose-`uname-s`-`uname-m`  -o /usr/local/bin/docker-compose
    [root@ubuntu1804 ~]#chmod +x /usr/local/bin/docker-compose
  • 方式3 : 直接从包仓库安装, 不推荐使用

    #ubuntu安装
    [root@ubuntu1804 ~]#apt -y install docker-compose
    [root@ubuntu1804 ~]#docker-compose --version
    docker-compose version 1.17.1, build unknown
    ​
    #CentOS7安装 , 依赖EPEL源
    [root@centos7 ~]#yum -y install docker-compose
    [root@centos7 ~]#docker-compose --version
    docker-compose version 1.18.0, buil 8dd22a9

2.2 卸载

正常系统安装卸载 :

# sudo rm /usr/local/bin/docker-compose

pip安装卸载 :

# pip uninstall docker-compose

2.2 命令使用

查看命令帮助

[root@centos7 ~]# docker-compose --help
Define and run multi-container applications with Docker.
​
Usage:
  docker-compose [-f <arg>...] [options] [COMMAND] [ARGS...]
  docker-compose -h|--help
​
Options:
  -f, --file FILE             #指定Compose 模板文件 , 默认为docker-compose.yml。
  -p, --project-name NAME     #指定项目名称 , 默认将使用当前所在目录名称作为项目名。
  --verbose                   #显示更多输出信息
  --no-ansi                   #不显示ANSI 控制字符
  -v, --version               #显示版本
  -H, --host HOST             Daemon socket to connect to
​
  --tls                       Use TLS; implied by --tlsverify
  --tlscacert CA_PATH         Trust certs signed only by this CA
  --tlscert CLIENT_CERT_PATH  Path to TLS certificate file
  --tlskey TLS_KEY_PATH       Path to TLS key file
  --tlsverify                 Use TLS and verify the remote
  --skip-hostname-check       Don't check the daemon's hostname against the name specified
                              in the client certificate (for example if your docker host
                              is an IP address)
  --project-directory PATH    Specify an alternate working directory
                              (default: the path of the Compose file)
​
#以下为命令选项 , 需要在docker-compose.yml|yaml 文件所在在目录里执行
Commands:
  build              #构建镜像 
  bundle             #从当前docker compose 文件生成一个以<当前目录>为名称的json格式的Docker Bundle 备份文件
  config             #查看当前配置 , 没有错误不输出任何信息 
  create             #创建服务 , 较少使用 
  down               #停止和删除所有容器、网络、镜像和卷 
  events             #从容器接收实时事件 , 可以指定json 日志格式 , 较少使用 
  exec               #进入指定容器进行操作
  help               #显示帮助细信息
  images             #显示镜像信息 , 较少使用
  kill               #强制终止运行中的容器
  logs               #查看容器的日志
  pause              #暂停服务
  port               #查看端口
  ps                 #列出容器 , 较少使用
  pull               #重新拉取镜像 , 镜像发生变化后 , 需要重新拉取镜像 , 较少使用 
  push               #上传镜像 
  restart            #重启服务 , 较少使用 
  rm                 #删除已经停止的服务
  run                #一次性运行容器
  scale              #设置指定服务运行的容器个数 
  start              #启动服务
  stop               #停止服务
  top                #显示容器运行状态
  unpause            #取消暂停服务
  up                 #创建并启动容器
  version            #显示版本

以下是Docker Compose中一些常用的命令 :

  • docker-compose up : 前台启动Compose文件中定义的服务 , 创建并启动所有容器。可以使用-d选项 , 使得进程处于后台运行

  • docker-compose down : 停止Compose文件中定义的服务 , 删除所有容器和网络。

  • docker-compose ps : 显示Compose文件中定义的所有容器的状态。

  • docker-compose logs : 显示Compose文件中定义的所有容器的日志。

  • docker-compose build : 根据Compose文件中定义的Dockerfile构建所有服务的镜像。

  • docker-compose pull : 拉取Compose文件中定义的所有服务的镜像。

  • docker-compose restart : 重启Compose文件中定义的所有服务。

  • docker-compose stop : 停止Compose文件中定义的所有服务。

  • docker-compose start : 启动Compose文件中定义的所有服务。

  • docker-compose exec : 在Compose文件中定义的容器中执行命令。

  • docker-compose run : 在Compose文件中定义的容器中运行命令。

  • docker-compose config : 检查Compose文件的语法 , 并显示Compose文件中定义的所有服务的配置。

3. docker compse文件格式

官方文档 : https://docs.docker.com/compose/compose-file/

docker compose文件是一个yaml格式的文件 , 所以注意行首的缩进很严格

默认docker-compose命令会调用当前目录下的docker-compose.yml的文件 , 因此一般执行docker-compose命令前先进入docker-compose.yml文件所在目录

docker compose文件的格式很不同版本 , 版本不同 , 语法和格式有所不同 , 参看以下列表

Compose file format

Docker Engine release

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+

2.4

17.12.0+

2.3

17.06.0+

2.2

1.13.0+

2.1

1.12.0+

2.0

1.10.0+

1.0

1.9.1.+

3.1 环境变量

Docker Compose允许你使用多种方法为服务设置环境变量。这些环境变量可以用来配置你的应用程序或将敏感信息传递给你的容器。

下面是一些设置Docker Compose环境变量的方法 :

  1. 在docker-compose.yml文件中设置环境变量

    你可以在 docker-compose.yml 文件中为每个服务设置环境变量。在服务配置中, 使用 environment 关键字, 并在其中列出需要设置的环境变量和其值。

    services:
      web:
        image: nginx
        environment:
          MY_VAR: my_value
  2. 从.env文件中读取环境变量

    你可以将环境变量存储在一个 .env 文件中, 并让Docker Compose读取它。在 docker-compose.yml 文件中, 使用 env_file 关键字并指定 .env 文件的路径。

    services:
      web:
        image: nginx
        env_file:
          - .env

    指定文件中配置如下

    [root@centos7 db]# cat env 
    POSTGRES_PASSWORD=root123
  3. 使用 shell环境变量

    你也可以在启动docker-compose命令时, 使用 shell 环境变量传递环境变量值。例如

    $ export MY_VAR=my_value
    $ docker-compose up

    在 docker-compose.yml 文件中使用 ${MY_VAR} 语法来引用 shell 环境变量。

    services:
      web:
        image: nginx
        environment:
          MY_VAR: ${MY_VAR}

3.2 编排中的字段详解

在 Docker Compose 编排文件中, 有一些重要的字段需要了解 :

3.2.1 version

version 字段指定了 Docker Compose 编排文件的版本。当前最新版本是 3。

version: '3'

该字段可以省略, 省略之后可以使用docker config默认生成一个指定的version版本

命令docker config 主要用途是检查编排文件

3.2.2 network

networks字段指定了要使用的网络。默认情况下, Docker Compose创建一个名为 default 的网络。以下是一个使用自定义网络的示例 :

networks:
  my-network:
    driver: bridge

Docker Compose中的网络可以用于在多个容器之间建立通信。通过定义网络 , 可以让容器之间相互通信 , 同时将它们与主机网络隔离开来 , 提高容器应用的安全性。

Docker Compose提供了三种网络类型 : bridge、host和none , 每种类型都适用于不同的场景。

3.2.2.1 bridge网络类型

bridge网络类型是默认的网络类型 , 它创建一个桥接网络 , 允许容器之间进行通信。每个容器都有自己的IP地址 , 并且可以通过容器名称来相互访问。如果没有指定网络类型 , Docker Compose将使用 bridge 网络类型。

在bridge网络类型中 , Docker Compose会为每个服务创建一个容器 , 并为每个容器分配一个IP地址。在同一个网络中的容器可以相互访问。

注意 : 如果您使用了Docker Compose的网络功能 ( 默认情况下会创建一个网络 ) , 则可以在同一网络中的任何容器中使用容器名称来访问服务。如果您没有使用Docker Compose网络功能 , 则需要手动创建网络 , 并将所有容器添加到同一网络中。

示例 假设我们有两个服务, web和db。在默认情况下 , Docker Compose使用 bridge 网络类型 , 我们可以不用特别指定网络类型。以下是一个示例的docker-compose.yml文件 :

version: '3'
services:
  web:
    build: .
    ports:
      - "80:80"
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: example

在上述示例中 , web服务将使用本地Dockerfile构建 , 并将容器端口80映射到主机端口80。db服务将使用MySQL 5.7镜像 , 并设置 MySQL的root用户密码为example。

通过docker-compose up命令启动这个示例 , Docker Compose将为每个服务创建一个容器 , 并自动创建一个默认的bridge网络来使它们互相通信。

3.2.2.2 host 网络类型

host 网络类型让容器共享主机的网络栈 , 这意味着容器将与主机具有相同的IP地址和网络接口。这样可以提高容器的网络性能和可访问性 , 但是容器之间不能互相访问 , 因为它们共享同一个网络栈。

在host网络类型中 , Docker Compose会将每个服务直接放在主机网络中 , 容器将与主机共享IP地址和网络接口 , 因此可以通过主机 IP 地址来访问容器中运行的服务。

示例 , 假设我们有一个服务 , 它需要使用主机网络接口。以下是一个示例的docker-compose.yml文件 :

version: '3'
services:
  web:
    build: .
    network_mode: host

在上述示例中 , 我们使用 build 关键字来指定构建上下文 , 并使用 network_mode 关键字将服务 web 的网络模式设置为 host。这样 , web 服务将与主机共享 IP 地址和网络接口 , 可以通过主机 IP 地址来访问服务。

3.2.2.3 none 网络类型

none 网络类型表示不为容器分配任何网络资源 , 容器将没有网络接口。这通常用于某些特殊的容器场景 , 例如一些只需要与主机交互而不需要网络连接的容器。

在none网络类型中 , Docker Compose会将每个服务放在一个单独的网络命名空间中 , 容器将没有任何网络资源 , 无法进行网络通信。

示例 假设我们有一个服务 , 它不需要任何网络连接。以下是一个示例的docker-compose.yml文件 :

version: '3'
services:
  worker:
    build: .
    network_mode: none

在上述示例中 , 我们使用 build 关键字来指定构建上下文 , 并使用 network_mode 关键字将服务worker的网络模式设置为none。这样 , worker服务将没有任何网络资源 , 无法进行网络通信。

3.2.2.4 自定义网络

Docker Compose 默认会为每个Compose项目创建一个网络。这个网络的名称会以Compose项目的目录名作为前缀 , 例如 , 如果您的Compose项目目录名为myproject , 则默认创建的网络名称为myproject_default。

  • 在这个默认创建的网络中 , 所有的服务和容器都可以通过它们的服务名称或容器名称进行通信。这些名称在默认情况下都是唯一的 , 因此可以避免名称冲突和混乱。

  • 如果您需要访问不同的网络或自定义网络 , 则可以使用Docker Compose的networks属性来创建自定义网络。例如 , 以下是一个Docker Compose文件 , 其中定义了一个名为my_network的自定义网络 :

    version: '3'
    services:
      web:
        image: nginx
        networks:
          - my_network
    
    networks:
      my_network:
        driver: bridge

    在这个示例中 ,web服务将被连接到my_network网络中 , 而不是默认创建的网络。该网络的驱动程序为bridge , 这是Docker Compose默认使用的网络驱动程序。

Compose项目目录名解释 : Compose项目目录名是指包含Docker Compose文件的目录的名称。Docker Compose文件 ( 通常命名为docker-compose.yml ) 描述了Docker Compose应该如何构建和运行Docker容器应用程序。该文件通常存储在Compose项目目录的根目录中。

例如 , 如果您正在开发一个名为myapp的应用程序 , 并使用Docker Compose来管理它的容器化部署 , 那么您可能会在以下目录结构中存储您的Docker Compose文件 :

myapp/
├── docker-compose.yml
├── app/
│   ├── Dockerfile
│   └── app.py
└── data/

在这个例子中 , myapp是Compose项目目录名 , docker-compose.yml是Compose文件的名称 , 并存储在myapp目录的根目录中。myapp目录还包含了应用程序的代码和数据目录。

3.2.3 数据卷挂载(volumes)

  • 数据卷类型

    1. 匿名卷 : 由Docker自动创建 , 没有指定明确的名称 , 适合临时数据。

    2. 命名卷 : 具有特定名称 , 便于引用和重用 , 适合持久化数据。

    3. 宿主机卷 : 直接映射宿主机的目录或文件到容器中 , 适合开发环境。

volumes 字段指定了要使用的数据卷。以下是一个使用数据卷的示例 :

volumes:
  my-volume:
    driver: local

在Docker Compose中 , 可以通过挂载主机目录或文件来访问容器内部的文件或目录 , 以便在容器内外共享数据或配置文件。Docker Compose支持两种方式进行挂载 :

  1. 命名卷挂载

    命名卷是由Docker创建和管理的卷 , 它们可以用于存储持久化数据 , 并可以在多个容器之间共享。在Docker Compose中 , 可以通过volumes字段来定义命名卷的挂载路径和主机目录的映射关系。

    version: "3.7"
    
    services:
      app:
        image: myapp:latest
        volumes:
          - myapp_data:/app/data
    
    volumes:
      myapp_data:

    在上述示例中 , 我们定义了一个myapp服务 , 该服务使用了myapp:latest镜像 , 并将命名卷myapp_data挂载到容器内的 /app/data目录。

  2. 匿名卷 在这个例子中 , app 服务将创建一个匿名卷来存储 /app/data 目录的数据。

    version: '3'  
    services:  
      app:  
        image: myapp  
        volumes:  
          - /app/data  
  3. 主机目录(宿主机卷)挂载

    主机目录挂载允许将Docker主机上的目录或文件夹挂载到容器内部 , 以便在容器内外共享数据。在Docker Compose中 , 可以通过 volumes字段来定义主机目录的挂载路径和主机目录的映射关系。例如 :

    version: "3.7"
    
    services:
      app:
        image: myapp:latest
        volumes:
          - /host/data:/app/data

    在上述示例中 , 我们定义了一个myapp服务 , 该服务使用了myapp:latest镜像 , 并将宿主机上的 /host/data目录挂载到容器内的 /app/data 目录。

【注意】在 Docker Compose 中 , 如果使用主机目录挂载 , 则要求主机目录必须存在且具有正确的权限。否则 , 容器将无法访问该目录。此外 , 在使用主机目录挂载时 , 请注意挂载的目录是否包含敏感数据 , 以避免数据泄露的风险。

另外可以使用volumes_from,从另一个服务或容器挂载它的所有卷。

volumes_from:
 - service_name
 - container_name

3.2.4 services

services 字段指定了在 Docker Compose 编排中要运行的服务。每个服务都有一个名称, 并指定要使用的镜像和容器的配置选项。以下是一个简单的services配置的示例 :

services:
  web:
    build: .
    ports:
      - "5000:5000"
  redis:
    image: "redis:alpine"

3.2.4.1 build 与image

  1. build

    build 字段允许在Docker Compose编排中指定Dockerfile的位置, 从而可以使用Docker Compose构建镜像。例如, 以下是使用本地 Dockerfile 的示例 :

    services:
      web:
        build: .

    也可以指定一个包含Dockerfile的目录 :

    services:
      web:
        build: ./my-web-app
  2. image

    image 字段指定要使用的Docker镜像。例如 :

    services:
      web:
        image: nginx

    温馨提示: build和image二选一即可, 也可以同时写, 但是一般只选择image吧。

    version: '3.8'
    services:
      web:
        build: ./web
        image: myapp/web:latest

    上面的配置指定了服务名称为web, Dockerfile路径为./web, 镜像名称为 myapp/web, 标签为 latest。在运行docker-compose build 命令时, 会自动构建名为 myapp/web:latest 的镜像。

3.2.4.2 environment 与 environment_file

  1. environment

    environment 字段指定了要设置的环境变量。以下是一个使用环境变量的示例 :

    environment:
      MY_VAR: my_value
  2. environment_file

    environment_file : 指定从文件中读取环境变量。

    environment_file: .env

3.2.4.3 ports 与 expose

  1. ports

    ports 字段指定了要宿主机映射到容器的端口 ( 宿主机端口:容器端口 ) 。以下是一个使用端口映射的示例 :

    version: '3'
    services:
      web:
        image: myapp:latest
        ports:
          - "8080:80"
  2. expose

    expose字段是用于在Docker容器内部暴露端口的选项, 可以让其他容器连接到这些端口, 但不会将它们映射到Docker主机上。

    在docker-compose.yml文件中使用expose选项来指定容器内部需要暴露的端口。例如, 以下示例定义了一个web服务, 它暴露了 8000和8080端口 :

    version: '3'
    services:
      web:
        image: myapp:latest
        expose:
          - "8000"
          - "8080"

    当您使用 expose 选项时, 其他容器可以使用Docker的内部网络进行连接。例如, 如果您有另一个服务worker, 它需要连接到 web服务的8000端口, 则可以在worker服务的docker-compose.yml文件中使用 links 选项 :

    version: '3'
    services:
      worker:
        image: myworker:latest
        links:
          - web

ports 和 expose 是两个不同的Docker Compose字段 , 用于在容器中暴露端口。

  • ports 字段 : 用于将容器内部的端口映射到宿主机上的端口 , 以便外部网络可以通过宿主机上的端口与容器中运行的应用程序进行通信。这个字段的语法如下 :

    version: "3"
    services:
      web:
        image: nginx
        ports:
          - "8080:80"

    这个例子中 , 容器中运行的nginx进程监听的是容器内部的80端口 , 而ports字段将宿主机上的8080端口映射到了容器内部的 80 端口 , 这样外部网络就可以通过访问宿主机上的8080端口来访问容器中运行的nginx应用程序。

  • expose 与 ports 不同的是 , expose 字段仅仅是将容器内部的端口暴露给其他容器使用 , 而不是直接映射到宿主机上的端口。这个字段的语法如下 :

    version: "3"
    services:
      db:
        image: mysql
        expose:
          - "3306"
      web:
        image: nginx
        expose:
          - "80"

这个例子中 , db和web两个容器分别暴露了它们内部的3306和80端口 , 其他容器可以使用这些端口来与它们通信。但是 , 由于这些端口没有被映射到宿主机上 , 因此外部网络无法直接访问它们。如果要从外部网络访问这些容器 , 需要使用ports字段将它们映射到宿主机上的端口。

3.2.4.4 depends_on

depends_on 字段指定了服务之间的依赖关系。例如, 如果web服务依赖于db服务, 则可以使用以下示例 :

version: '3'
services:
  web:
    image: myapp:latest
    depends_on:
      - db

3.2.4.5 restart

Docker Compose提供了几种重启策略, 以便在容器出现故障时自动重启它们。以下是可用的重启策略 :

  • no: 不重启任何容器。如果容器停止, Compose 不会尝试自动重启它们。 ( 默认策略 )

  • always: 如果容器停止, Compose 将自动重启它。 ( 常用 )

  • on-failure: 只有在容器因非 0 退出码而停止时才会重启。

  • unless-stopped: 除非手动停止, 否则始终重启容器。这相当于使用docker run命令时使用的--restart=unless-stopped标志。

这些策略可以在docker-compose.yml文件中通过restart 键指定, 例如 :

version: '3'
services:
  web:
    image: myapp:latest
    restart: always

这个示例使用always策略, 这意味着如果web容器停止, Compose将自动重启它。

3.2.4.6 command

command字段可以使用多种写法来指定容器启动时要执行的命令, 具体取决于您的需求和偏好。以下是一些常见的写法示例 :

  1. 字符串形式

    version: '3'
    services:
      web:
        image: myapp:latest
        command: python manage.py runserver 0.0.0.0:8000

    在这个示例中, command 字段的值是一个字符串, 表示要执行的命令和参数。

  2. 列表形式

    version: '3'
    services:
      web:
        image: myapp:latest
        command:
          - python
          - manage.py
          - runserver
          - 0.0.0.0:8000

    在这个示例中, command 字段的值是一个列表, 每个元素都表示要执行的命令或参数。

  3. Shell命令形式

    version: '3'
    services:
      web:
        image: myapp:latest
        # 两种写法
        # command: sh -c "python manage.py runserver 0.0.0.0:8000"
        command: ["sh","-c","python manage.py runserver 0.0.0.0:8000"]
  4. 使用环境变量形式

    version: '3'
    services:
      web:
        image: myapp:latest
        environment:
          - ENVIRONMENT=production
        command: python manage.py runserver 0.0.0.0:${PORT}

    在这个示例中, command字段中的 ${PORT} 将被替换为web服务的环境变量 PORT 的值。

3.2.4.7 hostname 与 container_name

hostname 和 container_name 都是用来定义 Docker 容器的标识符, 但是它们的含义不同。

  1. hostname

    hostname用于设置容器的主机名, 也就是在容器内部可以使用的名称。例如, 如果您在容器内部使用ping hostname命令, 它将解析为容器的IP地址。可以使用以下格式设置主机名 :

    version: '3'
    services:
      web:
        image: myapp:latest
        hostname: myapp-container

    在这个示例中, web服务的容器主机名被设置为 myapp-container。

  2. container_name

    container_name 用于给容器命名, 也就是在Docker主机上使用的名称。可以使用以下格式设置容器名称 :

    version: '3'
    services:
      web:
        image: myapp:latest
        container_name: myapp

    在这个示例中, web服务的容器名称被设置为myapp。

总之, hostname和container_name都是用于定义容器的标识符, 但是hostname用于容器内部的标识, container_name用于 Docker主机上的标识。

3.2.4.8 user

在Docker Compose中, 可以使用user字段来指定容器中运行的进程的用户和用户组。它的语法与 docker run 命令的 --user 选项类似, 有以下三种形式 :

  1. user:group ( 推荐 )

    以user用户和group用户组的身份运行容器中的进程, 例如 :

    version: "3"
    services:
      web:
        image: nginx
        user: nginx:nginx

  2. uid:gid

    以uid用户ID和gid用户组ID的身份运行容器中的进程, 例如 :

    version: "3"
    services:
      web:
        image: nginx
        user: "1000:1000"

  3. user

    以user用户的身份运行容器中的进程, 例如 :

    version: "3"
    services:
      web:
        image: nginx
        user: nginx

    需要注意的是, 如果在Docker Compose中使用了user 字段, 则容器中的所有进程都将以指定的用户身份运行, 而不是默认的root 用户身份运行。这可以提高容器的安全性, 避免在容器中使用root用户造成潜在的安全风险。

  • links

    链接到其它服务中的容器,使一个容器可以主动的去和另外一个容器通讯。使用服务名称(同时作为别名) 或服务名称 : 服务别名 ( SERVICE:ALIAS ) 格式都可以。

    links:
     - db
     - db:database
     - redis

    使用的别名将会自动在服务容器中的/etc/hosts里创建,相应的环境变量也将被创建。例如

    172.17.2.186 db
    172.17.2.186 database
    172.17.2.187 redis

  • external_links

    链接到 docker-compose.yml外部的容器 , 甚至 并非Compose管理的容器。参数格式跟links类似。

    external_links:
     - redis_1
     - project_db_1:mysql
     - project_db_1:postgresql

3.2.4.10 extends

基于已有的服务进行扩展。例如我们已经有了一个webapp服务 , 模板文件为common.yml。

# common.yml
webapp:
  build: ./webapp
  environment:
    - DEBUG=false
    - SEND_EMAILS=false

编写一个新的development.yml文件 , 使用common.yml中的webapp服务进行扩展。

# development.yml
web:
  extends:
    file: common.yml
    service: webapp
  ports:
    - "8000:8000"
  links:
    - db
  environment:
    - DEBUG=true
db:
  image: postgres

后者会自动继承common.yml中的webapp服务及相关环节变量。

3.2.4.11 dns相关

  • dns

    配置DNS服务器。可以是一个值 , 也可以是一个列表。

    dns: 8.8.8.8
    dns:
      - 8.8.8.8
      - 9.9.9.9
  • dns_search

    配置DNS搜索域。可以是一个值,也可以是一个列表。

    dns_search: example.com
    dns_search:
      - domain1.example.com
      - domain2.example.com
  • extra_host

    给指定生成的容器中的/etc/hosts文件中添加host主机解析

    extra_hosts:
      - "harbor:192.168.194.130"
      - "harbor2:192.168.194.146"

3.2.5 configs 与 secrets

  1. configs

    configs : 指定容器使用的配置文件。

    configs:
      - source: my-config
        target: /etc/nginx/conf.d/default.conf

    上面的例子中 , 将名为my-config的配置文件复制到容器的/etc/nginx/conf.d/default.conf 目录下。

  2. secrets

    secrets : 指定容器使用的机密数据。

    secrets:
      - db_password

configs 和 secrets 是Docker Compose和Docker Swarm中用于管理容器配置和敏感数据的两个不同的功能。它们的区别如下 :

  • 用途不同 : configs 用于管理容器应用程序的配置文件 , 例如nginx的配置文件、MySQL的配置文件等 , 而 secrets 则用于管理敏感数据 , 例如数据库的密码、API 密钥等。

  • 存储位置不同 : configs存储在 Docker 主机的文件系统中 , 可以是本地文件系统、NFS 文件系统或远程 S3 存储等 , 而secrets存储在Docker Swarm的安全存储中 , 该存储是加密的、高度安全的 , 并且只能由授权的Docker服务和节点访问。

  • 访问方式不同 : configs可以通过文件挂载或Docker Compose文件中的configs字段来访问 , 而secrets可以通过文件挂载、Docker Compose文件中的secrets字段、Docker CLI的docker secret命令或容器内部的文件系统来访问。

  • 生命周期不同 : configs 的生命周期是独立于服务的 , 当服务停止时 , 配置文件仍然可以保留在主机上 , 而 secrets 的生命周期是与服务绑定的 , 当服务被删除时 , 敏感数据也会被删除。

  • 更新方式不同 : configs的更新是通过重新部署服务来实现的 , 而secrets的更新是通过Docker CLI的docker secret命令或容器内部的文件系统来实现的。

以下是一个使用 configs 和 secrets 的Docker Compose文件的示例 :

version: '3.7'

services:
  web:
    image: nginx:latest
    ports:
      - 80:80
    configs:
      - source: nginx_conf
        target: /etc/nginx/nginx.conf
    secrets:
      - source: db_password
        target: /run/secrets/db_password

configs:
  nginx_conf:
    file: ./nginx.conf

secrets:
  db_password:
    file: ./db_password.txt

在上面的示例中 , 我们定义了一个web服务 , 该服务使用了nginx:latest镜像 , 并将容器内的80端口映射到Docker主机的80端口。此外 , 我们还定义了两个配置 : configs和secrets。

  • configs 定义了一个名为nginx_conf的配置 , 该配置从本地的 nginx.conf 文件中读取配置 , 并将其挂载到容器内的 /etc/nginx/nginx.conf 路径。这样 , 我们就可以使用自定义的 nginx.conf 配置文件来配置 nginx 服务。

  • secrets 定义了一个名为 db_password 的敏感数据 , 该数据从本地的 db_password.txt文件中读取 , 并将其挂载到容器内的 /run/secrets/db_password 路径。这样 , 我们就可以在容器内部安全地访问数据库密码 , 而不必担心密码泄露的风险。

在上述示例中 , 我们使用了文件挂载来访问 configs 和 secrets。这是最常见的访问方式 , 但并不是唯一的方式。secrets还可以通过Docker CLI的docker secret命令或容器内部的文件系统来访问。

3.2.6 健康检查

Docker Compose支持为服务定义健康检查 , 用于检查服务是否正常运行。健康检查可以是一个命令、一个HTTP请求或者一个TCP端口。如果健康检查失败 , Docker Compose将尝试重新启动服务 , 直到达到最大重试次数或者服务成功运行。

3.2.6.1 健康检查语法

在Docker Compose中 , 可以通过healthcheck关键字来定义健康检查。具体语法如下 :

healthcheck:
  test: ["CMD-SHELL", "command"]
  interval: interval
  timeout: timeout
  retries: retries

参数解释 :

  • test 是健康检查的命令或者请求。

  • interval 是检查健康状态的时间间隔 , 单位为秒 , 默认为 30s。

  • timeout 是检查健康状态的超时时间 , 单位为秒 , 默认为 30s。

  • retries 是健康检查失败时的重试次数 , 默认为 3。

3.2.6.2 健康检查写法

包括以下几种写法 :

  1. 字符串形式的命令

    healthcheck:
      test: curl --fail http://localhost:80 || exit 1
      interval: 30s
      timeout: 10s
      retries: 5

    在上述示例中 , healthcheck字段的test属性是一个字符串 , 表示需要执行的健康检查命令。在这个示例中 , 我们使用curl命令来测试localhost:80是否能够访问。如果健康检查命令返回状态码0 , 则表示服务正常 , 否则表示服务异常。在这个示例中 , 如果健康检查失败 , Docker Compose将在每30秒尝试重新运行健康检查 , 最多重试5次。

  2. 数组形式的命令

    healthcheck:
      test:
        - CMD
        - curl
        - --fail
        - http://localhost:80
      interval: 30s
      timeout: 10s
      retries: 5

  3. 自定义命令

    healthcheck:
      test: ["CMD-SHELL", "curl --fail http://localhost:80 || exit 1"]
      interval: 30s
      timeout: 10s
      retries: 5

    在上述示例中 , healthcheck字段的 test 属性是一个数组 , 其中第一个元素是CMD-SHELL , 表示使用shell执行命令。第二个元素是一个自定义的命令 , 与前面的示例相同。

3.2.6.3 CMD-SHELL 与 CMD

CMD-SHELL 和 CMD 都是 Dockerfile 中 RUN 指令以及 Docker Compose 中 healthcheck 指令中常用的命令格式 , 两者之间的区别如下 :

  • CMD-SHELL(这里推荐) : 表示使用shell执行命令。在Docker Compose中 , 健康检查的test属性中可以使用CMD-SHELL 来执行自定义的shell命令。

  • CMD : 表示执行指定的命令或者命令参数。在Dockerfile中 , CMD常用于指定容器启动时需要执行的命令 , 而在Docker Compose 中 , CMD常用于指定服务启动时需要执行的命令或者命令参数。

两者的使用方式不同 , 但都可以用于执行命令或者命令参数。在Dockerfile中 , CMD-SHELL 并不是一个有效的指令 , 而在Docker Compose中 ,CMD用于定义服务的启动命令 , 而 healthcheck 中的test属性可以使用CMD-SHELL来执行自定义的shell命令。其实CMD在docker compose healthcheck 也是可以使用的。只是更建议使用CMD-SHELL。

3.2.6.4 示例讲解

以下是一个简单的Docker Compose文件 , 其中定义了一个健康检查 :

version: "3"
services:
  web:
    image: nginx
    ports:
      - "80:80"
    healthcheck:
      #test: ["CMD", "curl", "-f", "http://localhost"]
      test: ["CMD-SHELL", "curl -f http://localhost"]
      interval: 1m
      timeout: 10s
      retries: 3

在这个例子中 , web服务使用nginx镜像 , 并将端口80映射到主机上的端口80。此外 , 它定义了一个健康检查 , 该检查将定期运行curl命令来测试服务是否响应HTTP请求。具体来说 , 该检查将每隔1分钟运行一次 , 超时时间为10秒 , 并尝试重试3次。

您可以使用以下命令启动该服务 :

# 也通过-f指定docker-compose文件
docker-compose up

在服务启动后 , Compose将定期运行健康检查 , 并根据检查结果重启服务。您可以使用以下命令查看服务的健康状态 :

docker-compose ps

此命令将显示服务的健康状态 , 例如 :

   Name           Command              State          Ports        
-------------------------------------------------------------------
webapp_web_1   nginx -g daemon off;   Up (healthy)   0.0.0.0:80->80/tcp

在这个例子中 , 服务的健康状态为"Up (healthy)" , 这表示服务正在运行并且健康检查通过。

3.2.7 docker-compose 对容器资源限制

在使用docker-compose时 , 可以通过在docker-compose.yml文件中设置特定的参数来限制Docker容器的资源。以下是一些可以设置的参数 :

  • cpus : 限制CPU的使用量。例如 , 如果设置为0.5 , 则表示容器可以使用50%的CPU资源。

  • mem_limit: 限制内存的使用量。可以使用M或G来表示内存的大小。例如 , 如果设置为512M , 则表示容器可以使用512MB的内存。

这些参数需要在服务的定义下的deploy部分进行设置。例如 :

version: '3'
services:
  web:
    image: nginx
    deploy:
      resources:
        limits:
          cpus: '0.50'
          memory: 512M

在这个例子中 , 我们限制了名为web的服务的CPU使用量为50% , 内存使用量为512MB。

除了cpus和memory之外 , Docker还提供了其他一些参数来限制容器的资源使用。以下是一些常用的参数 :

  • cpuset: 指定容器可以使用的CPU集。例如 , 如果设置为"0-3" , 则表示容器可以使用CPU 0到3。

  • memswap_limit: 限制容器可以使用的swap内存。这个值包括了mem_limit设置的内存限制。例如 , 如果mem_limit设置为300M , memswap_limit设置为1G , 那么容器可以使用300M的物理内存和700M的swap内存。

  • oom_kill_disable: 如果设置为true , 当容器超出内存限制时 , 内核不会杀死容器。相反 , 它会杀死容器内的进程来释放内存。

  • oom_score_adj: 设置容器在内存不足时被杀死的优先级。值越高 , 容器被杀死的可能性越大。

这些参数同样需要在deploy部分进行设置。例如 :


version: '3'
services:
  web:
    image: nginx
    deploy:
      resources:
        limits:
          cpus: '0.50'
          memory: 512M
          cpuset: '0-3'
          memswap_limit: 1G
        reservations:
          memory: 256M
      restart_policy:
        condition: on-failure

在这个例子中 , 我们限制了名为web的服务的CPU使用量为50% , 内存使用量为512MB , CPU集为0到3 , swap内存为1G , 并且设置了内存预留为256M。

这些设置只在使用Docker Swarm模式时才会生效。如果你只是在单个主机上运行Docker容器 , 你需要使用docker run命令的相关参数来限制资源。

3.3 域名解析 DNS

Docker Compose中的容器可以使用容器名称或服务名称来相互访问 , 而不需要使用IP地址。这是因为Docker Compose会为每个服务创建一个DNS记录 , 这些记录由默认的DNS解析器处理。

默认情况下 , Docker Compose会创建一个名为"projectname_default"的网络 , 并将所有服务连接到该网络中。该网络使用Docker内置的DNS解析器 , 为每个服务和容器分配一个DNS名称。例如 , 如果您的Compose项目名为"myproject" , 那么您可以使用以下命令查看所有服务的DNS名称 :

docker-compose run <service> nslookup <service>

例如 , 如果您的服务名称为"web" , 则可以使用以下命令查看web服务的DNS名称 :

docker-compose run web nslookup web

这将输出web服务的DNS记录 , 包括IP地址和DNS名称。例如 :

Server:    127.0.0.11
Address 1: 127.0.0.11

Name:      web
Address 1: 172.18.0.2

在这个例子中 , web服务的DNS名称为"web" , IP地址为172.18.0.2。您可以使用该名称( "web" ) 来访问该服务 , 而无需使用IP地址。

4. 案例说明

4.1 从docker compose启动单个容器

  • 创建docker compose文件

    docker compose文件可在任意目录,创建文件名为docker-compose.yml配置文件,要注意前后的缩进

    [root@ubuntu1804 ~]#docker-compose --version
    docker-compose version 1.25.4, build unknown
    [root@ubuntu1804 ~]#mkdir /data/docker-compose
    [root@ubuntu1804 ~]#cd /data/docker-compose
    [root@ubuntu1804 docker-compose]#vim  docker-compose.yml
    [root@ubuntu1804 docker-compose]#cat docker-compose.yml
    service-nginx-web:
      image: docker pull 10.0.0.102/example/nginx-centos7-base:1.6.1
      container_name: nginx-web
      expose:
       - 80 
       - 443
      ports:
        - "80:80"
        - "443:443"
  • 查看配置和格式检查

    [root@ubuntu1804 docker-compose]#docker-compose  config 
    services:
      service-nginx-web:
        container_name: nginx-web
        expose:
        - 80
        - 443
        image: 10.0.0.102/example/nginx-centos7-base:1.6.1
        network_mode: bridge
        ports:
        - 80:80/tcp
        - 443:443/tcp
    version: '2.1'
    
    [root@ubuntu1804 docker-compose]#docker-compose  config -q
    
    #改错ocker-compose文件格式
    [root@ubuntu1804 docker-compose]#vim docker-compose.yml
    service-nginx-web   #改此行,最后的”:"删除                           
      image: 10.0.0.102/example/nginx-centos7-base:1.6.1
      container_name: nginx-web
      expose:
       - 80
       - 443
      ports:
        - "80:80"
        - "443:443"
    
    [root@ubuntu1804 docker-compose]#docker-compose  config -q
    ERROR: yaml.scanner.ScannerError: mapping values are not allowed here
      in "./docker-compose.yml", line 2, column 8
    [root@ubuntu1804 docker-compose]#

  • 启动容器

    注意 : 必须要在docker compose文件所在的目录执行 :

    #前台启动
    [root@ubuntu1804 docker-compose]#docker-compose up
    Pulling service-nginx-web (10.0.0.102/example/nginx-centos7-base:1.6.1)...
    ERROR: Get https://10.0.0.102/v2/: dial tcp 10.0.0.102:443: connect: connection refused
    [root@ubuntu1804 docker-compose]#vim /lib/systemd/system/docker.service 
    ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --insecure-registry 10.0.0.102 
    [root@ubuntu1804 docker-compose]#systemctl daemon-reload 
    [root@ubuntu1804 docker-compose]#systemctl restart docker
    [root@ubuntu1804 docker-compose]#docker-compose up
    Pulling service-nginx-web (10.0.0.102/example/nginx-centos7-base:1.6.1)...
    1.6.1: Pulling from example/nginx-centos7-base
    f34b00c7da20: Pull complete
    544476d462f7: Pull complete
    39345915aa1b: Pull complete
    d5376f2bbd9e: Pull complete
    4596aecee927: Pull complete
    1617b995c379: Pull complete
    d00df95be654: Pull complete
    Digest: sha256:82e9e7d8bf65e160ba79a92bb25ae42cbbf791092d1e09fb7de25f91b31a21ff
    Status: Downloaded newer image for 10.0.0.102/example/nginx-centos7-base:1.6.1
    Creating nginx-web ... done
    Attaching to nginx-web
    
    #以上是前台执行不退出

  • 验证docker compose执行结果

    #上面命令是前台执行,所以要查看结果,可以再开一个终端窗口进行观察
    [root@ubuntu1804 ~]#docker ps 
    CONTAINER ID        IMAGE                                         COMMAND                  CREATED             STATUS              PORTS                                      NAMES
    d71030504f6a        10.0.0.102/example/nginx-centos7-base:1.6.1   "/apps/nginx/sbin/ng…"   15 seconds ago      Up 13 seconds       0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp   nginx-web
    [root@ubuntu1804 ~]#docker-compose ps 
    ERROR: 
            Can't find a suitable configuration file in this directory or any
            parent. Are you in the right directory?
    
            Supported filenames: docker-compose.yml, docker-compose.yaml
    
    [root@ubuntu1804 ~]#cd /data/docker-compose/
    [root@ubuntu1804 docker-compose]#docker-compose ps 
      Name             Command           State                    Ports                  
    -------------------------------------------------------------------------------------
    nginx-web   /apps/nginx/sbin/nginx   Up      0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
    
    [root@ubuntu1804 docker-compose]#curl 127.0.0.1/app/
    Test Page in app
    [root@ubuntu1804 docker-compose]#docker-compose images
    Container                Repository                  Tag      Image Id       Size  
    -----------------------------------------------------------------------------------
    nginx-web   10.0.0.102/example/nginx-centos7-base   1.6.1   ea3840c349e5   413.4 MB
    
    [root@ubuntu1804 docker-compose]#docker-compose exec service-nginx-web bash
    [root@17c17ad30193 /]# 
    [root@17c17ad30193 /]# 
    [root@17c17ad30193 /]# 
    [root@17c17ad30193 /]# tail -f /apps/nginx/logs/access.log 
    172.17.0.1 - - [04/Feb/2020:16:01:42 +0800] "GET /app/ HTTP/1.1" 200 17 "-" "curl/7.58.0"
    10.0.0.101 - - [04/Feb/2020:16:06:29 +0800] "GET /app/ HTTP/1.1" 200 17 "-" "curl/7.58.0"
    10.0.0.102 - - [04/Feb/2020:16:08:22 +0800] "GET /app/ HTTP/1.1" 200 17 "-" "curl/7.58.0"

  • 结束前台执行

    [root@ubuntu1804 docker-compose]#docker-compose up
    Pulling service-nginx-web (10.0.0.102/example/nginx-centos7-base:1.6.1)...
    1.6.1: Pulling from example/nginx-centos7-base
    f34b00c7da20: Pull complete
    544476d462f7: Pull complete
    39345915aa1b: Pull complete
    d5376f2bbd9e: Pull complete
    4596aecee927: Pull complete
    1617b995c379: Pull complete
    d00df95be654: Pull complete
    Digest: sha256:82e9e7d8bf65e160ba79a92bb25ae42cbbf791092d1e09fb7de25f91b31a21ff
    Status: Downloaded newer image for 10.0.0.102/example/nginx-centos7-base:1.6.1
    Creating nginx-web ... done
    Attaching to nginx-web
    ^CGracefully stopping... (press Ctrl+C again to force)  #ctrl+c键,结束容器
    Stopping nginx-web ... done
    [root@ubuntu1804 docker-compose]#docker-compose ps 
      Name             Command           State    Ports
    ---------------------------------------------------
    nginx-web   /apps/nginx/sbin/nginx   Exit 0        
    [root@ubuntu1804 docker-compose]#docker ps -a
    CONTAINER ID        IMAGE                                         COMMAND                  CREATED             STATUS                          PORTS               NAMES
    d71030504f6a        10.0.0.102/example/nginx-centos7-base:1.6.1   "/apps/nginx/sbin/ng…"   5 minutes ago       Exited (0) About a minute ago                       nginx-web
    
    [root@ubuntu1804 docker-compose]#docker-compose start
    Starting service-nginx-web ... done
    [root@ubuntu1804 docker-compose]#docker-compose ps 
      Name             Command           State                    Ports                  
    -------------------------------------------------------------------------------------
    nginx-web   /apps/nginx/sbin/nginx   Up      0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
    
    #关闭容器
    [root@ubuntu1804 docker-compose]#docker-compose kill
    Killing nginx-web ... done
    [root@ubuntu1804 docker-compose]#docker-compose ps 
      Name             Command            State     Ports
    -----------------------------------------------------
    nginx-web   /apps/nginx/sbin/nginx   Exit 137

  • 删除容器

    [root@ubuntu1804 docker-compose]#docker-compose ps
      Name             Command           State    Ports
    ---------------------------------------------------
    nginx-web   /apps/nginx/sbin/nginx   Exit 0     
    
    #只删除停止的容器
    [root@ubuntu1804 docker-compose]#docker-compose rm
    Going to remove nginx-web
    Are you sure? [yN] y
    Removing nginx-web ... done
    [root@ubuntu1804 docker-compose]#docker-compose up -d
    Creating nginx-web ... done
    [root@ubuntu1804 docker-compose]#docker-compose rm
    No stopped containers
    
    #停止并删除容器
    [root@ubuntu1804 docker-compose]#docker-compose down
    Stopping nginx-web ... done
    Removing nginx-web ... done
    [root@ubuntu1804 docker-compose]#docker-compose ps 
    Name   Command   State   Ports
    ------------------------------
    [root@ubuntu1804 docker-compose]#docker ps -a
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
    #也会自动删除镜像
    [root@ubuntu1804 docker-compose]#docker-compose  images
    Container   Repository   Tag   Image Id   Size
    ----------------------------------------------

  • 后台执行

    [root@ubuntu1804 docker-compose]#docker-compose  up -d
    Creating nginx-web ... done
    [root@ubuntu1804 docker-compose]#docker-compose  ps 
      Name             Command           State                    Ports                  
    -------------------------------------------------------------------------------------
    nginx-web   /apps/nginx/sbin/nginx   Up      0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
    [root@ubuntu1804 docker-compose]#curl 127.0.0.1/app/
    Test Page in app
    [root@ubuntu1804 docker-compose]#curl http://127.0.0.1/app/
    Test Page in app

  • 停止和启动与日志查看

    [root@ubuntu1804 docker-compose]#docker-compose stop
    Stopping nginx-web ... done
    [root@ubuntu1804 docker-compose]#docker-compose  ps 
      Name             Command           State    Ports
    ---------------------------------------------------
    nginx-web   /apps/nginx/sbin/nginx   Exit 0 
    [root@ubuntu1804 docker-compose]#docker-compose start 
    Starting service-nginx-web ... done
    [root@ubuntu1804 docker-compose]#docker-compose  ps 
      Name             Command           State                    Ports                  
    -------------------------------------------------------------------------------------
    nginx-web   /apps/nginx/sbin/nginx   Up      0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
    
    [root@ubuntu1804 docker-compose]#docker-compose  restart
    Restarting nginx-web ... done
    [root@ubuntu1804 docker-compose]#docker-compose  ps 
      Name             Command           State                    Ports                  
    -------------------------------------------------------------------------------------
    nginx-web   /apps/nginx/sbin/nginx   Up      0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
    
    #执行上面操作时,可以同时开一个终端,观察日事件
    [root@ubuntu1804 docker-compose]#docker-compose events
    2020-02-04 15:38:13.253822 container kill 5d92e4da8679a973145e5b4db364ae8cf8596a03c4fd0b3b6a28213a2f155be6 (image=10.0.0.102/example/nginx-centos7-base:1.6.1, name=nginx-web)
    2020-02-04 15:38:13.531208 container die 5d92e4da8679a973145e5b4db364ae8cf8596a03c4fd0b3b6a28213a2f155be6 (image=10.0.0.102/example/nginx-centos7-base:1.6.1, name=nginx-web)
    2020-02-04 15:38:13.631137 container stop 5d92e4da8679a973145e5b4db364ae8cf8596a03c4fd0b3b6a28213a2f155be6 (image=10.0.0.102/example/nginx-centos7-base:1.6.1, name=nginx-web)
    2020-02-04 15:38:15.137495 container start 5d92e4da8679a973145e5b4db364ae8cf8596a03c4fd0b3b6a28213a2f155be6 (image=10.0.0.102/example/nginx-centos7-base:1.6.1, name=nginx-web)
    2020-02-04 15:38:15.137546 container restart 5d92e4da8679a973145e5b4db364ae8cf8596a03c4fd0b3b6a28213a2f155be6 (image=10.0.0.102/example/nginx-centos7-base:1.6.1, name=nginx-web)
    
    #以json格式显示日志
    [root@ubuntu1804 docker-compose]#docker-compose events --json
    {"time": "2020-02-04T15:48:22.423539", "type": "container", "action": "kill", "id": "19d72e9bc85842d8879d7dcf2a3d2defd79a5a0c3c3d974ddfbbbc6e95bf910b", "service": "service-nginx-web", "attributes": {"name": "nginx-web", "image": "10.0.0.102/example/nginx-centos7-base:1.6.1"}}
    {"time": "2020-02-04T15:48:22.537200", "type": "container", "action": "exec_die", "id": "19d72e9bc85842d8879d7dcf2a3d2defd79a5a0c3c3d974ddfbbbc6e95bf910b", "service": "service-nginx-web", "attributes": {"name": "nginx-web", "image": "10.0.0.102/example/nginx-centos7-base:1.6.1"}}
    {"time": "2020-02-04T15:48:22.745670", "type": "container", "action": "die", "id": "19d72e9bc85842d8879d7dcf2a3d2defd79a5a0c3c3d974ddfbbbc6e95bf910b", "service": "service-nginx-web", "attributes": {"name": "nginx-web", "image": "10.0.0.102/example/nginx-centos7-base:1.6.1"}}
    {"time": "2020-02-04T15:48:22.863375", "type": "container", "action": "stop", "id": "19d72e9bc85842d8879d7dcf2a3d2defd79a5a0c3c3d974ddfbbbc6e95bf910b", "service": "service-nginx-web", "attributes": {"name": "nginx-web", "image": "10.0.0.102/example/nginx-centos7-base:1.6.1"}}
    {"time": "2020-02-04T15:48:23.979421", "type": "container", "action": "start", "id": "19d72e9bc85842d8879d7dcf2a3d2defd79a5a0c3c3d974ddfbbbc6e95bf910b", "service": "service-nginx-web", "attributes": {"name": "nginx-web", "image": "10.0.0.102/example/nginx-centos7-base:1.6.1"}}
    {"time": "2020-02-04T15:48:23.979468", "type": "container", "action": "restart", "id": "19d72e9bc85842d8879d7dcf2a3d2defd79a5a0c3c3d974ddfbbbc6e95bf910b", "service": "service-nginx-web", "attributes": {"name": "nginx-web", "image": "10.0.0.102/example/nginx-centos7-base:1.6.1"}}

  • 暂停和恢复

    [root@ubuntu1804 docker-compose]#docker-compose  pause
    Pausing nginx-web ... done
    [root@ubuntu1804 docker-compose]#docker-compose  ps 
      Name             Command           State                     Ports                  
    --------------------------------------------------------------------------------------
    nginx-web   /apps/nginx/sbin/nginx   Paused   0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
    [root@ubuntu1804 docker-compose]#curl -m 1  http://127.0.0.1/app/
    curl: (28) Operation timed out after 1002 milliseconds with 0 bytes received
    [root@ubuntu1804 docker-compose]#docker-compose  unpause
    Unpausing nginx-web ... done
    [root@ubuntu1804 docker-compose]#docker-compose  ps 
      Name             Command           State                    Ports                  
    -------------------------------------------------------------------------------------
    nginx-web   /apps/nginx/sbin/nginx   Up      0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
    [root@ubuntu1804 docker-compose]#curl -m 1  http://127.0.0.1/app/
    Test Page in app

  • 指定同时启动容器的数量

    [root@ubuntu1804 docker-compose]#vim docker-compose.yml 
    [root@ubuntu1804 docker-compose]#cat docker-compose.yml
    service-nginx-web:
      image: 10.0.0.102/example/nginx-centos7-base:1.6.1
    #  container_name: nginx-web #同时启动多个同一镜像的容器,不要指定容器名称,否则会冲突
      expose:
       - 80 
       - 443
    #  ports:                    #同时启动多个同一镜像的容器,不要指定端口号,否则会冲突
    #    - "80:80"
    #    - "443:443"
    
    #再加一个service
    service-tomcat:
      image: 10.0.0.102/example/tomcat-base:v8.5.50
    
    [root@ubuntu1804 docker-compose]#docker-compose  ps 
    Name   Command   State   Ports
    ------------------------------
    [root@ubuntu1804 docker-compose]#docker-compose  up -d --scale service-nginx-web=2
    Creating docker-compose_service-tomcat_1    ... done
    Creating docker-compose_service-nginx-web_1 ... done
    Creating docker-compose_service-nginx-web_2 ... done
    [root@ubuntu1804 docker-compose]#docker-compose  ps 
                   Name                         Command           State         Ports     
    --------------------------------------------------------------------------------------
    docker-compose_service-nginx-web_1   /apps/nginx/sbin/nginx   Up       443/tcp, 80/tcp
    docker-compose_service-nginx-web_2   /apps/nginx/sbin/nginx   Up       443/tcp, 80/tcp
    docker-compose_service-tomcat_1      /bin/bash                Exit 0                  
    [root@ubuntu1804 docker-compose]#docker-compose  up -d --scale service-nginx-web=3 --scale service-tomcat=2
    Starting docker-compose_service-tomcat_1    ... done
    Starting docker-compose_service-nginx-web_1 ... done
    Starting docker-compose_service-nginx-web_2 ... done
    Creating docker-compose_service-nginx-web_3 ... done
    Creating docker-compose_service-tomcat_2    ... done
    [root@ubuntu1804 docker-compose]#docker-compose  ps 
                   Name                         Command           State         Ports     
    --------------------------------------------------------------------------------------
    docker-compose_service-nginx-web_1   /apps/nginx/sbin/nginx   Up       443/tcp, 80/tcp
    docker-compose_service-nginx-web_2   /apps/nginx/sbin/nginx   Up       443/tcp, 80/tcp
    docker-compose_service-nginx-web_3   /apps/nginx/sbin/nginx   Up       443/tcp, 80/tcp
    docker-compose_service-tomcat_1      /bin/bash                Exit 0                  
    docker-compose_service-tomcat_2      /bin/bash                Exit 0                  
    [root@ubuntu1804 docker-compose]#docker-compose  up -d 
    Stopping and removing docker-compose_service-nginx-web_2 ... done
    Stopping and removing docker-compose_service-nginx-web_3 ... done
    Stopping and removing docker-compose_service-tomcat_2    ... done
    Starting docker-compose_service-tomcat_1                 ... done
    Starting docker-compose_service-nginx-web_1              ... done
    [root@ubuntu1804 docker-compose]#docker-compose  ps 
                   Name                         Command           State         Ports     
    --------------------------------------------------------------------------------------
    docker-compose_service-nginx-web_1   /apps/nginx/sbin/nginx   Up       443/tcp, 80/tcp
    docker-compose_service-tomcat_1      /bin/bash                Exit 0 

4.2 从docker compose启动多个容器

  • 编辑docker-compose文件并使用数据卷

    注意 : 同一个文件 ,数据卷的优先级比镜像内的文件优先级高

    [root@ubuntu1804 docker-compose]#vim docker-compose.yml 
    [root@ubuntu1804 docker-compose]#cat  docker-compose.yml 
    service-nginx-web:
      image: 10.0.0.102/example/nginx-centos7-base:1.6.1
      container_name: nginx-web 
      volumes:
        - /data/nginx:/apps/nginx/html/#指定数据卷,将宿主机/data/nginx挂载到容器/apps/nginx/html
      expose:
       - 80 
       - 443
      ports:
        - "80:80"
        - "443:443"
    
    service-tomcat-app1:
      image: 10.0.0.102/example/tomcat-web:app1
      container_name: tomcat-app1
      expose:
        - 8080
      ports:
        - "8081:8080"
    
    service-tomcat-app2:
      image: 10.0.0.102/example/tomcat-web:app2
      container_name: tomcat-app2
      expose:
        - 8080
      ports:
        - "8082:8080"
    
    #在宿主机准备nginx测试页面文件
    [root@ubuntu1804 docker-compose]#mkdir /data/nginx
    [root@ubuntu1804 docker-compose]#echo Docker compose test page > /data/nginx/index.html

  • 启动容器并验证结果

    [root@ubuntu1804 docker-compose]#docker-compose up -d
    Pulling service-tomcat-app1 (10.0.0.102/example/tomcat-web:app1)...
    app1: Pulling from example/tomcat-web
    f34b00c7da20: Already exists
    544476d462f7: Already exists
    39345915aa1b: Already exists
    4b792f2bae38: Already exists
    4439447a3522: Already exists
    fe34d2ec1dd0: Already exists
    b8487ca03126: Already exists
    5a475b7d8b1a: Already exists
    df8703d3d2dd: Already exists
    f0da1ffa7aa7: Pull complete
    80fd4c70e670: Pull complete
    c2a0247d7bfa: Pull complete
    b0977ed809cd: Pull complete
    Digest: sha256:e0aba904df6095ea04c594d6906101f8e5f4a6ceb0a8f9b24432c47698d0caa8
    Status: Downloaded newer image for 10.0.0.102/example/tomcat-web:app1
    Pulling service-tomcat-app2 (10.0.0.102/example/tomcat-web:app2)...
    app2: Pulling from example/tomcat-web
    f34b00c7da20: Already exists
    544476d462f7: Already exists
    39345915aa1b: Already exists
    4b792f2bae38: Already exists
    4439447a3522: Already exists
    fe34d2ec1dd0: Already exists
    b8487ca03126: Already exists
    5a475b7d8b1a: Already exists
    df8703d3d2dd: Already exists
    f0da1ffa7aa7: Already exists
    80fd4c70e670: Already exists
    1a55cb76a801: Pull complete
    565ab795f82a: Pull complete
    Digest: sha256:c4d6f166c3933f6c1ba59c84ea0518ed653af25f28b87981c242b0deff4209bb
    Status: Downloaded newer image for 10.0.0.102/example/tomcat-web:app2
    Creating tomcat-app1 ... done
    Creating tomcat-app2 ... done
    Creating nginx-web   ... done
    
    [root@ubuntu1804 docker-compose]#docker-compose  ps 
       Name                  Command               State                    Ports                  
    -----------------------------------------------------------------------------------------------
    nginx-web     /apps/nginx/sbin/nginx           Up      0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
    tomcat-app1   /apps/tomcat/bin/run_tomcat.sh   Up      8009/tcp, 0.0.0.0:8081->8080/tcp        
    tomcat-app2   /apps/tomcat/bin/run_tomcat.sh   Up      8009/tcp, 0.0.0.0:8082->8080/tcp        
    [root@ubuntu1804 docker-compose]#curl http://127.0.0.1/
    Docker compose test page
    [root@ubuntu1804 docker-compose]#curl http://127.0.0.1:8081/app/
    Tomcat Page in app1
    [root@ubuntu1804 docker-compose]#curl http://127.0.0.1:8082/app/
    Tomcat Page in app2

4.3 基于docker-compose搭建wordpress

  1. 创建docker-compose.yml文件 , 在指定的目录下创建docker-compose.yml文件

    [root@dockerwordpress]#cat  docker-compose.yml
    version: '3.3'
     
    services:
       wordpress:
         depends_on:
           - db
         image: wordpress:latest
         volumes:
           - wordpress_files:/var/www/html
         ports:
           - "8080:80"   # 指定宿主机的端口号,左边时宿主机的暴露端口号,右边是容器暴露端口号
         restart: always
         environment:
           WORDPRESS_DB_HOST: db:3306
           WORDPRESS_DB_NAME: wpdb   # 指定数据库名称
           WORDPRESS_DB_USER: wpuser  # 指定wordpass名称
           WORDPRESS_DB_PASSWORD: wppass  # 指定wordpass名称
     
       db:
         image: mysql:5.7
         volumes:
           - db_data:/var/lib/mysql
         restart: always
         environment:
           MYSQL_ROOT_PASSWORD: centos   # 指定数据库密码
           MYSQL_DATABASE: wpdb  # 指定数据库名称,与上面一致
           MYSQL_USER: wpuser  # 与上面的wordpass名称一致
           MYSQL_PASSWORD: wppass  #  与上面指定名称一致
    volumes:
        wordpress_files:
        db_data:
  2. 拉取数据库和镜像

    # docker pull wordpress
    #  docker pull mysql:5.7
  3. 启动创建的wordpress

    [root@dockerwordpress]#docker-compose up -d    # 第一次启动使用up选项,-d是在后台启动容器
    Creating network "wordpress_default" with the default driver
    Creating volume "wordpress_wordpress_files" with default driver
    Creating wordpress_db_1        ... done
    Creating wordpress_db_1        ...
    Creating wordpress_wordpress_1 ... done
  4. 在页面上访问并查看效果

    访问192.168.7.101:8080的URL,此时就会就会访问wordpress

    docker-compose-1


参考链接

docker-容器编排管理工具docker compse基础 - 运维派 (yunweipai.com)

docker-compose 进阶篇 (qq.com)

Docker Compose : 从零基础到实战应用的全面指南 (qq.com)

如何通过docker-compose对docker容器资源进行限制 (qq.com)

Docker之九---容器编排工具Docker Compose详解 - 一叶知秋~~ - 博客园 (cnblogs.com)