• Docker Compose教程


    docker-compose是Docker官方提供的开源项目,负责实现对Docker容器集群的快速编排。
    docker容器本身占用资源极少,所以docker官方建议我们每一个容器只运行一个服务,即将每个服务单独的分割开来。但是如果分隔开来的话,就需要启动多个容器,如果遇到迁移、重启等操作,就需要花费很多时间,所以docker官方又提供了docker-compose工具,支持用户按照一定的业务规则批量管理容器。

    Compose允许用户通过一个单独的docker-compose.yml模板文件来定义一组相关的应用容器为一个项目。即可以非常容易地用一个配置文件定义一个多容器,然后使用一条指令安装应用的所有依赖,完成多个容器的构建,解决了容器与容器之间如何管理编排的问题。

    docker-compose安装

    macOS、Windows系统使用的Docker Desktop默认已经安装。可以通过docker-compose version查看安装的版本。
    具体的安装可以根据官方教程来:Install Docker Compose-Overview
    也可以网上找具体的教程,这里不具体展示了。

    docker-compose的使用

    想要了解docker-compose,则需要了解docker中镜像、容器之间的使用,特别是需要了解docker run命令。

    简单入门

    刚开始可能对docker-compose的不太了解,我们可以先简单的认为docker-compose是对docker run命令的解析。
    首先可以先了解下docker部署mysql的操作(相关步骤可以参考:docker常用应用部署,我们按照这个示例来讲如何使用docker-compose实现mysql的部署。
    官方给出使用docker-compose的3个步骤:
    在这里插入图片描述
    我们可以先看步骤2、3(步骤1后面再涉及),从步骤2来看,我们需要有个docker-compose.yml文件。docker-compose.yml对docker run命令的解析说明如下:
    docker run命令如下:

    docker run -id --name=test_mysql -p 3307:3306 \
    -v $PWD/conf:/etc/mysql/conf.d \
    -v $PWD/logs:/logs \
    -v $PWD/data:/var/lib/mysql \
    -e MYSQL_ROOT_PASSWORD=wenxiaoba \
    mysql:latest
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    以下是解析的docker-compose.yml(yaml文件的具体语法参考:YAML 入门教程):

    # 确认使用docker-compose项目的版本号
    version: "3.8"
    
    services:  # 服务群,即一组容器,容器的信息都在services下定义
     regx_mysql:  # 如果下一层没有设置container_name,则docker-compose会根据该名称按照规则生成容器的容器名称
      container_name: test_mysql  # 定义容器名称
      image: mysql:latest  # 生成容器时使用的镜像
      ports:
        - 3307:3306  # 指定端口映射,相当于docker run -p参数
      volumes:  # 相当于docker run -v参数
        - ./conf:/etc/mysql/conf.d
        - ./logs:/logs
        - ./data:/var/lib/mysql
      environment:  # 相当于docker run -e参数
        - "MYSQL_ROOT_PASSWORD=wenxiaoba"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    解析说明:

    • version:指定docker-compose项目的版本号,具体使用后面会讲
    • services:容器相关的信息都需要在这里定义,下一层就是对容器的定义(可以定义多个容器)
    • test_mysql:若没有设置container_name,则docker-compose会根据该名称按照相关规则生成容器名称
    • container_name:设置容器名称
    • image:指定当前容器使用的镜像,格式:镜像名称:版本号(没有版本号的话,默认是latest)
    • ports:指定端口映射,格式为:主机(宿主)端口:容器端口,相当于docker run -p参数
    • volumes:绑定数据卷,格式为:宿主机路径:容器路径,相当于docker run -v参数
    • environment:设置环境变量,相当于docker run -e参数

    在这里插入图片描述

    远程连接mysql,连接成功
    在这里插入图片描述
    docker-compose up命令会获取当前目录下的docker-compose.yml文件(文件名称与后缀是固定的,除非使用docker-compose命令时加上-f选项),根据docker-compose.yml的内容,按照规则去启动容器

    docker-compose.yml模板

    模板组成

    docker-compose.yml文件中定义了一组容器的信息,定义了:version(已弃用)、services(必需)、networks、volumes、configs和secrets

    • version:指定docker-compose的版本号,已被弃用,可不用加,根据当前的docker引擎的版本确定,版本设置参考:Compose file version 3 reference ,本地的docker版本,可以根据命令docker version获取到
    • services:必需字段,包含了容器相关的字段(镜像、数据卷、端口号映射、环境变量设置等)
    • networks、volumes、configs和secrets:非必需字段,根据services中容器的配置进行

    docker-compose.yml模板官网示例:

    services:
      frontend:
        image: awesome/webapp
        ports:
          - "443:8043"
        networks:
          - front-tier
          - back-tier
        configs:
          - httpd-config
        secrets:
          - server-certificate
    
      backend:
        image: awesome/database
        volumes:
          - db-data:/etc/data
        networks:
          - back-tier
    
    volumes:
      db-data:
        driver: flocker
        driver_opts:
          size: "10GiB"
    
    configs:
      httpd-config:
        external: true
    
    secrets:
      server-certificate:
        external: true
    
    networks:
      # The presence of these objects is sufficient to define them
      front-tier: {}
      back-tier: {}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    docker-compose.yml基本包含了容器群的基本信息。services的下一层是容器,services字段下的每一个键值对都表示一个容器,键会被按照规则定义为容器的名称,值则为容器的配置信息。如模板中,services下有frontend、backend共2个键值对,即表示会生成2个容器,容器名称会涉及到“frontend”和“backend”;frontend层下内容,则表示了frontend容器的配置(比如根据哪个镜像生成、端口映射、数据卷配置、网络配置等),backend层下的内容,表示了backend容器的配置。

    模板字段

    关于模板全部的字段,可以看docker官方教程Compose specification
    中文译本可以参考:Compose 模板文件
    容器的一些需要注意的配置字段下面具体介绍下。

    build

    在本章的 简单入门 示例中,我们介绍了如何用镜像去使用docker-compose。实际使用中,经常是使用dockerfile文件去生成容器的,build字段就是docker-compose工具支持dockerfile文件去生成镜像。

    build:在通过docker-compose启动容器之前,会先根据dockerfile构建镜像,然后根据构建的镜像启动容器

    格式:

    services:
    ​
      webapp:
        build:
          context: ./dir
          dockerfile: Dockerfile-alternate
          args:
            buildno: 1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • context:指定dockerfile所在文件夹的路径(即指定上下文)
    • dockerfile:指定Dockerfile文件名
    • args:指定构建镜像时的变量

    我们以docker镜像构建的tomcat镜像dockerfile为例,使用docker-compose命令启动容器
    编辑dockerfile文件(tomcat_dockerfile):

    FROM tomcat:jre17-temurin
    
    MAINTAINER wenxiaoba 
    
    RUN cp -r webapps.dist/* webapps/
    
    RUN rm ./webapps/ROOT/index.jsp
    
    RUN echo "

    Welcomo to Tomcat Docker

    ---by wenxiaoba, create in docker-compose with dockerfile">./webapps/ROOT/index.html WORKDIR /usr/local/tomcat EXPOSE 8080
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    编辑docker-compose.yml文件:

    services:
           regx_tomcat:
                   build:
                           context: ./
                           dockerfile: tomcat_dockerfile
                   ports:
                           - "8080:8080"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述
    **注意:**相关文件最好放在同一个目录下,方便管理、操作和引用
    在这里插入图片描述
    访问主机的8080端口:
    在这里插入图片描述

    command

    command:覆盖容器启动后默认执行的命令。相当于docker run命令末尾的command命令

    container_name

    container_name:指定docker-compose启动的容器的容器名称,相当于docker run --name参数。如果未设置的话,容器名称默认将会使用 项目名称_服务名称_序号 这样的格式。不建议使用container_name指令

    格式:

    container_name: xxxx
    
    • 1

    注意:由于Docker不允许容器名称重复,所以如果指定了容器名称,则docker-compose up启动容器时,若容器名称重复,会导致启动失败,其他人使用docker-compose.yml启动容器时也会遇到这种问题,所以不推荐使用container_name指令

    depends_on

    depends_on:设置在当前容器启动前需要先启动的容器,即根据容器的依赖设置启动顺寻。

    示例:

    services:
      web:
        build: .
        depends_on:
          - db
          - redis
    ​
      redis:
        image: redis
    ​
      db:
        image: postgres
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在该示例中,web容器会在redis、db容器启动后再启动

    注意:当前容器不会等待被依赖服务【完全启动】后才启动,一般是在快【完全启动】时启动

    environment

    environment:用来给容器启动指定环境变量,相当于docker run -e参数

    有2种格式:

    environment:
      变量名1: 值1
      变量名2: 值2
      ...
    
    • 1
    • 2
    • 3
    • 4

    或:

    environment:
      - 变量名1=值1
      - "变量名2=值2"  # 对于yaml文件来说,双引号加不加都是被识别成字符串
    
    • 1
    • 2
    • 3

    示例:

    services:
     regx_mysql:
      container_name: test_mysql
      image: mysql:latest
      ports:
        - 3307:3306
      volumes:
        - ./conf:/etc/mysql/conf.d
        - ./logs:/logs
        - ./data:/var/lib/mysql
      environment:
        - "MYSQL_ROOT_PASSWORD=wenxiaoba"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在此示例中,设置MYSQL_ROOT_PASSWORD为wenxiaoba(即mysql的root用户密码)

    env_file

    env_file:用来给容器启动指定环境变量文件,相当于docker run -e参数。
    与environment区别:

    • environment指定变量
    • env_file是指定到变量文件,在指定的变量文件中定义具体变量

    格式:

    # 单个变量文件
    env_file: 变量文件路径
    
    # 多个变量文件
    env_file:
      - 变量文件路径1
      - 变量文件路径2
      - 变量文件路径3
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    变量文件格式如下(#开头的为注释行,一行定义一个变量,变量定义格式为变量名=值):

    # 注释的内容
    变量名1=值1
    变量名2=值2
    ...
    
    • 1
    • 2
    • 3
    • 4
    env_file示例:

    在当前目录的.env文件中设置内容如下:

    MYSQL_ROOT_PASSWORD=wenxiaob
    
    • 1

    docker-compose.yml文件内容如下:

    services:
     regx_mysql:
      image: mysql:latest
      ports:
        - 3306:3306
      volumes:
        - ./data:/var/lib/mysql
      env_file: .env
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述
    远程连接mysql成功
    在这里插入图片描述

    env_file和environment的使用场景

    environment的变量及其对应的值是在docker-compose.yml中明文显示的,如果有涉及到比较私密的数据,就不宜分享出去了,所以,如果有私密的数据,则使用env_file,到时候env_file指向的变量可以根据情况进行分享,且变量文件的文件名可以使用.开头,这样会被识别为隐藏文件(虽然ls -a还是能识别,但是好歹比明文显示在docker-compose.yml中的要好一丢丢)

    expose

    expose:指定构建镜像过程容器暴露的端口号,不建议使用

    格式:

    expose:
     - "3000"
     - "8000"
    
    • 1
    • 2
    • 3

    有需要时,镜像中就有指定暴露的端口号(如dockerfile),docker-compose.yml文件一般不指定。

    image

    image:指定创建容器的镜像

    格式:

    image: mysql  # 如果只有名称,则默认版本号是latest
    image: centos:7  # 指定centos,版本7的镜像
    image: a4bc65fd  # 根据镜像id指定镜像(不推荐,镜像id只是本系统唯一,在其他系统可能不存在)
    
    • 1
    • 2
    • 3

    示例:
    在这里插入图片描述

    networks

    networks:指定容器使用的网桥,相当于docker run --network。(如果多个容器使用同一个网桥,则容器之间可以通过容器名通讯,具体内容可以查阅:Docker:网络模式详解尚硅谷2022版Docker实战教程(docker教程天花板)

    示例:

    services:
    
      container1:
        networks:
         - some-network
         - other-network
    
      container2:
        networks:
         - other-network
    
    networks:
      some-network:
      other-network:
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    该示例中,创建了2个networks,container1和container2可以通过通过网桥other-network进行通讯,container1可以通过some-network根其他容器通讯。

    ports

    ports:指定宿主机和容器的端口映射,相当于docker run -p

    示例:

    services:
     regx_mysql:
      container_name: test_mysql
      image: mysql:latest
      ports:
        - 3307:3306  # 宿主机的3307端口与容器的3306端口映射
      volumes:
        - ./data:/var/lib/mysql
      environment:
        - "MYSQL_ROOT_PASSWORD=wenxiaoba"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    volumes

    volumes:指定宿主机和容器的端口映射,相当于docker run -p

    格式:

    volumes:
      - 宿主机路径(绝对路径|相对路径):容器路径(绝对路径)
      - 宿主机路径2:容器路径2
    
    • 1
    • 2
    • 3

    如果想挂载数据卷容器,则services下的容器volumes字段中,:前为数据卷容器名称,且与services同一层级定义volumes,声明数据卷容器。
    宿主机路径的数据卷本章一开始的示例有介绍到,这里只说明下数据卷容器的使用
    在这里插入图片描述

    restart: always

    restart: always:指定docker容器总是运行,即保持容器始终运行,相当于docker run --restart=always

    示例:

    services:
     regx_mysql:
      container_name: test_mysql
      image: mysql:latest
      restart: always  # 保持当前容器始终运行
      ports:
        - 3307:3306
      volumes:
        - ./data:/var/lib/mysql
      environment:
        - "MYSQL_ROOT_PASSWORD=wenxiaoba"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    docker-compose 命令

    docker-compose命令的基本使用格式是:

    docker-compose [-f=…] [options] [COMMAND] [ARGS…]

    • -f,–file:指定使用的compose模板文件,默认为docker-compose.yml,-f可以指定文件(文件名可以不是docker-compose.yml)
    • -p,–project-name:指定项目名称,默认是将

    在这里插入图片描述

    docker-compose命令说明教程包含了docker-compose的命令说明,重点关注up、down,其他的使用docker原生命令也可以达到

    up

    格式为: docker-compose up [options] [SERVICE…]
    描述:该命令会自动完成包括构建镜像、(重新)创建容器、启动容器,并关联相关内容等一系列操作。

    • 默认情况下,启动的容器都在前台,控制台会打印容器的输出信息,可以方便调试,·Ctrl-C`会停止所有容器
    • 如果需要再后台启动容器,可以使用-d选项,即docker-compose up -d,推荐生产环境使用-d选项
    • 默认情况下,若项目所在容器已经存在,docker-compose up会将项目已有容器停止,再重新创建(但保持volumes-from挂载的数据卷【数据非常重要】),以保证新启动的服务匹配 docker-compose.yml 文件的最新内容
    • –force-recreate:强制重新创建容器,不能与 --no-recreate 同时使用。
    • –no-recreate:如果容器已经存在了,则不重新创建,不能与 --force-recreate 同时使用。
    • –no-deps:不启动服务所链接的容器(比如depends_on字段指向的容器)。
    • 单独启动某个容器:
      • 包含链接的容器(depends_on字段等):docker-compose up -d 服务名称
      • 只有指定的容器:docker-compose up --no-deps -d 服务名称
        注意:这里的服务名称是指services下一层的键名

    在这里插入图片描述

    down

    格式:docker-compose down
    描述:停止up命令所启动的容器,并移除网络(network)

    在这里插入图片描述

    exec

    格式:docker-compose exec 服务名称
    进入指定的STATUS为UP的容器(非UP的进不了)

    在这里插入图片描述

    ps

    格式:docker-compose ps
    列出当前docker-compose.yml所运行的服务

    在这里插入图片描述

    restart

    格式:docker-compose restart [服务名称]
    根据当前docker-compose.yml重启已存在的容器(不创建,只重启)

    在这里插入图片描述
    在docker-compose.yml有定义,但是系统中不存在的容器,restart并不会创建并启动,restart只是重启已存在的在docker-compose.yml中有定义的容器

    在这里插入图片描述

    rm

    格式:docker-compose rm [服务名称]
    根据当前服务名称删除对应的容器(容器必须是非UP状态)

    在这里插入图片描述

    logs

    格式:docker-compose logs [-f] [服务名称]
    查看整个项目中所有(或某个)服务的运行日志

    在这里插入图片描述

    逼逼叨

    关于docker-compose.yml(-f参数的话可以是其他名称),模板字段的冒号:后面必须有个空格,否则会被识别成字符串,比如image:redis会被识别字符串”image:redis“,所以英文冒号后面记得加个空格

  • 相关阅读:
    Python 潮流周刊#54:ChatTTS 强大的文本生成语音模型
    adb shell执行定时2小时命令
    jQuery的选择器与自带函数详解
    1V1音视频实时互动直播系统
    WasmEdge 0.10.0 发布!全新的插件扩展机制、Socket API 增强、LLVM 14 支持
    堆排序+TOPK问题
    YB506A是一款锂电池充、放电管理专用芯片,集成锂电池充电管理和降压DCDC电路
    【论文阅读】CVPR2021: MP3: A Unified Model to Map, Perceive, Predict and Plan
    自定义Webpack配置
    2311d更好C析构类
  • 原文地址:https://blog.csdn.net/wenxiaoba/article/details/127597607