跳转至

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 设置环境变量,可以在 RUNCMDENTRYPOINT 等指令中使用。
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 开头,可以多次使用以实现多阶段构建。 - RUNCMD:区别在于 RUN 用于构建时执行命令,而 CMD 用于容器启动时的默认命令。 - ENTRYPOINTCMDENTRYPOINT 更倾向于固定执行的命令,CMD 可以作为参数传递给 ENTRYPOINT。 - COPYADDADD 功能更强大,但更推荐使用 COPY,除非需要解压缩文件或从远程URL获取文件。

通过熟练使用这些指令,你可以编写出更加高效、灵活的Dockerfile,以满足各种构建和部署需求。

4. 网络模式

1. 网络模式概述

Docker 支持以下几种网络模式:

1.  bridge 网络模式
2.  host 网络模式
3.  none 网络模式
4.  container 网络模式
5.  自定义网络模式overlaymacvlan

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 数据持久化方式概述

  1. Volumes(卷):由 Docker 管理的挂载点,可以在容器间共享,且与宿主机的文件系统隔离。
  2. Bind Mounts(绑定挂载):将宿主机的目录或文件直接挂载到容器中,容器对该目录或文件的操作会直接影响宿主机。
  3. 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 来构建、运行和管理容器化应用。