• [docker] docker compose


    [docker] docker compose

    docker compose 是一个简化运行 docker 指令的工具,它可以部分代替 docker builddocker run 指令,但是无法取代 docker 指令,更不会取代容器和镜像。它可以运行单个或多个容器,通过运行 YAML 配置好的文件建造镜像和运行容器

    不过 docker compose 有个缺点,它无法管理不同 hosts 上的容器——这个需要通过 类似于 docker swarm/kubernetes 这样的工具去进行管理

    docker compose 文件

    这里不会过多涉及 YAML/YML 的语法,下面分成一个个的 service,每个 service 是在 services 这个 key 下

    不包含 service 具体实现的框架如下:

    version: "3.8"
    services:
      mongodb:
      backend:
      frontend:
    
    volumes:
      data:
      logs:
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    命名规范——默认为 docker-compose.yaml,运行指令时需要在 docker-compose.yaml 同一个文件夹里运行

    mongodb

    mongodb:
      # container_name: mongodb
      image: "mongo"
      volumes:
        - data:/data/db
      # environment:
      #   # - MONGO_INITDB_ROOT_USERNAME=root
      #   MONGO_INITDB_ROOT_PASSWORD: root
      #   MONGO_INITDB_ROOT_USERNAME: root
      env_file:
        - ./env/mongo.env
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    backend

    backend:
      # build: ./backend
      build:
        # should be the highest common parent level
        context: ./backend
        # can be omitted if the name is same as Dockerfile
        dockerfile: Dockerfile
      ports:
        - "80:80"
      volumes:
        - logs:/app/logs
        # can use relative path here
        - ./backend:/app
        - /app/node_modules
      env_file:
        - ./env/backend.env
      depends_on:
        - mongodb
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    frontend

    frontend:
      build: ./frontend
      volumes:
        - ./frontend/src:/app/src
      ports:
        - "3000:3000"
      stdin_open: true
      tty: true
      depends_on:
        - backend
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    运行

    讲配置之前先简单的提一下运行

    up

    安装最新版本的 docker 可以直接通过 docker compoe 去运行,如下面就是直接运行 docker compoe up 的结果:

    docker compose up
    [+] Running 1/0
     ✔ Container compose-mongodb-1  Created                                                                                                                    0.0s
    Attaching to mongodb-1
    # will hang here, but can stop using cmd+c
    # run detached modedocker compose up -d
    [+] Running 1/1
     ✔ Container compose-mongodb-1  Started                                                                                                                    0.0s
    ❯ docker compose down
    [+] Running 2/2
     ✔ Container compose-mongodb-1  Removed                                                                                                                    0.1s
     ✔ Network compose_default      Removed
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    默认情况下 docker compoe up 不会在 detached 模式下运行,但是可以直接使用 cmd/ctrl+c 的方式去终结运行。一旦 docker compoe up 被终止,那么所有的容器就会进入终止状态:

    [+] Stopping 1/2d with code 0
     ✔ Container compose-frontend-1  Stopped                                                                                                                   0.7s
    [+] Stopping 3/3pose-backend-1   Stopping                                                                                                                  0.6s
     ✔ Container compose-frontend-1  Stopped                                                                                                                   0.7s
     ✔ Container compose-backend-1   Stopped                                                                                                                   0.7s
     ✔ Container compose-mongodb-1   Stopped                                                                                                                   0.1s
    mongodb-1 exited with code 0
    canceled
    ❯ docker ps
    CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
    ❯ docker ps -a
    CONTAINER ID   IMAGE              COMMAND                  CREATED          STATUS                     PORTS     NAMES
    04fd7da5b373   compose-frontend   "docker-entrypoint.s…"   18 seconds ago   Exited (1) 7 seconds ago             compose-frontend-1
    9ad9301633bd   compose-backend    "docker-entrypoint.s…"   18 seconds ago   Exited (1) 7 seconds ago             compose-backend-1
    72c2fbe335e4   mongo              "docker-entrypoint.s…"   18 seconds ago   Exited (0) 6 seconds ago             compose-mongodb-1
    9888e9d4cf74   mysql              "docker-entrypoint.s…"   2 days ago       Exited (0) 2 days ago                mysql
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    添加 -d flag 可以在 detached 模式下运行 docker compose

    down

    docker compose down 可以用来终止并清理所有通过 docker-compose.yaml 管理的容器,如:

    docker ps -a
    CONTAINER ID   IMAGE              COMMAND                  CREATED          STATUS                     PORTS     NAMES
    04fd7da5b373   compose-frontend   "docker-entrypoint.s…"   18 seconds ago   Exited (1) 7 seconds ago             compose-frontend-1
    9ad9301633bd   compose-backend    "docker-entrypoint.s…"   18 seconds ago   Exited (1) 7 seconds ago             compose-backend-1
    72c2fbe335e4   mongo              "docker-entrypoint.s…"   18 seconds ago   Exited (0) 6 seconds ago             compose-mongodb-1
    9888e9d4cf74   mysql              "docker-entrypoint.s…"   2 days ago       Exited (0) 2 days ago                mysql
    ❯ docker compose down
    [+] Running 4/4
     ✔ Container compose-frontend-1  Removed                                                                                                                   0.0s
     ✔ Container compose-backend-1   Removed                                                                                                                   0.0s
     ✔ Container compose-mongodb-1   Removed                                                                                                                   0.0s
     ✔ Network compose_default       Removed                                                                                                                   0.1s
    ❯ docker ps -a
    CONTAINER ID   IMAGE     COMMAND                  CREATED      STATUS                  PORTS     NAMES
    9888e9d4cf74   mysql     "docker-entrypoint.s…"   2 days ago   Exited (0) 2 days ago             mysql
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    network

    默认情况下所有 docker-compose 中管理的容器都会在同一个 docker network 中,没有特殊需求可以不用配置

    build 镜像

    默认情况下,如果 docker-compose.yaml 文件中有配置的话,那么 docker compsoe 指令会在找不到所需的镜像这一情况下自动 build

    如果想要强制 docker compose 去重新 build 镜像,可以使用 build 这个 arg

    docker compose build
    [+] Building 1.4s (17/17) FINISHED                                                                                                         docker:desktop-linux
     => [backend internal] load .dockerignore                                                                                                                  0.0s
     => => transferring context: 68B                                                                                                                           0.0s
     => [backend internal] load build definition from Dockerfile                                                                                               0.0s
     => => transferring dockerfile: 202B                                                                                                                       0.0s
     => [frontend internal] load metadata for docker.io/library/node:latest                                                                                    1.1s
     => [frontend 1/5] FROM docker.io/library/node@sha256:162d92c5f1467ad877bf6d8a098d9b04d7303879017a2f3644bfb1de1fc88ff0                                     0.0s
     => [backend internal] load build context                                                                                                                  0.0s
     => => transferring context: 924B                                                                                                                          0.0s
     => CACHED [frontend 2/5] WORKDIR /app                                                                                                                     0.0s
     => CACHED [backend 3/5] COPY package.json .                                                                                                               0.0s
     => CACHED [backend 4/5] RUN npm install                                                                                                                   0.0s
     => CACHED [backend 5/5] COPY . .                                                                                                                          0.0s
     => [backend] exporting to image                                                                                                                           0.0s
     => => exporting layers                                                                                                                                    0.0s
     => => writing image sha256:0b50e06210a6786efef5e4b403eed36760a9fac59a81b75c5b0ba0070918c0e6                                                               0.0s
     => => naming to docker.io/library/compose-backend                                                                                                         0.0s
     => [frontend internal] load build definition from Dockerfile                                                                                              0.0s
     => => transferring dockerfile: 147B                                                                                                                       0.0s
     => [frontend internal] load .dockerignore                                                                                                                 0.0s
     => => transferring context: 70B                                                                                                                           0.0s
     => [frontend internal] load build context                                                                                                                 0.0s
     => => transferring context: 4.31kB                                                                                                                        0.0s
     => CACHED [frontend 3/5] COPY package.json .                                                                                                              0.0s
     => CACHED [frontend 4/5] RUN npm install                                                                                                                  0.0s
     => CACHED [frontend 5/5] COPY . .                                                                                                                         0.0s
     => [frontend] exporting to image                                                                                                                          0.0s
     => => exporting layers                                                                                                                                    0.0s
     => => writing image sha256:98fe0b6f0a0f89aa2c1b36a7a1c54006e5dd0f522209a4d59f2cf768a14c911a                                                               0.0s
     => => naming to docker.io/library/compose-frontend                                                                                                        0.0s
    
    • 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

    ⚠️:docker compose build 不会运行容器,只会重新 build 镜像

    配置

    接下来补充一下配置的内容

    version

    这部分可以通过官方文档查看:Compose file versions and upgrading

    具体还是要看用的是什么 docker engine,大多数情况下可以使用 3.8,即 docker engine 19.03.0+

    目前我的版本是:

    docker engine --version
    Docker version 24.0.7, build afdd53b
    
    • 1
    • 2

    虽然本机上安装的不是最新的版本,不过只差了 3 个 minor 版本,也可以看到大多数情况下用 3.8 就够了

    services

    services 下面列举的是一个个单独的 service,service 可以理解成容器的具体描述,即一个容器应当如何配置和如何运行

    以上面列举的配置为例,mongodb 指的就是当前 service 的名称,并不是容器的名称。比如说 service 的名称是 frontend,但是 docker 容器的名称为 compose-frontend-1

    在 docker swarm 的情况下——我们项目用的是 Kubernetes,所以我应该不会设计 swarm,service 指的是不同的东西

    volumes

    本片配置中,volumes 出现在两个地方,一个和 services 平级,一个在单独的 service 里

    和 services 平级的 volumes 是整个 compose 文件中所有出现过的命名卷及其配置——本片配置出现的都是极简配置。和 services 平级的 volumes 并不是强制要求定义的,不过一般来说被认为是个 good practice

    在单独的 service 中的 volumes 则是当前容器会使用的 volume,包含 bind mounts,anonymous volume 和 named volume

    image

    这是在当前 service 使用的是别人已经实现好的 image 的情况下使用

    如上面实现的 mongodb,我这里没有 load 其他的数据看不需要额外的 Dockerfile 去实现,所以直接使用 image 即可

    build

    这是在需要 tailor 别人实现的 image,添加自己的代码

    前后端有自己实现的代码,需要运行 Dockerfile 去 build 镜像,这里就会使用 build 去实现

    这里的实现方法有两种:

    1. 直接指定 Dockerfile 所在的文件夹地址

      这里可以使用相对路径,所以注释掉的代码用的是 build: ./backend

      这种情况下 compose 会自动寻找该目录下的 Dockerfile 文件去运行

    2. 使用更细节的配置

      这里提到的是 contextdockerfile

      context 是当前 container 的作用域,也就是说 Dockerfile 中所有会涉及到的文件——如 COPY 操作所需要的文件都应存在于当前作用域,不然可能会导致 build 失败

      dockerfile 则是 Dockerfile 的名称,默认情况下为 Dockerfile

    ports

    即端口,可以暴露和 map 多个端口

    环境参数

    这里实现的方法有两种:

    1. 直接写

      这里也有两种实现方法:

      • - MONGO_INITDB_ROOT_USERNAME=root
      • MONGO_INITDB_ROOT_PASSWORD: root

      二者不可通用

      两个都是 YAML 的语法,这里不多赘述

    2. 配置一个环境变量的文件

      主流还是搭配一个 .env 文件,如 mongo.env 的内容为:

      MONGO_INITDB_ROOT_PASSWORD=root
      MONGO_INITDB_ROOT_USERNAME=root
      
      • 1
      • 2

    depends_on

    这是在有依赖关系的时候使用,如后端项目依赖于 mongodb 实现,那么后端的 depends_on 就是 mongodb

    这个会和优先级/排序有关系,可以被依赖的容器存在,但是无法完全保证被依赖的项目一定会初始完毕。要保证被依赖的容器已经成功初始化,可以被连接,还需要使用其他的工具辅助

    container_name

    容器最终会使用的名称,可选

    项目比较小/简单的时候用不用都可以,当然,用了更具有指向性

    stdin_open & tty

    就是 -it,进入 interact mode 和 teletypewriter

  • 相关阅读:
    yaml-cpp开源库使用
    嵌入式学习 - 用电控制电
    深度学习 神经网络
    ceph(分布式存储)
    Python爬虫讲解(超详细)
    中科大计网学习记录笔记(十二):TCP 套接字编程
    vant weapp的custom-tab-bar显示红点
    Qt-OpenCV学习笔记--人脸识别
    【Java】 java | 正则 | 正则表达式 | 强密码
    tomcat跨域问题CORS踩坑点
  • 原文地址:https://blog.csdn.net/weixin_42938619/article/details/138144654