Docker
1. Docker 简介
Docker是一种开源平台,用于开发、交付和运行应用程序。它使用容器化技术,允许开发者将应用程序及其依赖项打包到一个称为容器的独立单元中。这个容器包括应用程序的代码、运行时、系统工具、系统库以及配置。
以下是Docker的一些关键概念和特性:
-
容器化技术: Docker使用容器技术,通过在操作系统级别虚拟化来隔离应用程序。每个容器都是一个独立的运行环境,具有自己的文件系统、进程空间和网络接口,但共享主机操作系统的内核。这使得容器轻量、快速启动,并且具有一致的运行环境。
-
镜像: Docker镜像是一个只读的模板,包含运行应用程序所需的所有信息,包括代码、运行时、库、环境变量和配置。镜像是容器的基础,可以用来创建多个相同配置的容器实例。
-
容器: 容器是Docker运行的实体,它是从镜像创建的运行时实例。容器包含了应用程序的所有组件,以及在运行时所需的文件系统和系统工具。容器可以在任何支持Docker的环境中运行,而不受主机环境的影响。
-
Dockerfile: Dockerfile是一个文本文件,包含用于构建Docker镜像的一系列指令。这些指令描述了如何从基础镜像构建应用程序镜像,包括添加依赖项、设置环境变量、运行命令等。
-
Docker Hub: Docker Hub是一个集中的镜像注册中心,开发者可以在其中分享和获取Docker镜像。它是一个社区驱动的平台,提供了大量的公共镜像供开发者使用。
-
跨平台性: Docker提供了跨平台的支持,可以在Linux、Windows和macOS等多种操作系统上运行。这使得开发者可以在不同环境中保持一致的开发、测试和部署流程。
-
容器编排: Docker还提供了容器编排工具,如Docker Compose和Docker Swarm,用于管理和协调多个容器的部署、伸缩和运维。
使用Docker,开发者可以更容易地构建、测试和部署应用程序,同时提高了应用程序的可移植性和可扩展性。
2. Docker 和 VM 区别
Docker和虚拟机(VM)是两种不同的虚拟化技术,它们在隔离应用程序和提供虚拟化环境方面有一些关键的区别。
Docker | VM | |
---|---|---|
隔离级别 | 使用操作系统级别的虚拟化,容器在主机操作系统上共享同一个内核,但具有独立的用户空间。这使得容器更轻量,更快速启动,并且占用更少的资源 | 使用硬件级别的虚拟化,每个虚拟机都有自己的完整操作系统和内核。这使得虚拟机更隔离,但也更重量级,占用更多资源 |
资源占用 | 共享主机操作系统的内核,因此更轻量。容器启动快速,并且占用的资源相对较少 | 每个虚拟机都需要独立的操作系统和内核,因此相对较重。虚拟机启动慢,占用的资源相对更多 |
性能 | 由于共享内核,容器通常具有更高的性能,更低的开销,并且更适合大规模部署 | 虚拟机的性能开销较大,启动速度相对较慢,但提供了更高的隔离级别 |
部署速度 | 由于轻量级的特性,容器的部署速度非常快 | 虚拟机的部署速度相对较慢,因为需要启动完整的操作系统 |
可移植性 | 由于容器包含应用程序及其依赖项,因此更具有可移植性,可以在不同的环境中运行 | 虚拟机的可移植性相对较低,因为虚拟机通常与特定的虚拟化平台相关 |
使用场景 | 适用于轻量级、快速部署和大规模的微服务架构 | 适用于需要更高隔离性、运行不同操作系统的应用程序以及对安全性要求较高的场景 |
3. Docker 架构
Docker采用了一种客户端-服务器架构,主要包括以下几个组件:
- Docker客户端(Docker Client):
- Docker客户端是用户与Docker交互的主要方式。用户通过命令行界面(CLI)或Docker API与Docker客户端进行通信,以执行各种Docker操作,如构建、运行和管理容器。
- Docker守护进程(Docker Daemon):
- Docker守护进程是在主机上运行的后台进程,负责管理Docker对象,如镜像、容器、网络和数据卷。它接收来自Docker客户端的请求,并通过Docker API与其他Docker守护进程通信。Docker守护进程还负责构建、运行和监视容器。
- Docker镜像(Docker Images):
- Docker图像是一个轻量级、独立、可执行的软件包,包括运行应用程序所需的所有内容,如代码、运行时、库、环境变量和配置。Docker镜像是容器的基础。用户可以通过Dockerfile定义一个Docker镜像,并使用Docker客户端构建和管理这些镜像。
- Docker容器(Docker Containers):
- Docker容器是Docker镜像的实例,是运行应用程序的独立单元。容器包含了应用程序的代码、运行时、系统工具、系统库以及配置。多个容器可以在同一主机上并行运行,互相隔离,但又共享主机操作系统的内核。
- Docker注册中心(Docker Registry):
- Docker注册中心是用于存储和分享Docker镜像的服务。Docker Hub是Docker官方提供的公共注册中心,用户可以在其中找到和分享Docker图像。此外,用户也可以搭建私有的注册中心,以在内部网络中管理和分享自己的Docker镜像。
- Docker Compose:
- Docker Compose是一个工具,允许用户定义和运行由多个容器组成的应用程序。通过一个简单的YAML文件,用户可以定义应用程序的服务、网络和卷等配置,然后使用
docker-compose
命令启动整个应用程序。
这些组件共同构成了Docker的体系结构,使得开发者能够方便地构建、打包、分发和运行应用程序,同时提供了高度的可移植性和可伸缩性。Docker的架构设计使得容器技术变得更加灵活和易于使用。
4. Docker 安装
-
卸载旧版本
sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine
-
设置 yum 仓库
sudo yum install -y yum-utils sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
-
安装 Docker Engine、containerd 和 Docker Compose
sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
-
docker-ce
Docker Community Edition 是Docker的免费版本,包含Docker引擎、Docker CLI(命令行工具)和Docker Compose等。这是适用于个人、小型团队和开源项目的版本,用于构建、打包和运行容器化应用程序
-
docker-ce-cli
Docker CLI(命令行工具)是与Docker引擎进行交互的命令行界面。
docker-ce-cli
包含了Docker CLI工具,它允许用户使用命令行指令执行与Docker引擎相关的操作,如构建镜像、运行容器、管理网络等 -
containerd.io
Containerd是一个轻量级的容器运行时,由Docker维护。它提供了容器的基本功能,如容器的生命周期管理、镜像传输和存储、容器网络等。
containerd.io
是Docker引擎使用的底层容器运行时,与Docker CLI结合使用来创建和管理容器 -
docker-buildx-plugin
Docker Buildx 是一个用于增强Docker构建功能的插件。它允许用户使用多个不同的构建后端,包括本地构建、Docker CLI构建、BuildKit和QEMU等。Buildx 提供了一种灵活的方式来构建多平台和多架构的容器镜像,支持通过构建时设置多个目标平台
-
-
启动 Docker
sudo systemctl start docker
-
通过运行镜像来验证 Docker 引擎安装是否成功
sudo docker run hello-world
-
卸载
sudo yum remove docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras sudo rm -rf /var/lib/docker sudo rm -rf /var/lib/containerd
-
配置镜像加速器(阿里云镜像加速器 https://z69zdf14.mirror.aliyuncs.com)
sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://z69zdf14.mirror.aliyuncs.com"] } EOF sudo systemctl daemon-reload sudo systemctl restart docker
-
给普通用户分配 docker 执行权限
因为 docker 只能 root 用户执行,但是如果将普通用户加入 docker 组,普通用户也就有了 docker 权限
sudo usermod -aG docker your_username
5. 镜像操作
5.1 docker images
docker images
命令用于列出本地系统上的 Docker 镜像。以下是该命令的详细解释:
docker images [OPTIONS] [REPOSITORY[:TAG]]
参数:
- -a, --all: 显示所有镜像,包括中间层镜像。
- –digests: 显示镜像的摘要信息。
- –format: 使用 Go 模板格式化输出。
- –no-trunc: 不截断镜像名。
- -q, --quiet: 只显示镜像ID。
示例:
-
列出所有本地镜像:
docker images
-
只显示镜像ID:
docker images -q
-
显示详细信息,包括摘要:
docker images --digests
-
使用 Go 模板格式化输出:
docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}"
输出列说明:
- REPOSITORY: 镜像的仓库名。
- TAG: 镜像的标签。
- IMAGE ID: 镜像的唯一标识符。
- CREATED: 镜像的创建时间。
- SIZE: 镜像占用的磁盘空间大小。
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 20.04 94e814e2efa8 2 weeks ago 72.9MB
nginx latest ae513a47849b 3 weeks ago 133MB
alpine 3.14 6dbb9cc54074 3 weeks ago 5.61MB
5.2 docker search
docker search
命令用于在Docker Hub或其他Docker镜像仓库中搜索镜像。以下是该命令的详细解释:
docker search [OPTIONS] TERM
示例:
-
在Docker Hub中搜索 Ubuntu 相关镜像:
docker search ubuntu
-
搜索 Nginx 相关镜像:
docker search nginx
常用选项:
- –filter , -f: 使用过滤器来限制搜索结果。
- –format: 使用Go模板格式化输出。
示例输出:
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
ubuntu Ubuntu is a Debian-based... 12243 [OK]
nginx Official build of Nginx.... 8322 [OK]
解释说明:
- NAME: 镜像的名称或仓库名。
- DESCRIPTION: 镜像的描述信息。
- STARS: 镜像的星标数量,表示该镜像的受欢迎程度。
- OFFICIAL: 是否为官方镜像。
- AUTOMATED: 是否为自动构建的镜像。
使用场景:
# 搜索与 Ubuntu 相关的镜像
docker search ubuntu
# 搜索 Nginx 相关的镜像
docker search nginx
5.3 docker pull
docker pull
命令用于从Docker镜像仓库拉取或下载一个指定的镜像。以下是该命令的详细解释:
docker pull [OPTIONS] NAME[:TAG|@DIGEST]
示例:
-
拉取指定版本的镜像:
docker pull ubuntu:20.04
-
拉取最新版本的镜像:
docker pull nginx
常用选项:
- -a, --all-tags: 拉取仓库中的所有标签。
- –disable-content-trust: 忽略图像签名(默认启用)。
- –platform: 设置要拉取的镜像的平台。
示例输出:
20.04: Pulling from library/ubuntu
5c939e3a4d10: Pull complete
9a9e7b415e46: Pull complete
cf0a714eda7c: Pull complete
Digest: sha256:5d1d9cf8b117f813d0e6b1c7415c9f71c92e2593082c7c4d132a908d4f83ce50
Status: Downloaded newer image for ubuntu:20.04
解释说明:
- NAME: 镜像的名称或仓库名。
- TAG: 镜像的标签(版本)。如果未指定标签,则默认为
latest
。 - DIGEST: 镜像的摘要。
注意事项:
- 如果未提供具体的镜像标签,Docker将默认拉取
latest
标签的镜像。 - 使用
--platform
选项可以指定拉取的镜像平台,例如linux/amd64
。
示例使用场景:
# 拉取 Ubuntu 20.04 镜像
docker pull ubuntu:20.04
# 拉取 Nginx 最新版本的镜像
docker pull nginx
5.4 docker rmi
docker rmi
命令用于删除本地系统上的一个或多个Docker镜像。以下是该命令的详细解释:
docker rmi [OPTIONS] IMAGE [IMAGE...]
示例:
-
删除一个本地镜像:
docker rmi ubuntu:20.04
-
删除多个本地镜像:
docker rmi ubuntu:20.04 nginx
常用选项:
- -f, --force: 强制删除,即使有运行中的容器使用该镜像。
- –no-prune: 不移除无关镜像。
- –help: 显示帮助信息。
示例输出:
Untagged: ubuntu:20.04
Untagged: ubuntu@sha256:5d1d9cf8b117f813d0e6b1c7415c9f71c92e2593082c7c4d132a908d4f83ce50
Deleted: sha256:94e814e2efa8ea52c8e05a02c123e885da9baf9cd9e25c05ffb243c7ed8087f7
注意事项:
- 如果镜像被用于运行中的容器,必须使用
-f
强制选项来删除它。 - 删除镜像时,Docker将尝试删除与该镜像相关的所有不再使用的中间层镜像。
使用场景:
# 删除一个本地镜像
docker rmi ubuntu:20.04
# 删除多个本地镜像
docker rmi ubuntu:20.04 nginx
5.5 docker inspect
docker inspect
命令用于获取有关Docker对象(如容器、镜像、网络等)的详细信息。以下是该命令的详细解释:
docker inspect [OPTIONS] NAME|ID [NAME|ID...]
示例:
-
查看一个容器的详细信息:
docker inspect my_container
-
查看一个镜像的详细信息:
docker inspect ubuntu:20.04
常用选项:
- -f, --format: 使用Go模板格式化输出。
- –type: 指定要检查的对象类型。
示例输出:
输出是一个包含有关Docker对象详细信息的JSON格式文本。
使用场景:
# 查看容器详细信息
docker inspect my_container
# 查看镜像详细信息
docker inspect ubuntu:20.04
docker inspect
提供了关于Docker对象的深入信息,包括配置、状态、网络设置、挂载点等。可以使用该命令来获取更详细的信息,以便进一步分析和了解Docker对象的状态和配置。在使用 --format
选项时,你还可以使用Go模板来格式化输出,以满足特定的信息需求。
5.6 Docker tag
docker tag
命令用于为本地的 Docker 镜像打标签,为其指定一个新的仓库名称(Repository)和/或标签(Tag)。这对于给镜像取别名或将其推送到不同的镜像仓库非常有用。以下是该命令的详细解释:
docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
示例:
-
为镜像打标签:
docker tag my_image:latest my_repository/my_image:1.0
-
为镜像打标签并指定远程仓库:
docker tag my_image:latest my_registry/my_repository/my_image:1.0
使用场景:
- 在为镜像打标签时,你可以指定新的仓库名称和/或标签,从而为镜像创建一个新的标识。
- 通过给镜像打标签,你可以方便地将镜像推送到不同的远程仓库,或者创建不同版本的同一镜像。
示例输出:
该命令没有明确的输出,只是为指定的镜像创建了一个新的标签。
注意事项:
- 如果只指定了新的标签,而没有指定新的仓库名称,Docker 将默认为新标签使用相同的仓库名称。
- 标签通常用于版本控制,例如将
my_image:latest
标签更新为my_image:1.0
。
示例使用场景:
# 为镜像打标签
docker tag my_image:latest my_repository/my_image:1.0
# 为镜像打标签并指定远程仓库
docker tag my_image:latest my_registry/my_repository/my_image:1.0
docker tag
允许你轻松创建别名、版本标签或将镜像标记为将来的推送目标。在构建和管理Docker镜像时,使用 docker tag
是一种很常见的做法。
5.7 docker push
docker push
命令用于将本地的 Docker 镜像推送到远程镜像仓库,使得该镜像在仓库中可用。以下是该命令的详细解释:
docker push [OPTIONS] NAME[:TAG]
示例:
- 推送本地镜像到 Docker Hub:
docker push my_repository/my_image:1.0
常用选项:
- –disable-content-trust: 禁用图像签名(默认启用)。
- –quiet, -q: 显示推送过程中的镜像摘要。
使用场景:
- 当你在本地构建了一个镜像后,使用
docker push
将该镜像上传到远程仓库,以便其他人或系统可以访问和使用该镜像。
示例输出:
推送过程中,你会看到一系列与推送相关的日志信息,包括镜像的分层上传情况、推送进度等。
注意事项:
- 在推送之前,确保你已经登录到目标镜像仓库,可以使用
docker login
命令进行登录。 - 推送镜像可能需要一些时间,具体时间取决于网络状况和镜像大小。
示例使用场景:
# 推送本地镜像到 Docker Hub
docker push my_repository/my_image:1.0
docker push
是将本地构建的 Docker 镜像上传到远程仓库的关键步骤。通过推送,你可以将镜像分享给其他开发者、团队成员或者部署到生产环境。
6. 容器操作
6.1 docker create
docker create
命令用于创建一个新的容器,但不启动该容器。以下是该命令的详细解释:
docker create [OPTIONS] IMAGE [COMMAND] [ARG...]
示例:
- 创建一个新容器但不启动:
docker create -it --name my_container ubuntu:20.04 /bin/bash
常用选项:
- –add-host=[]: 将额外的主机名映射到IP地址。
- –attach=[],-a=[]: 连接到容器的标准输入、输出和错误输出。
- –blkio-weight: 设置块IO(block I/O)的权重。
- –blkio-weight-device=[]: 设置特定设备的块IO权重。
- –cap-add=[]: 启用容器内的额外功能。
- –cap-drop=[]: 禁用容器内的某些功能。
- –cgroup-parent: 为容器指定父cgroup。
- –cidfile: 将容器ID写入文件。
- –cpu-period: 设置CPU周期。
- –cpu-quota: 限制CPU配额。
- –cpu-rt-period: 设置实时CPU周期。
- –cpu-rt-runtime: 设置实时CPU运行时间。
- –cpuset-cpus: 设置CPU亲和性。
- –cpuset-mems: 设置内存亲和性。
- –detach,-d: 在后台运行容器。
- –device=[]: 添加主机设备到容器。
- –device-read-bps=[]: 限制设备的读速率。
- –device-read-iops=[]: 限制设备的读IOPS。
- –device-write-bps=[]: 限制设备的写速率。
- –device-write-iops=[]: 限制设备的写IOPS。
- –disable-content-trust: 忽略镜像签名。
- –dns=[]: 设置自定义DNS服务器。
- –dns-option=[]: 设置自定义DNS选项。
- –dns-search=[]: 设置自定义DNS搜索域。
- –domainname: 容器的域名。
- –entrypoint: 覆盖镜像的入口点。
- –env,-e=[]: 设置环境变量。
- –env-file=[]: 从文件中读取环境变量。
- –expose=[]: 暴露容器的端口到主机。
- –group-add=[]: 添加附加的组到容器。
- –help: 显示帮助信息。
- –hostname,-h: 容器的主机名。
- –init: 启用容器的初始化系统。
- –interactive,-i: 保持容器的标准输入打开,即使容器没有附加。
- –ipc: 设置容器的IPC模式。
- –ip: 容器的IPv4地址。
- –ip6: 容器的IPv6地址。
- –ipc: 设置容器的IPC模式。
- –isolation: 容器的隔离技术。
- –kernel-memory: 设置内核内存限制。
- –label=[]: 设置容器的元数据标签。
- –label-file=[]: 从文件中读取容器的元数据标签。
- –link=[]: 添加链接到另一个容器。
- –log-driver: 容器的日志驱动。
- –log-opt=[]: 容器的日志驱动选项。
- –mac-address: 容器的MAC地址。
- –memory,-m: 设置容器的内存限制。
- –memory-reservation: 设置容器的内存保留。
- –memory-swap: 设置容器的交换空间限制。
- –memory-swappiness: 容器的内存换页参数。
- –name: 为容器指定一个名称。
- –network,-net: 设置容器的网络模式。
- –network-alias=[]: 为容器添加网络别名。
- –no-healthcheck: 禁用容器的健康检查。
- –oom-kill-disable: 禁用内存超限时的OOM Killer。
- –oom-score-adj: 设置容器的OOM分数调整。
- –pid: 设置容器的PID模式。
- –pids-limit: 设置容器的PID限制。
- –publish,-p=[]: 将容器的端口映射到主机。
使用场景:
- 当你想要先创建容器,但暂时不需要运行它时,可以使用
docker create
命令。
注意事项:
- 创建容器后,你需要使用
docker start
命令来启动它。
示例使用场景:
# 创建一个新容器但不启动
docker create -it --name my_container ubuntu:20.04 /bin/bash
这个命令创建一个名为 my_container
的新容器,使用了交互式(-i
)和终端(-t
)选项,并指定了容器的名称和启动时要运行的命令 /bin/bash
。容器创建后,你可以通过 docker start
启动它。
6.2 docker ps
docker ps
命令用于列出当前正在运行的容器。以下是该命令的详细解释:
docker ps [OPTIONS]
示例:
- 列出当前正在运行的容器:
docker ps
常用选项:
- -a, --all: 列出所有容器,包括正在运行的和已经停止的。
- -q, --quiet: 以静默模式显示容器ID。
示例输出:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
123456789abc nginx "nginx -g 'daemon of…" 2 minutes ago Up 2 minutes 80/tcp my_container
输出列说明:
- CONTAINER ID: 容器的唯一标识符。
- IMAGE: 创建容器时使用的镜像。
- COMMAND: 容器启动时执行的命令。
- CREATED: 容器的创建时间。
- STATUS: 容器的运行状态。
- PORTS: 容器端口映射情况。
- NAMES: 容器的名称。
使用场景:
# 列出当前正在运行的容器
docker ps
# 列出所有容器,包括正在运行的和已经停止的
docker ps -a
docker ps
命令是一个方便的工具,用于查看当前正在运行的容器以及一些基本信息,如容器的ID、镜像、状态等。通过加上不同的选项,你可以获取更详细的容器信息。
6.3 docker start
docker start
命令用于启动已经停止的容器。以下是该命令的详细解释:
docker start [OPTIONS] CONTAINER [CONTAINER...]
示例:
- 启动已经停止的容器:
docker start my_container
常用选项:
- -a, --attach: 连接到容器的标准输入、输出和错误输出。
- –detach , -d: 在后台运行容器。
使用场景:
- 当你停止了一个容器,并希望重新启动该容器时,可以使用
docker start
命令。
示例输出:
docker start
命令通常没有明显的输出。如果你使用了 -a
选项,它会连接到容器的标准输入、输出和错误输出,你会看到容器的输出。
注意事项:
- 启动容器时,容器必须已经创建过。如果容器是通过
docker run
命令创建并启动的,那么docker start
就不再需要。
示例使用场景:
# 启动已经停止的容器
docker start my_container
6.4 docker stop
docker stop
命令用于停止正在运行的容器。以下是该命令的详细解释:
docker stop [OPTIONS] CONTAINER [CONTAINER...]
示例:
- 停止一个运行中的容器:
docker stop my_container
常用选项:
- -t, --time: 设置停止容器前的超时时间(默认为10秒)。
使用场景:
- 当你希望停止一个正在运行的容器时,可以使用
docker stop
命令。
示例输出:
docker stop
命令通常没有明显的输出,除非指定了 -t
选项并且发生了超时。
注意事项:
- 停止容器并不会删除容器,只是将其停止运行。
示例使用场景:
# 停止一个运行中的容器
docker stop my_container
6.5 docker run
docker run
命令用于在新容器中运行一个命令。以下是该命令的详细解释:
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
示例:
-
以交互模式运行容器:
docker run -it ubuntu:20.04 /bin/bash
这个命令会以交互模式运行
ubuntu:20.04
镜像,并在容器中执行/bin/bash
命令。 -
以后台模式运行容器:
docker run -d nginx
这个命令以后台模式运行
nginx
镜像,不附加到容器终端。
常用选项:
- -i, --interactive: 保持容器的标准输入打开,使其保持交互模式。
- -t, --tty: 分配一个伪终端,通常与
-i
一起使用,以使容器保持交互模式。 - –name: 为容器指定一个名称。
- -d, --detach: 在后台运行容器,不附加到容器的终端。
- –rm: 容器停止运行后立即删除容器。
- -p, --publish=[]: 将容器端口映射到主机端口。
- –volume, -v=[]: 将主机文件系统的路径挂载到容器中。
使用场景:
- 当你希望在新的容器中运行一个命令或应用程序时,可以使用
docker run
命令。
示例输出:
# 以交互模式运行 ubuntu:20.04 镜像,并执行 /bin/bash 命令
$ docker run -it ubuntu:20.04 /bin/bash
root@container_id:/#
# 以后台模式运行 nginx 镜像
$ docker run -d nginx
注意事项:
- 如果没有指定命令,
docker run
将执行镜像中的默认启动命令(在 Dockerfile 中定义)。 - 容器在退出后,如果使用了
--rm
选项,将被立即删除。
docker run
是一个强大的命令,允许你创建和运行容器。通过不同的选项,你可以控制容器的各种方面,如交互模式、后台模式、端口映射等。
6.6 docker exec
docker exec
命令用于在正在运行的容器中执行命令。以下是该命令的详细解释:
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
示例:
-
在运行中的容器中执行命令:
docker exec -it my_container /bin/bash
这个命令会在
my_container
容器中以交互模式执行/bin/bash
命令。 -
在后台模式下执行命令:
docker exec -d my_container ls /app
这个命令在
my_container
容器中以后台模式执行ls /app
命令。
常用选项:
- -i, --interactive: 保持容器的标准输入打开,使其保持交互模式。
- -t, --tty: 分配一个伪终端,通常与
-i
一起使用,以使容器保持交互模式。 - –user: 指定要执行命令的用户名或 UID。
- –workdir,-w: 指定命令执行的工作目录。
- –detach,-d: 在后台运行命令,不附加到容器的终端。
使用场景:
- 当你需要在运行中的容器中执行特定命令时,可以使用
docker exec
命令。
示例输出:
# 在 my_container 容器中以交互模式执行 /bin/bash 命令
$ docker exec -it my_container /bin/bash
root@container_id:/#
# 在 my_container 容器中以后台模式执行 ls /app 命令
$ docker exec -d my_container ls /app
注意事项:
- 使用
docker exec
命令时,容器必须是运行状态。 - 如果你需要在容器内执行多个命令,可以使用分号将它们连接在一起,或者通过在容器中启动一个 shell 来执行多个命令。
docker exec
允许你在运行中的容器中执行额外的命令,这对于调试、查看容器内部状态或运行其他操作是非常有用的。
6.7 docker logs
docker logs
命令用于查看容器的日志输出。以下是该命令的详细解释:
docker logs [OPTIONS] CONTAINER
示例:
- 查看容器的日志输出:
docker logs my_container
常用选项:
- –details: 显示更多的日志详情,如时间戳和标签。
- –follow, -f: 实时跟踪日志输出。
- –since: 显示自指定时间以来的日志。
- –tail: 仅显示最后几行日志。
- –timestamps, -t: 显示时间戳。
使用场景:
- 当你希望查看容器的标准输出或标准错误输出时,可以使用
docker logs
命令。
示例输出:
# 查看 my_container 容器的日志输出
$ docker logs my_container
This is the log output of my_container.
...
# 实时跟踪 my_container 容器的日志输出
$ docker logs -f my_container
注意事项:
docker logs
默认显示容器的标准输出,你可以使用其他选项来控制显示的内容。- 如果你希望在容器中运行的应用程序产生日志,确保应用程序将日志输出到标准输出或标准错误流。
docker logs
是一个用于查看容器日志的有用工具,可以帮助你了解容器的运行情况,排查问题以及监视应用程序的输出。
6.8 docker top
docker top
命令用于显示容器中正在运行的进程信息。以下是该命令的详细解释:
docker top CONTAINER [OPTIONS]
示例:
docker top my_container
常用选项:
- –format: 指定输出的格式。
使用场景:
- 当你需要查看容器内部运行的进程信息时,可以使用
docker top
命令。
示例输出:
UID PID PPID C STIME TTY TIME CMD
root 1234 5678 0.0 12:34 ? 00:00:00 /usr/bin/my_process
注意事项:
- 输出的列包括 UID(用户ID)、PID(进程ID)、PPID(父进程ID)、C(CPU利用率)、STIME(启动时间)、TTY(终端)、TIME(运行时间)和 CMD(命令)等。
docker top
命令提供了容器内运行进程的快速概览。你可以看到每个进程的一些基本信息,例如进程ID、父进程ID、CPU利用率、启动时间、运行时间以及执行的命令等。这对于监视容器内部的活动、排查问题或了解容器中正在运行的进程非常有用。
6.9 docker rm
docker rm
命令用于删除一个或多个已经停止的容器。以下是该命令的详细解释:
docker rm [OPTIONS] CONTAINER [CONTAINER...]
示例:
- 删除一个已经停止的容器:
docker rm my_container
常用选项:
- -f, --force: 强制删除正在运行的容器。
- -v, --volumes: 同时删除关联的数据卷。
使用场景:
- 当你希望删除一个已经停止的容器时,可以使用
docker rm
命令。
示例输出:
my_container
注意事项:
- 删除容器不会删除与容器关联的镜像。
- 如果容器正在运行,你需要使用
-f
选项来强制删除它。
示例使用场景:
# 删除一个已经停止的容器
docker rm my_container
docker rm
命令用于清理已经停止的容器。当你停止并删除容器时,可以使用这个命令来释放资源,并确保不再占用系统资源。如果你同时使用 -v
选项,还可以删除关联的数据卷。
7. 创建容器
7.1 使用 dockerfile 自定义创建
Docker 允许你通过创建 Dockerfile 文件并使用 docker build
命令来自定义构建镜像。以下是一般的步骤:
-
创建 Dockerfile: 在项目的根目录下创建一个名为 Dockerfile 的文件,其中包含构建镜像所需的指令。
示例 Dockerfile:
# 使用基础镜像 FROM ubuntu:20.04 # 设置工作目录 WORKDIR /app # 复制本地文件到容器中 COPY . . # 安装依赖 RUN apt-get update && \ apt-get install -y python3 && \ apt-get clean # 定义环境变量 ENV MY_VARIABLE=my_value # 定义容器启动时执行的命令 CMD ["python3", "app.py"]
以上是一个简单的 Python 应用的 Dockerfile。你可以根据实际需求定制你的 Dockerfile。
-
构建镜像: 在包含 Dockerfile 的目录中,运行以下命令构建镜像。
docker build -t my_custom_image .
这会根据 Dockerfile 中的指令构建一个名为
my_custom_image
的镜像。别忘了在命令的末尾加上.
,表示 Dockerfile 所在的当前目录。 -
运行容器: 构建完成后,你可以使用
docker run
命令来运行新构建的镜像。docker run -it my_custom_image
这样,你就可以通过 Dockerfile 自定义构建一个镜像。Dockerfile 中的指令用于定义镜像的构建过程,你可以在其中包含诸如基础镜像选择、安装软件包、设置环境变量、复制文件等操作。通过这种方式,你可以根据应用程序的要求创建定制的 Docker 镜像。
-
dockerfile 参数详解
Dockerfile 是一个包含一组指令的文本文件,用于自定义构建 Docker 镜像。通过 Dockerfile,你可以定义镜像的基础配置、环境设置、应用程序的依赖关系以及容器的启动命令。以下是 Dockerfile 的主要指令和用法的详细说明:
FROM
FROM image:tag
- 用于指定基础镜像。构建的新镜像将基于这个镜像。
image:tag
格式表示镜像名称和标签。例如,ubuntu:20.04
表示 Ubuntu 20.04 版本的官方镜像。
WORKDIR
WORKDIR /path/to/directory
- 设置工作目录,所有后续的指令都将在这个目录下执行。
- 可以使用相对路径或绝对路径。
COPY
和ADD
COPY <src> <dest>
ADD <src> <dest>
- 用于将文件或目录从构建上下文复制到镜像中。
COPY
用于简单复制,ADD
在复制的基础上提供了一些额外的功能(例如从 URL 复制、解压缩文件等)。
RUN
RUN command
- 在镜像构建过程中执行命令。
- 可以用于安装软件包、下载文件、运行脚本等。
ENV
ENV key=value
- 设置环境变量。这些变量在容器运行时可用。
- 可以一次设置多个环境变量。
EXPOSE
EXPOSE port
-
声明容器运行时将监听的端口。
-
仅是一个元数据,不会自动映射端口到主机,具体映射哪个端口由容器启动时指定
docker run -p 8081:8080 -d my-spring-boot-app
CMD
和ENTRYPOINT
CMD ["executable", "param1", "param2"]
ENTRYPOINT ["executable", "param1", "param2"]
容器的启动命令可以被覆盖。在 Docker 中,你可以使用
docker run
命令的CMD
参数来覆盖 Dockerfile 中指定的默认启动命令。例如,假设你有一个使用以下
CMD
指令的 Dockerfile:# Dockerfile FROM openjdk:11 COPY my-spring-boot-app.jar /app/ EXPOSE 8080 CMD ["java", "-jar", "/app/my-spring-boot-app.jar", "--spring.config.location=classpath:/,file:/app/application.properties"]
默认情况下,它会运行 Spring Boot 应用程序。
但是,如果你想在运行容器时使用不同的命令,可以通过
docker run
命令的CMD
参数进行覆盖。例如:docker run -p 8080:8080 -d my-spring-boot-app echo "Hello, Docker!"
在这个例子中,
echo "Hello, Docker!"
将覆盖 Dockerfile 中的默认命令。当容器启动时,它将执行这个新的命令而不是在 Dockerfile 中定义的默认命令。请注意,通过这种方式覆盖命令只是在容器启动时的一次性操作,对于持久性的更改,你可能需要修改 Dockerfile 中的
CMD
指令。VOLUME
VOLUME ["/data"]
VOLUME
指令在 Dockerfile 中用于创建一个挂载点,允许容器中的数据持久化保存,并且可以在容器和主机之间共享数据。具体来说,
VOLUME
指令主要有以下作用:-
持久化数据: 使用
VOLUME
可以在容器中创建一个挂载点,将容器中的特定目录挂载到主机文件系统上。这样,即使容器被删除,挂载点上的数据仍然可以保留在主机上。 -
数据共享: 通过挂载点,可以实现容器内外的数据共享。这对于需要在多个容器之间共享数据的场景非常有用,相当于共享路径,是同一个
-
备份和恢复: 通过将数据存储在挂载点上,可以方便地对容器中的数据进行备份和恢复。
示例:
以下是一个简单的 Dockerfile 示例,演示了如何使用
VOLUME
:FROM ubuntu:20.04 # 创建一个挂载点,指定容器内的 /data 目录将被挂载 VOLUME /data # 在挂载点上创建一个文件,用于演示挂载效果 RUN echo "Hello, Docker!" > /data/hello.txt
在这个例子中,
VOLUME /data
指定了一个挂载点,将容器内的/data
目录挂载到主机上。后续的RUN
指令在挂载点上创建了一个文件。构建并运行这个镜像:
docker build -t my-volume-example . docker run -v /host/path:/data my-volume-example
在运行容器时,使用
-v
参数可以将容器内的/data
挂载到主机上的/host/path
,这样容器内的数据就能在主机上持久化保存。在这个例子中,容器内的hello.txt
文件会在主机的/host/path
目录下创建。总的来说,
VOLUME
是 Docker 中一个重要的特性,使数据持久化和容器间数据共享变得更加灵活和方便。USER
USER user
- 设置在容器中运行命令时使用的用户名。
LABEL
LABEL key="value" key2="value2"
- 用于为镜像添加元数据标签。这些标签通常用于描述镜像的信息、版本、维护者等。
ARG
ARG variable=value
ARG
是 Dockerfile 中用于定义构建参数的指令。构建参数允许你在构建 Docker 镜像时传递参数,从而定制镜像的行为。这些参数可以在FROM
、RUN
、CMD
、LABEL
、MAINTAINER
、EXPOSE
、ENV
、ADD
、和COPY
等指令中使用。语法:
ARG <name>[=<default value>]
<name>
:构建参数的名称。<default value>
:构建参数的默认值。
示例:
# 设置一个构建参数 ARG version=latest # 使用构建参数在基础镜像中指定标签 FROM ubuntu:$version # 使用构建参数传递给 ENV 指令 ENV VERSION=$version # 使用构建参数在命令中指定标签 RUN echo "Building version $version"
在这个示例中,
ARG version=latest
定义了一个名为version
的构建参数,并给它一个默认值latest
。这个构建参数被用于设置基础镜像的标签、传递给ENV
指令,以及在RUN
指令中输出版本信息。使用场景:
-
版本控制: 允许在构建时指定应用程序或基础镜像的版本,使构建过程更加灵活。
-
定制化构建: 允许用户在构建时传递定制化的信息,例如构建脚本的路径、构建环境等。
-
避免硬编码: 可以避免硬编码在 Dockerfile 中的一些常量,使得 Dockerfile 更加通用和可配置。
使用示例:
docker build --build-arg version=1.2.3 -t my-image .
在构建过程中,通过
--build-arg
参数可以传递构建参数的值,覆盖默认值。在上述例子中,version
的值将被设置为1.2.3
。
7.2 maven 插件构建
Docker Maven 插件是一个 Maven 插件,用于简化使用 Maven 构建 Docker 镜像的过程。该插件使得将 Java 应用程序打包为 Docker 镜像变得更加容易。以下是使用 Docker Maven 插件构建 Docker 镜像的一般步骤:
-
添加 Docker Maven 插件到
pom.xml
:在 Maven 项目的
pom.xml
文件中,添加 Docker Maven 插件的配置。通常,你需要在plugins
部分添加如下配置:<build> <plugins> <plugin> <groupId>com.spotify</groupId> <artifactId>docker-maven-plugin</artifactId> <version>1.0.0</version> <!-- 根据需要更改版本 --> <configuration> <!-- 插件配置 --> </configuration> </plugin> </plugins> </build>
-
配置 Docker Maven 插件:
在
<configuration>
部分,你需要配置 Docker Maven 插件的参数,例如指定 Docker 镜像的名称、标签、Dockerfile 的位置等。以下是一个简单的例子:<build> <plugins> <plugin> <groupId>com.spotify</groupId> <artifactId>docker-maven-plugin</artifactId> <version>1.2.0</version> <configuration> <!-- 配置 Docker 镜像的名称和标签 --> <imageName>my-docker-app</imageName> <imageTag>${project.version}</imageTag> <!-- 配置 Dockerfile 文件的位置 --> <dockerDirectory>${project.basedir}/src/main/docker</dockerDirectory> <!-- 配置构建上下文 --> <contextDirectory>${project.basedir}</contextDirectory> <!-- 配置额外的构建参数,可以在 Dockerfile 中引用 --> <buildArgs> <JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE> <HTTP_PROXY>http://proxy.example.com:8080</HTTP_PROXY> </buildArgs> <!-- 配置 Docker 客户端版本 --> <apiVersion>1.22</apiVersion> <!-- 配置 Docker 主机 --> <host>tcp://192.168.99.100:2376</host> <!-- 配置推送到远程 Docker 仓库 --> <pushImage>false</pushImage> <!-- 配置 Docker 构建时的目标平台 --> <platform>linux/amd64</platform> <!-- 配置构建时的标签列表 --> <tags> <tag>latest</tag> <tag>${project.version}</tag> </tags> <!-- 配置附加的 Docker 构建参数 --> <additionalBuildArgs> -f src/main/docker/AnotherDockerfile </additionalBuildArgs> <!-- 配置 Docker 构建的超时时间 --> <timeout>300</timeout> <!-- 配置是否使用缓存 --> <useMavenSettingsForAuth>true</useMavenSettingsForAuth> </configuration> </plugin> </plugins> </build>
这个配置指定了 Docker 镜像的名称为
my-docker-image
,标签为latest
,Dockerfile 的位置为项目的根目录。 -
运行构建命令:
在项目根目录下运行 Maven 构建命令,触发 Docker Maven 插件执行构建:
mvn clean install docker:build
这将会编译你的项目,打包成一个 Docker 镜像,并将其上传到本地的 Docker 镜像仓库。
-
运行 Docker 容器:
使用以下命令运行刚刚构建的 Docker 镜像:
docker run -p 8080:8080 my-docker-image:latest
这里假设你的应用程序在容器内监听 8080 端口。
以上是一个基本的 Docker Maven 插件构建步骤的示例。具体的配置和操作可能因项目结构和需求而有所不同,你可以根据实际情况进行更详细的配置。
8. docker compose
Docker Compose 是一个用于定义和运行 Docker 容器应用的工具。通过一个简单的 YAML 文件,您可以定义应用程序的服务、网络和卷,并使用单个命令来启动整个应用程序。以下是 Docker Compose 的一些关键概念和使用方法:
Docker Compose 是一个用于定义和运行 Docker 容器应用的工具。通过一个简单的 YAML 文件,您可以定义应用程序的服务、网络和卷,并使用单个命令来启动整个应用程序。以下是 Docker Compose 的一些关键概念和使用方法:
8.1 Docker Compose 文件:
Docker Compose 使用一个名为 docker-compose.yml
的文件来定义应用程序的服务、网络和卷。该文件采用 YAML 格式,其中包含应用程序的配置信息。
一个简单的 docker-compose.yml
文件的例子:
version: '3'
services:
web:
image: nginx:latest
ports:
- "8080:80"
database:
image: mysql:latest
environment:
MYSQL_ROOT_PASSWORD: example
8.1.1 version
docker-compose.yml
文件中的 version
字段用于指定 Docker Compose 文件的版本。该版本号指示使用哪个版本的 Docker Compose 文件格式。不同的版本支持不同的功能和语法。
目前,Docker Compose 支持的版本主要有三个:version: '2'
、version: '3'
和 version: '3.8'
,具体版本号可能会有所变化,取决于 Docker Compose 的发布。
以下是每个版本的主要特点:
-
version: '2'
:- 支持服务扩展和网络定义。
- 不支持某些新功能,例如配置文件中的一些扩展选项。
version: '2' services: web: image: nginx:latest ports: - "8080:80"
-
version: '3'
:- 引入了新的网络模型,支持 overlay 网络和多主机部署。
- 引入了
deploy
部分,用于定义服务的部署配置。
version: '3' services: web: image: nginx:latest ports: - "8080:80"
-
version: '3.8'
(或其他具体版本号):- 进一步扩展了功能,包括配置文件的更多选项。
- 引入了一些新特性和改进。
version: '3.8' services: web: image: nginx:latest ports: - "8080:80"
8.1.2 services
在 docker-compose.yml
文件中,services
部分用于定义您应用程序中的不同服务。每个服务都是一个独立的容器,可以包括容器的镜像、启动命令、环境变量、卷、网络配置等。
以下是一个简单的 docker-compose.yml
文件,其中包含一个服务的定义:
version: '3'
services:
webapp:
image: nginx:latest
ports:
- "8080:80"
volumes:
- ./html:/usr/share/nginx/html
environment:
- DEBUG=true
在这个例子中:
version: '3'
指定了 Docker Compose 文件的版本。services
是一个字典,包含了您应用程序中的服务的定义。webapp
是服务的名称,您可以为其指定任何您喜欢的名称。image: nginx:latest
指定了使用的容器镜像,这里是最新的 Nginx 镜像。ports: - "8080:80"
定义了端口映射,将容器的 80 端口映射到主机的 8080 端口。volumes: - ./html:/usr/share/nginx/html
将主机上的./html
目录映射到容器内的/usr/share/nginx/html
目录,实现主机和容器之间的文件共享。environment: - DEBUG=true
设置了容器的环境变量。
8.1.3 networks
在 docker-compose.yml
文件中,networks
部分用于定义 Docker Compose 项目中的网络配置。您可以定义一个或多个网络,以便服务之间可以进行通信。
以下是一个包含 networks
部分的简单例子:
version: '3'
services:
webapp:
image: nginx:latest
networks:
- frontend
- backend
database:
image: mysql:latest
networks:
- backend
networks:
frontend:
driver: bridge
backend:
driver: bridge
在这个例子中:
version: '3'
指定了 Docker Compose 文件的版本。services
部分定义了两个服务:webapp
和database
。networks
部分定义了两个网络:frontend
和backend
。webapp
服务使用了两个网络:frontend
和backend
,而database
服务只使用了backend
网络。
在网络定义中,您可以配置一些选项,例如 driver
、driver_opts
、external
等。这些选项可以影响网络的行为。在上述例子中,driver: bridge
表示使用桥接网络。
问:定义两个网络是什么意思,具体会使用哪一个?
答:
在 Docker Compose 中定义两个网络意味着您为您的服务创建了两个独立的网络。每个网络可以用于实现特定的通信需求或隔离服务。
在上述示例中:
networks: frontend: driver: bridge backend: driver: bridge
有两个定义的网络:
frontend
和backend
。这两个网络可以在服务定义中使用。例如:services: webapp: image: nginx:latest networks: - frontend - backend database: image: mysql:latest networks: - backend
在这个例子中,
webapp
服务连接到了frontend
和backend
两个网络,而database
服务只连接到了backend
网络。使用多个网络的目的可能包括:
隔离服务: 将服务划分到不同的网络,以便实现隔离。这样,某个服务可能只能与其所属网络中的其他服务通信,而无法与其他网络中的服务通信。
实现不同的通信需求: 您可能希望将一些服务放在一个网络中,以便它们可以直接通信,而将其他服务放在另一个网络中,以便它们可以通过另一种方式通信。
容器连接到多个网络: 某些服务可能需要与多个网络连接,以便在不同的上下文中进行通信。这使得容器可以更灵活地进行配置,以满足不同的需求。
通常,您可以根据您的应用程序的需求来决定是否需要使用多个网络。在许多情况下,只使用一个默认的网络就足够了。如果需要更复杂的网络拓扑或隔离,那么使用多个网络可能是一种有效的策略。
8.1.4 volumes
在 Docker Compose 中,volumes
部分用于定义数据卷(volumes)。数据卷允许在 Docker 容器之间共享和持久化数据。
以下是一个包含 volumes
部分的简单例子:
version: '3'
services:
db:
image: mysql:latest
environment:
MYSQL_ROOT_PASSWORD: example
volumes:
- mysql-data:/var/lib/mysql
webapp:
image: nginx:latest
volumes:
- ./html:/usr/share/nginx/html
- logs:/var/log/nginx
volumes:
mysql-data:
logs:
在这个例子中:
version: '3'
指定了 Docker Compose 文件的版本。services
部分定义了两个服务:db
和webapp
。volumes
部分定义了两个数据卷:mysql-data
和logs
。db
服务使用了mysql-data
数据卷,将容器内的/var/lib/mysql
目录映射到了这个数据卷,用于存储 MySQL 数据。webapp
服务使用了两个数据卷:./html:/usr/share/nginx/html
(将主机上的./html
目录映射到容器内的/usr/share/nginx/html
目录)和logs:/var/log/nginx
(将数据卷logs
映射到容器内的/var/log/nginx
目录)。
通过使用数据卷,这两个服务可以在容器之间共享数据,并且这些数据将持久化,即使容器停止或删除,数据仍然保留在数据卷中。
使用数据卷的目的可能包括:
-
持久化存储: 将应用程序的数据存储到数据卷中,以确保数据在容器重新启动时不会丢失。
-
容器之间共享数据: 允许多个容器之间共享特定的目录或文件,使它们能够共同处理或访问相同的数据。
-
方便本地开发: 将本地开发环境的代码目录映射到容器内,以便容器可以实时反映本地代码的更改。
问:mysql-data logs 目录具体会是哪个?
答:
在上面的例子中,
mysql-data
和logs
是 Docker Compose 文件中定义的两个数据卷。这两个数据卷可以用于将容器内的路径映射到主机上的路径,从而在容器和主机之间共享数据。具体来说:
- 对于
mysql-data
,它是一个用于存储 MySQL 数据的数据卷。在db
服务中,它被用于将 MySQL 容器内的/var/lib/mysql
目录映射到主机上的数据卷。这意味着 MySQL 数据将存储在主机上,而不是容器内部。在主机上,您可以在 Docker Compose 文件所在的目录中找到mysql-data
数据卷,具体路径取决于您在哪个目录中运行docker-compose
命令。volumes: - mysql-data:/var/lib/mysql
- 对于
logs
,它是一个用于存储 Nginx 日志的数据卷。在webapp
服务中,它被用于将 Nginx 容器内的/var/log/nginx
目录映射到主机上的数据卷。这样,Nginx 日志将存储在主机上的logs
数据卷中。volumes: - logs:/var/log/nginx
总的来说,具体的路径取决于您在运行
docker-compose
命令时所在的目录。在这个例子中,这两个数据卷会在运行docker-compose
命令的目录中创建,您可以在那里找到对应的mysql-data
和logs
目录。
8.1.5 environment
设置服务容器的环境变量。
yamlCopy codeservices:
app:
image: myapp
environment:
- DEBUG=true
8.1.6 ports
定义服务容器的端口映射,将容器内部的端口映射到宿主机上。
yamlCopy codeservices:
web:
image: nginx:latest
ports:
- "8080:80"
8.1.7 depends_on
定义服务之间的依赖关系,确保某个服务在另一个服务启动之前启动。
yamlCopy codeservices:
app:
image: myapp
db:
image: mysql:latest
depends_on:
- app
8.1.8 build
在 Docker Compose 文件中,build
部分用于配置服务的构建过程。这意味着您可以使用 Docker Compose 来构建自定义的 Docker 镜像,而不是直接使用预构建的镜像。
以下是一个包含 build
部分的简单例子:
version: '3'
services:
app:
build:
context: .
dockerfile: Dockerfile
ports:
- "8080:80"
在这个例子中:
version: '3'
指定了 Docker Compose 文件的版本。services
部分定义了一个服务:app
。build
部分定义了构建过程的配置。context: .
指定构建上下文,即 Docker 构建上下文的路径。在这个例子中,构建上下文是当前目录,表示 Docker 将从当前目录开始查找构建上下文中的文件。dockerfile: Dockerfile
指定 Dockerfile 的路径。在这个例子中,Dockerfile 位于当前目录中。
通过这个配置,docker-compose up
命令将使用指定的 Dockerfile 从构建上下文中构建一个名为 app
的镜像,并将其用于 app
服务。构建的镜像将在服务启动之前构建。
构建的 Docker 镜像通常是在本地构建,但也可以通过配置为从远程构建上下文获取构建上下文的方式构建。有关更多构建配置选项的信息,您可以查看 Docker Compose 官方文档中的构建配置部分。
8.2 多环境支持
Docker Compose 支持多环境配置,您可以使用不同的 Docker Compose 文件来管理不同环境的配置。这使得您能够轻松切换开发、测试和生产环境的配置。
以下是一些管理多环境配置的一般方法:
不同的 Docker Compose 文件:
-
开发环境: 创建一个
docker-compose.yml
文件,包含适用于开发环境的配置。这可以包括映射本地开发目录、开启调试模式等。version: '3' services: web: image: nginx:latest volumes: - ./src:/usr/share/nginx/html ports: - "8080:80"
-
生产环境: 创建一个
docker-compose.prod.yml
文件,包含适用于生产环境的配置。这可以包括优化的构建步骤、更安全的设置等。version: '3' services: web: image: nginx:latest ports: - "80:80"
-
测试环境: 如果有必要,您还可以创建一个
docker-compose.test.yml
文件,包含适用于测试环境的配置。
使用不同文件运行 Docker Compose:
在运行 docker-compose
命令时,可以使用 -f
或 --file
选项来指定要使用的 Docker Compose 文件。例如:
# 使用默认的 docker-compose.yml 文件(开发环境)
docker-compose up
# 使用 docker-compose.prod.yml 文件(生产环境)
docker-compose -f docker-compose.prod.yml up
使用环境变量:
您还可以使用 COMPOSE_FILE
环境变量来指定要使用的 Docker Compose 文件。例如:
# 使用默认的 docker-compose.yml 文件(开发环境)
export COMPOSE_FILE=docker-compose.yml
docker-compose up
# 使用 docker-compose.prod.yml 文件(生产环境)
export COMPOSE_FILE=docker-compose.prod.yml
docker-compose up
针对不同环境设置变量:
在 Docker Compose 文件中,您还可以使用环境变量或其他变量来根据环境调整服务的配置。例如,您可以通过设置环境变量来决定使用哪个数据库服务器地址:
version: '3'
services:
app:
image: myapp
environment:
- DATABASE_URL=${DB_HOST}:${DB_PORT}/mydb
这样,您可以在不同环境中设置 DB_HOST
和 DB_PORT
的不同值。
综上所述,通过组织不同的 Docker Compose 文件,并使用相关的选项或环境变量,您可以很容易地支持多环境配置,确保适当的配置用于不同的部署和开发场景。
8.3 命令行工具
Docker Compose 提供了一组命令行工具,用于构建、启动、停止和管理整个应用程序。例如:
docker-compose up
: 启动应用程序。docker-compose down
: 停止并移除应用程序的容器、网络和卷。docker-compose ps
: 显示应用程序中的容器状态。docker-compose exec
: 在正在运行的服务容器中执行命令。
8.4 扩展和覆盖
在 Docker Compose 中,通过扩展和覆盖的方式,您可以基于一个基础的 docker-compose.yml
文件创建多个变体,以适应不同的环境、部署阶段或配置需求。这使得在不同的场景下使用相似的配置更加灵活。
8.4.1 扩展(Extending)
通过扩展,您可以基于一个现有的 docker-compose.yml
文件创建一个新的文件,而不是从头开始。在新文件中,您可以添加、修改或覆盖原始文件中的服务、网络、卷等定义。
例子:
假设您有一个基础的 docker-compose.yml
文件:
version: '3'
services:
web:
image: nginx:latest
ports:
- "8080:80"
db:
image: mysql:latest
environment:
MYSQL_ROOT_PASSWORD: example
然后,您可以创建一个新的 docker-compose.override.yml
文件,用于扩展基础配置,例如:
version: '3'
services:
web:
ports:
- "8081:80"
在这个例子中,docker-compose.override.yml
扩展了基础配置,修改了 web
服务的端口映射。
8.4.2 覆盖(Overriding)
覆盖是指通过一个额外的 docker-compose.yml
文件,以特定的优先级替换或修改基础配置中的部分内容。覆盖的文件名通常是 docker-compose.override.yml
,但也可以通过 -f
选项显式指定其他文件。
例子:
假设您有一个基础的 docker-compose.yml
文件:
version: '3'
services:
web:
image: nginx:latest
ports:
- "8080:80"
然后,您可以创建一个新的 docker-compose.override.yml
文件,用于覆盖基础配置,例如:
version: '3'
services:
web:
ports:
- "8081:80"
在这个例子中,docker-compose.override.yml
覆盖了基础配置中 web
服务的端口映射。
问:如果我运行 docker-compose -f docker-compose.dev.yml up ,还会去查找 docker-compose.yml 文件吗?
答:
是的,如果您在运行
docker-compose
命令时指定了-f
或--file
选项,Docker Compose 仍然会尝试查找默认的docker-compose.yml
文件,并将其与指定的文件一起合并。这样可以确保您在指定的文件中添加或覆盖配置时,仍然可以包含基本的配置。例如,假设您有以下文件:
docker-compose.yml
包含基本的配置。docker-compose.dev.yml
包含开发环境的配置。如果您运行以下命令:
docker-compose -f docker-compose.dev.yml up
Docker Compose 将尝试加载
docker-compose.yml
和docker-compose.dev.yml
文件,并将它们的配置合并在一起。在这个过程中,docker-compose.dev.yml
中的配置将覆盖docker-compose.yml
中的相同配置。这种行为是确保在不同环境中可以方便地使用默认配置并进行覆盖或扩展的一种机制。如果不需要默认的
docker-compose.yml
文件,您也可以在命令中省略-f
选项,例如:docker-compose up
这将使用默认的
docker-compose.yml
文件运行。
8.4.3 优先级
在扩展和覆盖中,有一定的优先级规则:
- 基础配置文件: 包含基本配置的
docker-compose.yml
文件。 - 扩展文件: 使用
-f
选项或docker-compose.override.yml
文件进行的扩展。 - 环境变量: 使用
COMPOSE_FILE
环境变量指定的文件。
例如,如果有一个 docker-compose.yml
文件和一个 docker-compose.override.yml
文件:
- 如果使用
docker-compose up
,则两个文件都会被考虑,docker-compose.override.yml
中的配置会覆盖docker-compose.yml
中的配置。 - 如果使用
COMPOSE_FILE
环境变量指定了一个文件,该文件将覆盖所有其他文件。
通过扩展和覆盖,您可以更容易地管理不同环境和配置变体,而无需修改原始配置文件。