Docker compose管理
Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。允许使用 YAML 文件来配置应用程序的服务,然后使用单个命令部署和启动所有服务。
YAML 配置文件:
Docker Compose 使用 YAML 文件来定义应用程序的服务。YAML 文件包含服务名称、镜像、端口映射、数据卷等配置信息。
例如,一个包含 Web 服务和数据库服务的应用程序的 YAML 文件可能如下所示:
1
2
3
4
5
6
7
8
9
10version: '3'
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
redis:
image: redis
环境变量和配置管理:
- Docker Compose 支持通过环境变量来管理配置信息,如数据库连接字符串、API 密钥等。
- 可以在 YAML 文件中使用
${VARIABLE}语法引用环境变量。 - 这使得在不同的环境(如开发、测试、生产)中部署应用程序时,可以轻松地修改配置信息。
网络和依赖管理:
- Docker Compose 会自动创建一个虚拟网络,并将应用程序的所有服务连接到该网络上。
- 服务之间可以通过服务名称进行相互通信,无需知道具体的 IP 地址。
- 您还可以定义服务依赖关系,确保在启动某个服务之前,其依赖的其他服务已经启动。
扩展和缩容:
- Docker Compose 支持轻松扩展和缩减应用程序的规模。
- 您可以使用
docker-compose scale命令来增加或减少某个服务的容器数量。
命令行工具:
- Docker Compose 提供了一个命令行工具
docker-compose。使用该工具可以快速启动、停止和管理应用程序的服务。
| 命令 | 说明 | 示例 |
|---|---|---|
docker-compose up |
启动应用程序的所有服务 | docker-compose up -d (以后台模式启动) |
docker-compose down |
停止并删除应用程序的所有服务 | docker-compose down |
docker-compose start |
启动已停止的服务 | docker-compose start web db (启动 web 和 db 服务) |
docker-compose stop |
停止正在运行的服务 | docker-compose stop web (停止 web 服务) |
docker-compose ps |
列出应用程序中正在运行的容器 | docker-compose ps |
docker-compose build |
构建或重新构建服务的镜像 | docker-compose build --no-cache web (不使用缓存构建 web 服务) |
docker-compose logs |
查看服务的日志输出 | docker-compose logs -f web (实时查看 web 服务的日志) |
docker-compose exec |
在运行的容器中执行命令 | docker-compose exec web bash (在 web 容器中执行 bash 命令) |
docker-compose scale |
扩展或缩减服务的容器数量 | docker-compose scale web=3 db=2 (将 web 服务扩展到 3 个容器, db 服务扩展到 2 个容器) |
docker-compose.yml文件编写
版本声明:
- 每个 YAML 文件都需要以
version关键字开头,指定所使用的 Docker Compose 版本号。常见的版本号有'2'、'3'和'3.x'。
- 每个 YAML 文件都需要以
services 部分:
services是 YAML 文件的核心部分,用于定义应用程序的各个服务。- 每个服务都有一个唯一的名称,并包含以下常见的配置项:
image: 指定运行该服务的 Docker 镜像名称。build: 如果没有现成的镜像,可以指定构建该服务的 Dockerfile 路径。ports: 定义服务对外暴露的端口映射,格式为"host_port:container_port"。environment: 设置服务运行时的环境变量。volumes: 定义数据卷,用于持久化服务产生的数据。depends_on: 指定该服务依赖的其他服务,确保先启动依赖服务。networks: 将服务连接到指定的网络。
volumes 和 networks 部分:
volumes部分用于定义数据卷,可以被多个服务共享使用。networks部分用于定义虚拟网络,服务之间通过网络名称进行通信。
示例配置文件:
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
27version: '3'
services:
web:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html
networks:
- frontend
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: password
volumes:
- db-data:/var/lib/mysql
networks:
- backend
volumes:
db-data:
networks:
frontend:
backend:- 该配置文件定义了一个 Web 服务和一个 MySQL 数据库服务,并为它们创建了前端和后端两个网络。
编写 Docker Compose YAML 配置文件时,需要注意服务之间的依赖关系、数据卷和网络的定义,以确保应用程序能够正确部署和运行。
Dockerfile编写
Dockerfile中的主要命令:
用于指定基础镜像,必须为Dockerfile的第一条指令。
1 | |
上例中,基础镜像为node:14-alpine。
用于在镜像中执行指定的命令。
1 | |
上例中,先使用apk包管理器安装tzdata时区数据包,将上海时区复制为本地时区,并写入时区配置文件。
用于将文件或目录从构建环境复制到镜像中。
1 | |
上例中,将当前目录下的所有文件复制到镜像的/app目录下。
类似于COPY,但ADD还支持从URL获取资源和自动解压缩等功能。
1 | |
上例从URL下载app.tgz包并解压到/app目录下。
用于设置容器启动时执行的默认命令。
Dockerfile中只能有一条CMD指令。如果列出多个CMD,则只有最后一个CMD才会生效。
1 | |
上例中,容器启动时执行node app.js命令。
也用于设置容器入口,但其优先级比CMD高。
CMD指令指定的容器启动时命令可以被docker run指定的命令覆盖,ENTRYPOINT指令指定的命令不能被覆盖。
CMD与ENTRYPOINT同时存在时,CMD指令可以为ENTRYPOINT指令设置默认参数。
1 | |
上例中,node为入口命令,app.js为默认参数。
用于设置环境变量。
1 | |
上例设置NODE_ENV环境变量为production。
用于设置工作目录,类似于bash的cd命令。
1 | |
上例设置工作目录为/app。
用于告诉Docker容器将要监听的端口。
1 | |
上例将暴露容器的8080端口。
用于创建挂载点,绕过联合文件系统,用于持久化存储。
1 | |
上例在/data创建一个挂载点。
用于指定运行容器的用户。
1 | |
设置用户为www用户。
用于指定构建镜像时的变量值。
1 | |
设置VERSION变量默认为1.0。
1 | |
也可以将ARG变量的值赋给ENV环境变量。
用于为镜像添加元数据标签。
1 | |
用于设置执行命令使用的shell。
1 | |
上例设置使用bash执行命令,并使用-c选项允许从字符串读取命令。
示例Dockerfile:
1 | |
构建镜像:
在包含Dockerfile的目录中运行以下命令构建镜像:
1 | |
运行容器:
使用构建的镜像启动容器:
1 | |
Dockerfile与docker-compose配合使用
Dockerfile 和 docker-compose.yml 可以很好地协同工作,实现自动化构建和编排容器化应用。
- 编写 Dockerfile
首先,根据应用需求编写 Dockerfile,定义如何构建应用镜像。例如:
1 | |
这个 Dockerfile 基于 node:14 镜像,安装 npm 依赖,复制应用代码,并配置启动命令。
然后,在项目目录下创建 docker-compose.yml 文件,定义需要的服务、网络和数据卷等。
1 | |
上面的配置,定义了一个名为 app 的服务,使用当前目录下的 Dockerfile 构建镜像,映射端口 3000,挂载本地代码目录作为数据卷,并设置环境变量 NODE_ENV。
编写完成后,就可以使用 docker-compose 命令自动构建镜像并启动容器了:
1 | |
–build 参数保证 Compose 总是使用最新的 Dockerfile 构建镜像。
这条命令会:
- 自动构建 Dockerfile 定义的镜像
- 根据 docker-compose.yml 的配置创建容器
- 启动容器
- 映射端口等
这样 docker-compose up -d就会同时启动 web 和 db 服务了。