Docker-基础
1. 概述
Docker 是一个开源的容器化平台,用于自动化应用程序的部署、扩展和管理。Docker 通过将应用程序及其依赖打包到一个轻量级的容器中,确保应用程序可以在任何支持 Docker 的环境中一致运行。主要用途包括:
- 环境一致性: 在开发、测试、生产环境中提供一致的运行环境。
- 资源隔离: 通过容器技术隔离不同应用,避免环境冲突。
- 敏捷开发: 加快应用程序的交付和部署周期。
- 扩展性: 支持大规模分布式系统的容器编排和管理。
2. Docker 镜像和容器
2.1 Docker 镜像(image)
Docker 镜像是Docker容器的基础,类似于虚拟机的操作系统镜像。Docker 镜像是由多个只读层(layer)组成的,每一层都代表文件系统的一部分。镜像是不可变的,而容器是在镜像的基础上添加一个可写层。
2.1.1. 镜像的结构
Docker 镜像由一系列只读层组成,每一层对应一次文件系统的修改。所有层都是基于上一层构建的,这种分层结构使得镜像在不同容器之间可以共享,从而减少存储空间和加快部署速度。
- 基础层(Base Layer):每个Docker镜像通常都会有一个基础层,它通常是操作系统的一个最小化版本,比如Ubuntu或Alpine。
- 中间层(Intermediate Layer):在基础层之上,Dockerfile中的每一条指令(如RUN、COPY、ADD等)都会创建一个新的层。
- 顶层(Top Layer):这是镜像的最后一层,包含了镜像构建过程的最终状态。
2.1.2. 镜像的创建
Docker镜像可以通过以下几种方式创建:
- Dockerfile:最常见的方法是通过编写一个Dockerfile,定义从基础镜像开始需要执行的指令,然后使用docker build命令来构建镜像。
- 从容器导出:可以从一个已经运行的容器中创建镜像,使用docker commit命令保存容器的当前状态为新的镜像。
2.1.3. 镜像的管理
常用的Docker镜像管理命令包括:
- docker images:列出本地存储的所有Docker镜像。
- docker pull
:从Docker Hub或其他镜像仓库拉取镜像。 - docker push
:将本地镜像上传到Docker Hub或私有仓库。 - docker rmi
:删除本地的Docker镜像。
2.1.4. 镜像标签(Tags)
每个Docker镜像通常都会有一个或多个标签(tag),用于标识镜像的不同版本。例如,nginx:latest表示nginx的最新版本,nginx:1.19表示nginx的1.19版本。标签便于在同一个镜像仓库中管理不同的版本。
2.1.5 镜像的优化
镜像的体积和构建速度是影响容器启动和部署的关键因素。优化Docker镜像的常用方法包括:
- 选择小型基础镜像:如Alpine,比标准的Ubuntu镜像体积小。
- 减少镜像层:通过合并Dockerfile中的指令来减少中间层。
- 清理缓存和临时文件:在镜像构建过程中清理不必要的文件,减少镜像大小。
2.1.6 镜像仓库(Registry)
Docker 镜像通常存储在镜像仓库中,可以是公共的Docker Hub,也可以是企业内部的私有仓库。
- Docker Hub:默认的公共镜像仓库,全球用户都可以访问。
- 私有仓库:可以使用Docker Registry搭建自己的镜像仓库,用于企业内部的镜像存储。
2.2 Docker 容器 (container)
Docker 容器是Docker技术的核心,它将应用程序及其所有依赖项封装在一个独立的环境中,使其能够在任何计算机上运行而不会受到底层操作系统的影响。Docker 容器与传统的虚拟机不同,具有轻量、快速启动、资源高效等特点。
2.2.1 Docker 容器的概念
Docker 容器是从Docker 镜像启动的一个实例。容器包含了应用程序运行所需的所有内容,包括代码、运行时环境、系统工具、库和设置。通过容器化,开发者可以确保应用在开发、测试和生产环境中的行为一致。
2.2.2 容器的工作原理
Docker 容器基于 Linux 的名字空间(Namespaces)和控制组(Cgroups)技术,实现进程隔离和资源限制。每个容器在自己的名字空间中运行,与其他容器和宿主机隔离开来,同时共享宿主机的操作系统内核。
- 名字空间(Namespaces):名字空间提供了进程隔离,确保每个容器只能看到自己的文件系统、进程、网络和用户空间。
- 控制组(Cgroups):控制组允许Docker限制容器的资源使用,如CPU、内存、磁盘I/O等。
2.2.3 容器的生命周期
Docker 容器的生命周期管理通过一系列的命令来实现:
- 创建容器:使用docker create或docker run命令从镜像创建一个容器。
- 启动容器:使用docker start命令启动一个已创建的容器。
- 停止容器:使用docker stop命令停止正在运行的容器。
- 删除容器:使用docker rm命令删除一个已停止的容器。
- 查看容器:使用docker ps查看正在运行的容器,使用docker ps -a查看所有容器。
3. Dockerfile
3.1 Dockerfile简介
Dockerfile 是一个包含了指令的文本文件,每个指令告诉 Docker 如何构建一个镜像。Docker 会按顺序读取 Dockerfile 中的指令并执行它们,最终生成一个可运行的镜像。
3.2 基础案例:创建一个简单的Web服务器
3.2.1创建一个简单的 HTML 页面
首先,我们创建一个简单的HTML文件,用于展示在Web服务器上。
<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
<title>Hello Docker</title>
</head>
<body>
<h1>Hello from Docker!</h1>
</body>
</html>
3.2.2编写 Dockerfile
在同一个目录中,创建一个名为 Dockerfile 的文件,内容如下:
# 使用官方的 Nginx 作为基础镜像
FROM nginx:alpine
# 维护者信息
LABEL maintainer="youremail@example.com"
# 复制当前目录下的 index.html 文件到 Nginx 的默认页面目录
COPY index.html /usr/share/nginx/html/
# 暴露端口 80
EXPOSE 80
# 启动 Nginx 服务器
CMD ["nginx", "-g", "daemon off;"]
3.2.3 构建镜像
使用以下命令构建镜像:
docker build -t my-nginx .
• -t my-nginx:为镜像指定一个标签名称。
• .:表示当前目录为构建上下文。
3.2.4 运行容器
运行构建好的镜像:
docker run -d -p 8080:80 my-nginx
• -d:让容器在后台运行。
• -p 8080:80:将宿主机的8080端口映射到容器的80端口。
打开浏览器访问 http://localhost:8080,你将看到“Hello from Docker!”的页面。
3.3 进阶案例:构建一个Python应用程序
3.3.1 准备Python脚本
创建一个简单的 Python 应用程序:
# app.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return "Hello, Docker!"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
3.3.2 创建Dockerfile
在同一目录下创建一个 Dockerfile 文件:
# 使用官方的 Python 作为基础镜像
FROM python:3.9-slim
# 设定工作目录
WORKDIR /app
# 将当前目录内容复制到容器的工作目录中
COPY . /app
# 安装 Python 依赖
RUN pip install flask
# 暴露端口 5000
EXPOSE 5000
# 启动应用
CMD ["python", "app.py"]
3.3.3 构建镜像
docker build -t my-python-app .
3.3.4 运行容器
运行构建好的镜像:
docker run -d -p 5000:5000 my-python-app
访问 http://localhost:5000,你将看到“Hello, Docker!”。
3.4 Dockerfile 指令的深入理解
3.4.1 多阶段构建
多阶段构建用于减少镜像的大小。一个典型的场景是构建二进制文件后仅将其复制到最终镜像中。
# 第一阶段:构建应用
FROM golang:alpine AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp
# 第二阶段:创建运行环境
FROM alpine
WORKDIR /app
COPY --from=builder /app/myapp .
CMD ["./myapp"]
3.4.2 使用 ARG 和 ENV
ARG指令
1. 定义
ARG 用于定义构建时的变量。这些变量在镜像构建过程中使用,可以在 RUN、CMD、ENTRYPOINT 等指令中使用。
2. 作用范围
ARG 变量的作用范围仅限于 Dockerfile 构建过程,即在使用 docker build 命令构建镜像时有效。构建完成后,这些变量不会保留在最终的镜像或容器中。
3. 使用示例
# 定义一个构建时变量,默认值为 1.0
ARG VERSION=1.0
# 使用该变量
RUN echo "Building version ${VERSION}"
# 如果需要将 ARG 的值保存到 ENV 中,可以使用 ENV 指令
ENV APP_VERSION=${VERSION}
4. 传递构建时参数
在使用 docker build 命令时,可以通过 --build-arg 选项传递构建时参数。
docker build --build-arg VERSION=2.0 -t myapp:2.0 .
上面的命令会将 VERSION 设置为 2.0,覆盖 Dockerfile 中的默认值 1.0。
5. 作用范围的限制
ARG 定义的变量在 FROM 指令之前是不可用的。因此,无法在 FROM 指令中使用 ARG 定义的变量,除非它们被定义在 FROM 之后或多阶段构建的过程中。
ENV指令
1. 定义
ENV 用于定义环境变量,这些变量会在镜像构建过程中和容器运行时都可用。它们的值会保留在镜像和容器中,可以被程序或脚本访问。
2. 作用范围
ENV 变量在整个镜像生命周期中都是有效的,包括镜像构建过程和容器运行时。因此,这些变量可以在 Dockerfile 的任何地方使用,也可以在容器内被应用程序访问。
3. 使用示例
# 定义环境变量
ENV APP_ENV=production
ENV APP_PORT=8080
# 使用环境变量
RUN echo "Running in ${APP_ENV} mode on port ${APP_PORT}"
# 容器启动时访问环境变量
CMD ["sh", "-c", "echo The app is running in $APP_ENV mode on port $APP_PORT"]
4. 覆盖环境变量
在启动容器时,可以使用 docker run 命令的 -e 选项覆盖 ENV 指令设置的环境变量:
docker run -e APP_ENV=development myapp
这样,APP_ENV 的值在容器内将会是 development 而非 production。
总结
- ARG:用于在构建时定义变量,范围仅限于构建过程中,可以通过 --build-arg 传递不同的值。这些变量在镜像构建完成后不再保留。
- ENV:用于定义环境变量,范围覆盖整个镜像和容器生命周期。这些变量可以在构建过程中和容器运行时使用,并且可以通过 docker run -e 来覆盖。
3.4.3 Dockerfile指令详解
以下是 Dockerfile 中常用指令的详解表格,包括每个指令的用途、示例和说明:
指令 | 用途 | 示例 | 说明 |
---|---|---|---|
FROM |
指定构建镜像所基于的基础镜像 | FROM ubuntu:20.04 |
每个 Dockerfile 必须以 FROM 指令开始。可以多次使用以实现多阶段构建。 |
LABEL |
添加元数据到镜像中 | LABEL maintainer="youremail@example.com" |
可以用来添加作者信息、版本信息等元数据。 |
RUN |
在镜像构建时执行命令 | RUN apt-get update && apt-get install -y curl |
用于安装包、执行脚本等。每个 RUN 指令会创建一个新的镜像层。 |
CMD |
指定容器启动时要执行的默认命令 | CMD ["nginx", "-g", "daemon off;"] |
指定容器启动时执行的命令,但可以被 docker run 命令行参数覆盖。 |
ENTRYPOINT |
配置容器启动时运行的可执行文件 | ENTRYPOINT ["python", "app.py"] |
设置一个固定的命令,CMD 仅作为参数传递给 ENTRYPOINT 。 |
WORKDIR |
设置工作目录 | WORKDIR /app |
在容器内设置工作目录,之后的所有命令都在这个目录下执行。 |
COPY |
将文件/目录从构建上下文复制到镜像中 | COPY . /app |
将文件或目录从构建上下文复制到容器文件系统中。 |
ADD |
复制文件/目录到镜像中,支持 URL 和解压归档文件 | ADD https://example.com/file.tar.gz /app/ |
类似 COPY ,但功能更强大,可以自动解压 tar 文件或下载 URL 中的文件。 |
ENV |
设置环境变量 | ENV APP_ENV=production |
设置环境变量,可以在 RUN 、CMD 、ENTRYPOINT 等指令中使用。 |
ARG |
定义构建时参数 | ARG VERSION=1.0 |
定义在构建时使用的参数,可通过 docker build --build-arg 传递。 |
VOLUME |
定义匿名挂载点 | VOLUME ["/data"] |
为持久化数据定义一个挂载点,该目录在容器运行时不会持久化到容器中。 |
EXPOSE |
声明镜像要监听的端口 | EXPOSE 80 |
声明容器使用的端口,但不自动发布端口到宿主机。用于文档或容器互联。 |
USER |
设置容器内运行时的用户 | USER nonrootuser |
切换到指定用户运行后续命令,增强容器的安全性。 |
HEALTHCHECK |
检查容器的运行状况 | HEALTHCHECK CMD curl --fail http://localhost:80 || exit 1 |
定义容器健康检查命令和频率。如果健康检查失败,容器状态会变为unhealthy 。 |
SHELL |
指定运行脚本时使用的 shell | SHELL ["/bin/bash", "-c"] |
改变执行脚本时的默认 shell,默认是 ["/bin/sh", "-c"] 。 |
STOPSIGNAL |
设置停止容器时发送的系统调用信号 | STOPSIGNAL SIGKILL |
定义在停止容器时发送的信号,默认是 SIGTERM 。 |
ONBUILD |
定义在未来镜像构建时自动执行的命令 | ONBUILD RUN echo "This will run on children images" |
用于定义父镜像中要在子镜像构建时自动执行的指令。 |
COPY --from |
从一个构建阶段复制文件到另一个阶段 | COPY --from=builder /app/build /app/ |
在多阶段构建中,从一个构建阶段复制文件到另一个阶段。 |
说明:
- FROM
:每个阶段都必须以 FROM
开头,可以多次使用以实现多阶段构建。
- RUN
和 CMD
:区别在于 RUN
用于构建时执行命令,而 CMD
用于容器启动时的默认命令。
- ENTRYPOINT
和 CMD
:ENTRYPOINT
更倾向于固定执行的命令,CMD
可以作为参数传递给 ENTRYPOINT
。
- COPY
和 ADD
:ADD
功能更强大,但更推荐使用 COPY
,除非需要解压缩文件或从远程URL获取文件。
通过熟练使用这些指令,你可以编写出更加高效、灵活的Dockerfile,以满足各种构建和部署需求。
4. 网络模式
1. 网络模式概述
Docker 支持以下几种网络模式:
1. bridge 网络模式
2. host 网络模式
3. none 网络模式
4. container 网络模式
5. 自定义网络模式(overlay、macvlan)
2. 网络模式详解
1. bridge 网络模式
描述:
-
bridge 模式是 Docker 默认的网络模式。当创建一个新容器时,如果没有指定网络模式,容器会连接到 Docker 创建的默认 bridge 网络中。
-
每个容器会被分配一个独立的 IP 地址,与其他容器和主机通过桥接网络通信。
使用场景:
- 适合在单机上运行多个容器,容器之间可以通过 IP 地址进行通信,同时可以通过端口映射将容器暴露给外部网络。
docker run -d --name my-container --network bridge nginx
特点:
- 容器之间可以通过 IP 地址通信。
- 可以使用端口映射(-p 参数)将容器端口暴露给主机。
2. host 网络模式
描述:
- 在 host 模式下,容器与宿主机共享网络栈,容器不会获得独立的 IP 地址,而是使用宿主机的 IP 地址。
- 容器内的应用程序直接暴露在宿主机的网络接口上。
使用场景
适用于对网络性能要求高的应用程序,或需要访问宿主机上网络接口的应用。
docker run -d --name my-container --network host nginx
特点
- 提供更好的网络性能,因为没有网络地址转换(NAT)。
- 容器直接使用宿主机的 IP 地址,所有暴露的端口对宿主机开放。
3. none 网络模式
描述:
- 在 none 模式下,容器没有网络接口,完全隔离于网络之外。容器只有一个 lo(回环)接口。
- 这种模式下,容器无法与其他容器或外部网络通信。
使用场景
适合完全隔离的任务,或者需要自定义网络栈的场景。
docker run -d --name my-container --network none nginx
特点:
- 容器完全没有外部网络连接。
- 需要通过自定义的网络配置来实现通信(如使用 ip link 等命令)。
4. container 网络模式
描述
container 模式允许一个容器共享另一个容器的网络栈。这意味着两个容器将共享同一个 IP 地址和端口空间。
使用场景
适用于需要多个容器共享同一个网络接口或依赖相同网络栈的应用。
docker run -d --name container1 nginx
docker run -d --name container2 --network container:container1 busybox
特点:
- 共享网络栈的容器使用同一个 IP 地址。
- 容器间通信使用 localhost 和本地端口。
5. 自定义网络模式
overlay 网络模式
• 描述:overlay 网络模式用于 Docker Swarm 集群中的跨主机通信。它通过在 Docker 主机之间创建虚拟网络来实现容器的跨主机通信。
• 使用场景:适用于分布式应用或微服务架构中的容器通信。
docker network create --driver overlay my-overlay-network
docker run -d --name my-container --network my-overlay-network nginx
macvlan 网络模式
描述:macvlan 网络模式允许每个容器获得一个唯一的 MAC 地址,使容器看起来像宿主机网络上的物理设备。容器可以直接连接到宿主机的物理网络。
使用场景:适用于需要容器直接参与物理网络、具有固定 IP 地址的场景。
docker network create -d macvlan \
--subnet=192.168.1.0/24 \
--gateway=192.168.1.1 \
-o parent=eth0 my-macvlan-network
docker run -d --name my-container --network my-macvlan-network nginx
总结
网络模式 | 描述 | 使用场景 |
---|---|---|
bridge |
默认网络模式,容器在虚拟桥接网络中,有独立的 IP 地址。 | 单机运行多个容器,容器间需通信并与外部网络连接。 |
host |
容器与宿主机共享网络栈,容器使用宿主机的 IP 地址。 | 对网络性能要求高,或需要直接使用宿主机网络的应用。 |
none |
容器没有网络接口,完全隔离于网络之外。 | 需要完全隔离的任务或自定义网络配置。 |
container |
容器共享另一个容器的网络栈,使用同一个 IP 地址。 | 多个容器需要共享同一网络接口或依赖相同网络栈。 |
overlay |
跨主机的虚拟网络,用于 Docker Swarm 集群中。 | 分布式应用或微服务架构中的容器通信。 |
macvlan |
每个容器获得一个唯一的 MAC 地址,容器像物理设备一样直接连接到宿主机的物理网络。 | 需要容器参与物理网络、具有固定 IP 地址的场景。 |
理解并灵活运用这些网络模式,可以帮助你设计和实现更为复杂和高效的容器网络架构。
5. 数据持久化
Docker 容器本质上是短暂的和无状态的,这意味着当容器被删除或重启时,容器内的数据会丢失。然而,很多应用需要数据持久化,以便在容器重启或删除后数据仍然存在。Docker 提供了多种方式来实现持久化存储,主要通过卷(Volumes)、绑定挂载(Bind Mounts)和 tmpfs 挂载来实现。
一、Docker 数据持久化方式概述
- Volumes(卷):由 Docker 管理的挂载点,可以在容器间共享,且与宿主机的文件系统隔离。
- Bind Mounts(绑定挂载):将宿主机的目录或文件直接挂载到容器中,容器对该目录或文件的操作会直接影响宿主机。
- Tmpfs Mounts(内存挂载):将数据存储在内存中,而非宿主机的磁盘上,适用于需要高性能、但数据无需持久化的场景。
二、Docker 持久化方式详解
1. Volumes(卷)
- 描述:
- 卷是 Docker 推荐的数据持久化方式。卷存储在 Docker 管理的目录中(通常在
/var/lib/docker/volumes/
下),并且可以被多个容器挂载和共享。 -
卷的生命周期独立于容器,可以在容器删除后保留数据。
-
使用场景:
-
适用于需要持久化数据、跨多个容器共享数据的应用,如数据库、持久化缓存等。
-
示例:
-
创建并挂载卷: ```bash # 创建卷 docker volume create my-volume
运行容器并挂载卷
docker run -d --name my-container -v my-volume:/data nginx ```
-
删除卷:
bash # 删除卷(注意:在删除前需确保没有容器在使用此卷) docker volume rm my-volume
-
特点:
- 卷是由 Docker 管理的,与宿主机的文件系统隔离。
- 可以通过卷跨多个容器共享数据。
- 卷可以在容器停止或删除后继续存在。
2. Bind Mounts(绑定挂载)
- 描述:
-
Bind Mounts 允许你将宿主机的特定目录或文件挂载到容器内的目录。这种方式直接映射宿主机的文件系统,容器对挂载目录或文件的操作会直接影响宿主机。
-
使用场景:
-
适用于需要容器访问和使用宿主机上的现有数据的场景,如访问配置文件、日志文件等。
-
示例:
-
使用绑定挂载:
bash docker run -d --name my-container -v /path/on/host:/path/in/container nginx
-
例如,将宿主机的
/var/log
目录挂载到容器的/log
目录:bash docker run -d --name my-container -v /var/log:/log nginx
-
特点:
- Bind Mounts 直接使用宿主机的文件系统,因此对数据的更改会直接影响宿主机。
- 相比卷,它更灵活,但需要更小心管理,因为错误配置可能导致宿主机数据被破坏。
3. Tmpfs Mounts(内存挂载)
- 描述:
-
Tmpfs Mounts 允许你将容器内的数据存储在内存中,而不是宿主机的磁盘上。它不适合持久化存储,但在需要快速访问数据且数据不需要持久化的场景中非常有用。
-
使用场景:
-
适用于临时数据、缓存文件或敏感数据的存储,数据在容器停止后即丢失。
-
示例:
-
创建 Tmpfs 挂载:
bash docker run -d --name my-container --mount type=tmpfs,destination=/app/tmpfs tmpfs-size=64m nginx
-
特点:
- 数据存储在内存中,访问速度快。
- 适合不需要持久化的数据存储,数据在容器停止后丢失。
三、Docker 数据持久化的高级使用
1. Named Volumes(命名卷)
-
描述:命名卷是指使用特定名称创建和管理的卷,允许你明确地指定和管理卷的生命周期。
-
使用:
bash docker volume create my-named-volume docker run -d --name my-container -v my-named-volume:/data nginx
2. Anonymous Volumes(匿名卷)
-
描述:匿名卷是没有名称的卷,当你使用
-v /path/in/container
格式挂载卷时,会自动创建一个匿名卷。 -
特点:在容器删除时,匿名卷会孤立存在,需手动清理。
-
使用:
bash docker run -d --name my-container -v /data nginx
3. 数据卷容器
-
描述:数据卷容器是一种用于共享卷的容器。你可以将卷挂载到一个容器上,然后在其他容器中通过
--volumes-from
选项使用这些卷。 -
示例: ```bash # 创建一个数据卷容器 docker create -v /data --name data-container busybox
# 其他容器可以通过 --volumes-from 共享数据卷 docker run -d --name my-container --volumes-from data-container nginx ```
四、总结
持久化方式 | 描述 | 使用场景 | 优点 | 缺点 |
---|---|---|---|---|
Volumes | 由 Docker 管理的存储卷,可在容器间共享,独立于宿主机文件系统。 | 需要持久化数据、跨多个容器共享数据的场景。 | 卷独立于宿主机文件系统,安全且便于管理。 | 与宿主机文件系统隔离,可能不适合需要直接访问宿主机数据的场景。 |
Bind Mounts | 直接将宿主机的目录或文件挂载到容器中,容器对数据的更改会直接反映在宿主机上。 | 需要容器访问和使用宿主机上的现有数据的场景。 | 可以直接访问和操作宿主机上的文件和目录。 | 需要小心管理,错误的配置可能导致宿主机数据损坏。 |
Tmpfs Mounts | 将数据存储在内存中,适用于需要快速访问且不需持久化的数据。 | 临时数据、缓存或敏感数据存储,数据在容器停止后丢失。 | 高性能的数据访问,因为数据存储在内存中。 | 数据不可持久化,容器停止后数据丢失。 |
选择合适的持久化方式取决于具体的应用需求。对于需要长期保存的数据,如数据库数据,使用 Volumes
是最佳选择;对于需要直接操作宿主机文件的场景,Bind Mounts
更为合适;而对于临时性或高性能数据需求,Tmpfs Mounts
则是一个不错的选择。
6. Docker Compose
Docker Compose 是一个用于定义和管理多容器 Docker 应用的工具。它允许你使用一个 YAML 文件来定义应用的服务、网络、卷等配置,并通过简单的命令来管理这些服务。Docker Compose 可以极大地简化多容器应用的部署和管理,尤其是在开发、测试和持续集成环境中。
一、Docker Compose 基本概念
- 服务(Services):服务是一个运行容器的定义,通常对应一个镜像。你可以在 Docker Compose 文件中定义多个服务,每个服务可以运行一个或多个容器。
- 网络(Networks):Docker Compose 中的服务默认会连接到一个名为
default
的网络,你也可以在 YAML 文件中自定义网络。 - 卷(Volumes):用于持久化服务数据或在服务之间共享数据,可以在 YAML 文件中定义和配置。
二、Docker Compose 文件结构
Docker Compose 的配置文件使用 YAML 格式,通常命名为 docker-compose.yml
。以下是一个基本的 Docker Compose 文件结构:
version: '3.8' # 指定 Docker Compose 文件版本
services: # 定义应用的服务
web: # 定义一个服务,名称为 web
image: nginx # 使用官方的 nginx 镜像
ports: # 映射容器的端口到主机
- "8080:80"
volumes: # 将主机目录挂载到容器中
- ./html:/usr/share/nginx/html
networks: # 指定服务使用的网络
- frontend
db: # 定义另一个服务,名称为 db
image: mysql:5.7 # 使用官方的 MySQL 镜像
environment: # 设置环境变量
MYSQL_ROOT_PASSWORD: example
volumes: # 定义数据卷
- db-data:/var/lib/mysql
networks: # 指定服务使用的网络
- backend
volumes: # 定义应用使用的数据卷
db-data:
networks: # 定义应用使用的网络
frontend:
backend:
三、Docker Compose 文件详解
1. version
-
描述:指定 Docker Compose 文件的版本。不同版本支持的功能不同,目前常用的是
3.x
系列。 -
示例:
yaml version: '3.8'
2. services
-
描述:定义应用的服务。每个服务对应一个 Docker 容器,服务可以通过镜像构建,也可以从 Dockerfile 构建。
-
关键子项:
image
:指定服务使用的镜像。build
:如果没有镜像,可以指定 Dockerfile 来构建镜像。ports
:暴露容器的端口。volumes
:挂载卷或绑定挂载。environment
:设置环境变量。-
networks
:指定服务加入的网络。 -
示例:
yaml services: web: image: nginx ports: - "8080:80" volumes: - ./html:/usr/share/nginx/html networks: - frontend db: image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: example volumes: - db-data:/var/lib/mysql networks: - backend
3. volumes
-
描述:定义和管理数据卷。卷可以用于持久化数据或在多个服务之间共享数据。
-
示例:
yaml volumes: db-data:
4. networks
-
描述:定义和管理服务间的网络。你可以创建多个自定义网络,并将服务连接到这些网络中。
-
示例:
yaml networks: frontend: backend:
四、常用 Docker Compose 命令
以下是一些常用的 Docker Compose 命令:
docker-compose up
:启动所有服务,并在前台显示日志。如果使用-d
选项,服务会在后台运行。
bash
docker-compose up
docker-compose up -d # 后台运行
docker-compose down
:停止并删除所有服务容器、网络和数据卷。
bash
docker-compose down
docker-compose ps
:查看当前运行的服务容器状态。
bash
docker-compose ps
docker-compose logs
:查看服务的日志输出。
bash
docker-compose logs
docker-compose logs -f # 实时查看日志
docker-compose exec
:在一个运行中的服务容器内执行命令。
bash
docker-compose exec web bash # 在 web 服务的容器中打开 Bash 终端
docker-compose build
:构建或重新构建服务镜像。
bash
docker-compose build
五、Docker Compose 的高级特性
1. 多环境支持(Override Files)
-
描述:Docker Compose 支持使用多个配置文件,以便在不同的环境中使用不同的配置。例如,可以创建一个
docker-compose.override.yml
文件,用于覆盖或扩展docker-compose.yml
中的配置。 -
示例:
yaml # docker-compose.override.yml version: '3.8' services: web: environment: - DEBUG=true
-
命令:
bash docker-compose -f docker-compose.yml -f docker-compose.override.yml up
2. 环境变量文件(.env
)
-
描述:可以使用
.env
文件来定义环境变量,Docker Compose 会自动加载该文件中的变量。 -
示例:
bash # .env 文件 MYSQL_ROOT_PASSWORD=examplepassword
在 docker-compose.yml
中使用:
yaml
services:
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
3. 部署模式(Swarm 模式)
-
描述:Docker Compose 还可以用于 Docker Swarm 集群的部署,利用
docker stack deploy
命令可以将 Compose 文件作为 Swarm 集群的服务定义。 -
命令:
bash docker stack deploy -c docker-compose.yml my_stack
六、总结
Docker Compose 提供了一种简单但强大的方式来定义和管理多容器应用的运行环境。通过一个 YAML 文件,你可以轻松地定义应用的各个服务、网络、卷等配置,并通过简单的命令来启动、停止和管理这些服务。这使得 Docker Compose 成为开发、测试和部署环境中不可或缺的工具。
掌握 Docker Compose 的基本概念和命令,可以显著提高开发和运维的效率,尤其是在管理复杂的多容器应用时。
7. Docker命令大全
Docker 是一个强大的容器管理工具,提供了一系列命令用于构建、运行、管理和监控容器。以下是一些常用的 Docker 命令及其详细解释:
一、镜像管理命令
1. docker pull
- 描述:从 Docker 仓库中拉取镜像到本地。
- 语法:
docker pull [OPTIONS] NAME[:TAG|@DIGEST]
- 示例:
bash docker pull nginx:latest # 拉取最新版本的 nginx 镜像
2. docker images
- 描述:列出本地所有的 Docker 镜像。
- 语法:
docker images [OPTIONS] [REPOSITORY[:TAG]]
- 示例:
bash docker images # 查看所有本地镜像
3. docker rmi
- 描述:删除一个或多个本地镜像。
- 语法:
docker rmi [OPTIONS] IMAGE [IMAGE...]
- 示例:
bash docker rmi nginx:latest # 删除指定的 nginx 镜像
4. docker build
- 描述:通过 Dockerfile 构建镜像。
- 语法:
docker build [OPTIONS] PATH | URL | -
- 示例:
bash docker build -t myapp:latest . # 使用当前目录的 Dockerfile 构建镜像,并命名为 myapp:latest
二、容器管理命令
1. docker run
- 描述:创建并启动一个新的容器。
- 语法:
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
- 示例:
bash docker run -d -p 80:80 nginx # 后台运行一个 nginx 容器,并将主机的 80 端口映射到容器的 80 端口
2. docker ps
- 描述:列出当前运行的容器。
- 语法:
docker ps [OPTIONS]
- 示例:
bash docker ps # 列出所有正在运行的容器 docker ps -a # 列出所有容器,包括已停止的
3. docker stop
- 描述:停止一个或多个正在运行的容器。
- 语法:
docker stop [OPTIONS] CONTAINER [CONTAINER...]
- 示例:
bash docker stop my-container # 停止名为 my-container 的容器
4. docker start
- 描述:启动一个或多个已停止的容器。
- 语法:
docker start [OPTIONS] CONTAINER [CONTAINER...]
- 示例:
bash docker start my-container # 启动名为 my-container 的容器
5. docker restart
- 描述:重启一个或多个容器。
- 语法:
docker restart [OPTIONS] CONTAINER [CONTAINER...]
- 示例:
bash docker restart my-container # 重启名为 my-container 的容器
6. docker rm
- 描述:删除一个或多个已停止的容器。
- 语法:
docker rm [OPTIONS] CONTAINER [CONTAINER...]
- 示例:
bash docker rm my-container # 删除名为 my-container 的容器 docker rm $(docker ps -a -q) # 删除所有已停止的容器
7. docker exec
- 描述:在运行中的容器内执行命令。
- 语法:
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
- 示例:
bash docker exec -it my-container /bin/bash # 进入名为 my-container 的容器并打开 Bash 终端
三、网络管理命令
1. docker network ls
- 描述:列出所有的 Docker 网络。
- 语法:
docker network ls
- 示例:
bash docker network ls # 列出所有网络
2. docker network create
- 描述:创建一个新的 Docker 网络。
- 语法:
docker network create [OPTIONS] NETWORK
- 示例:
bash docker network create my-network # 创建一个名为 my-network 的网络
3. docker network inspect
- 描述:查看一个或多个 Docker 网络的详细信息。
- 语法:
docker network inspect [OPTIONS] NETWORK [NETWORK...]
- 示例:
bash docker network inspect my-network # 查看 my-network 的详细信息
4. docker network connect
- 描述:将一个容器连接到一个网络。
- 语法:
docker network connect [OPTIONS] NETWORK CONTAINER
- 示例:
bash docker network connect my-network my-container # 将 my-container 容器连接到 my-network 网络
5. docker network disconnect
- 描述:将一个容器从一个网络中断开。
- 语法:
docker network disconnect [OPTIONS] NETWORK CONTAINER
- 示例:
bash docker network disconnect my-network my-container # 将 my-container 容器从 my-network 网络中断开
四、卷管理命令
1. docker volume ls
- 描述:列出所有的 Docker 卷。
- 语法:
docker volume ls
- 示例:
bash docker volume ls # 列出所有卷
2. docker volume create
- 描述:创建一个新的 Docker 卷。
- 语法:
docker volume create [OPTIONS] VOLUME
- 示例:
bash docker volume create my-volume # 创建一个名为 my-volume 的卷
3. docker volume inspect
- 描述:查看一个或多个 Docker 卷的详细信息。
- 语法:
docker volume inspect [OPTIONS] VOLUME [VOLUME...]
- 示例:
bash docker volume inspect my-volume # 查看 my-volume 的详细信息
4. docker volume rm
- 描述:删除一个或多个 Docker 卷。
- 语法:
docker volume rm [OPTIONS] VOLUME [VOLUME...]
- 示例:
bash docker volume rm my-volume # 删除名为 my-volume 的卷
五、容器监控和管理命令
1. docker logs
- 描述:查看容器的日志输出。
- 语法:
docker logs [OPTIONS] CONTAINER
- 示例:
bash docker logs my-container # 查看名为 my-container 的容器日志 docker logs -f my-container # 实时查看容器日志
2. docker stats
- 描述:实时查看容器的资源使用情况。
- 语法:
docker stats [OPTIONS] [CONTAINER...]
- 示例:
bash docker stats # 实时查看所有运行中的容器资源使用情况
3. docker top
- 描述:查看容器中运行的进程。
- 语法:
docker top CONTAINER [ps OPTIONS]
- 示例:
bash docker top my-container # 查看 my-container 容器中运行的进程
4. docker inspect
- 描述:查看 Docker 对象的详细信息,如容器、镜像、网络等。
- 语法:
docker inspect [OPTIONS] NAME|ID [NAME|ID...]
- 示例:
bash docker inspect my-container # 查看 my-container 容器的详细信息
六、其他常用命令
1. docker login
- 描述:登录到 Docker 仓库。
- 语法:
docker login [OPTIONS] [SERVER]
- 示例:
bash docker login # 登录到 Docker Hub
2. docker tag
- 描述:为镜像打标签。
- 语法:
docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
- 示例:
bash docker tag my-image:latest my-repo/my-image:v1.0 # 为 my-image 镜像打标签
3. docker push
- 描述:推送镜像到 Docker 仓库
。
- 语法:docker push [OPTIONS] NAME[:TAG]
- 示例:
bash
docker push my-repo/my-image:v1.0 # 推送 my-image 镜像到 Docker 仓库
4. docker system prune
- 描述:清理未使用的容器、镜像、网络和卷。
- 语法:
docker system prune [OPTIONS]
- 示例:
bash docker system prune -a # 删除所有未使用的容器、镜像、网络和卷
总结
这些命令涵盖了 Docker 的基本操作,包括镜像管理、容器管理、网络管理、卷管理以及容器的监控与管理。掌握这些命令可以帮助你有效地使用 Docker 来构建、运行和管理容器化应用。