第6章:Docker Compose - 多容器应用的编排利器

第6章:Docker Compose - 多容器应用的编排利器

回顾上一章,为了启动我们的"Web应用 + 数据库"组合,我们执行了一系列命令:

  1. docker network create my-app-net
  2. docker run ... --name db --network my-app-net ... postgres:13
  3. docker run ... --name my-web-app --network my-app-net ... my-app:1.1

这一过程不仅步骤繁多,容易出错,而且还必须严格保证启动顺序(先启动数据库,再启动应用)。如果我们的应用有十几个服务,手动管理简直就是一场噩梦。

是时候请我们的主角登场了------Docker Compose

6.1 告别手敲 docker run!什么是 Docker Compose?

Docker Compose 是 Docker 官方提供的一个用于定义和运行多容器 Docker 应用的工具。

它的核心思想是,让你使用一个 YAML 文件来配置你的应用服务,然后,只需一个简单的命令,就能根据你的配置,创建并启动所有服务。

把 Dockerfile 比作是为单个 组件(服务)准备的"零件图纸",那么 Docker Compose 文件就是一份整个产品的"总装配图"。它清晰地描述了:

  • 产品由哪些零件(服务)组成?
  • 每个零件使用哪张图纸(镜像)?
  • 零件之间如何连接(网络)?
  • 是否需要外接仓库(数据卷)?
  • 需要哪些启动参数(环境变量、端口映射等)?

使用 Compose,你将获得"一键式"的超能力,极大地简化了开发和测试环境的管理。

6.2 docker-compose.yml 文件详解

Compose 的所有魔力,都源于项目根目录下的一个名为 docker-compose.yml 的文件。这是一个遵循特定规范的 YAML 文件。

我们来看一个典型的 docker-compose.yml 结构:

yaml 复制代码
# 指定 compose 文件版本,建议使用 "3.8" 或更新版本
version: "3.8"

# 定义我们应用的所有服务
services:
  # 第一个服务,我们给它起名叫 web
  web:
    # 指定该服务使用哪个镜像构建
    # '.' 表示使用当前目录下的 Dockerfile
    build: .
    # 定义端口映射,相当于 docker run -p 4000:8080
    ports:
      - "4000:8080"
    # 定义数据卷挂载
    volumes:
      - .:/usr/src/app
      - /usr/src/app/node_modules
    # 定义该服务依赖的其他服务
    depends_on:
      - db

  # 第二个服务,名为 db
  db:
    # 直接使用 Docker Hub 上的官方 postgres 镜像
    image: "postgres:13"
    # 定义环境变量,相当于 docker run -e ...
    environment:
      POSTGRES_PASSWORD: mysecretpassword
    # 定义数据卷
    volumes:
      - pg-data:/var/lib/postgresql/data

# 统一管理我们用到的所有数据卷
volumes:
  pg-data:

这个文件是不是看起来非常直观?它几乎把我们之前在 docker run 命令中使用的所有参数,都用一种清晰、声明式的方式描述了出来。

6.3 [实战] 使用 Compose 一键部署"Web应用 + 数据库"

现在,让我们在 my-app 项目的根目录下,创建这个 docker-compose.yml 文件,并把上面的内容粘贴进去。

在开始之前,请先清理掉我们之前手动创建的所有容器和网络,以避免冲突:

bash 复制代码
docker rm -f my-web-app db
docker network rm my-app-net

好了,现在你的环境是干净的。确保你正处于 my-app 目录下,然后执行那个神奇的命令:

bash 复制代码
docker-compose up

当你敲下回车,Compose 会在背后为你完成所有事情:

  1. 读取 docker-compose.yml 文件
  2. 创建网络 :它会自动创建一个默认的网络(通常是 myapp_default),并将所有服务连接上去。
  3. 创建数据卷 :如果 pg-data 数据卷不存在,它会自动创建。
  4. 构建/拉取镜像 :它会检查 web 服务,发现需要 build,于是执行 docker build。然后检查 db 服务,发现需要 image,于是执行 docker pull
  5. 创建并启动服务 :按照 depends_on 定义的依赖关系,它会先启动 db 服务,再启动 web 服务。

你会看到两个服务的日志交错地输出在你的终端上。

现在,打开浏览器访问 http://localhost:4000/db,一切都和之前一样正常工作!

但这一次,我们只用了一条命令!

如果你想让它们在后台运行,只需:

bash 复制代码
# 先用 Ctrl + C 停掉前台运行的服务
# 然后执行
docker-compose up -d

-d 同样是 detach 的意思。

6.4 docker-compose 常用命令

掌握了 docker-compose up,你就掌握了80%的精髓。这里再介绍几个常用的管理命令:

  • 停止并删除所有服务 : 在 docker-compose.yml 所在的目录执行:

    bash 复制代码
    docker-compose down

    这个命令会做 up 的逆向操作:停止并删除所有相关的容器。如果你想把数据卷也一并删除,可以加上 --volumes 参数。

  • 查看所有服务状态:

    bash 复制代码
    docker-compose ps

    功能类似 docker ps,但它只会显示由当前 docker-compose.yml 文件管理的服务。

  • 查看服务日志:

    bash 复制代码
    # 查看所有服务的日志
    docker-compose logs
    
    # 查看特定服务的日志,并实时跟踪
    docker-compose logs -f web
  • 在特定服务中执行命令 : 功能类似 docker exec

    bash 复制代码
    docker-compose exec web /bin/sh

6.5 本章小结

恭喜你,完成了 Docker 篇的最终章!你已经拥有了在本地高效管理复杂应用的能力。

  • 本章回顾
    • 我们理解了 Docker Compose 是用来定义和运行多容器应用的编排工具。
    • 我们学会了编写 docker-compose.yml 这个"总装配图",用声明式的方式定义服务、网络和数据卷。
    • 我们掌握了核心命令 docker-compose updocker-compose down,实现了一键启停整个应用。
    • 我们了解了 ps, logs, exec 等常用的管理命令。

Docker Compose 是开发和测试阶段的绝对神器。它将你从繁琐的命令中解放出来,让你能更专注于代码本身。

至此,Docker 篇的学习就告一段落了。你已经从一个对容器一无所知的新手,成长为了一名能够熟练使用 Docker 打包、运行和管理应用的开发者。

但是,这只是我们旅程的第一步。当你的应用需要部署到生产环境,需要面对高可用、弹性伸缩、自动修复等更严峻的挑战时,一个更强大的"自动化港口"------Kubernetes,正在前方等待着我们。

在下一部分,我们将正式进入 Kubernetes 的世界,探索规模化部署的奥秘!

相关推荐
3分云计算4 小时前
Prometheus-02: 安装部署与配置管理详解
运维·云原生·grafana·普罗米修斯
失散134 小时前
分布式专题——15 ZooKeeper特性与节点数据类型详解
java·分布式·zookeeper·云原生·架构
失散135 小时前
分布式专题——20 Kafka快速入门
java·分布式·云原生·架构·kafka
boonya5 小时前
如何理解Service Mesh(服务网格)
云原生·服务网格·service_mesh
小马过河R5 小时前
K8s引入Service Mesh原因及Istio入门
云原生·容器·kubernetes·k8s·istio·service_mesh
行者Sun19896 小时前
【K8s】Kubernetes 虚拟机管理工具之 KubeVirt
云原生·容器·kubernetes
途经六月的绽放6 小时前
Docker Compose 从入门到实践
java·docker
虚伪的空想家6 小时前
生产环境K8S的etcd备份脚本
运维·容器·kubernetes·脚本·备份·etcd
孙克旭_7 小时前
kind部署K8S集群并将“修仙业务“部署到kind集群
linux·运维·云原生·kubernetes·kind