缘博客
发布日期

Docker(三):项目部署与 Docker Compose 编排

作者
  • 姓名
    社交账号

本篇学习范围

单个 MySQL 或 Nginx 容器并不难。真正部署一个项目时,数据库、后端、前端,甚至 Redis、消息队列和多个业务服务都需要一起启动、连到正确网络、挂载正确目录。

课件的项目部署部分围绕 tlias 示例展开,本篇把它提炼成可复用的顺序:

准备数据库和网络
打包 Java 服务、构建镜像、运行后端
挂载静态资源和 nginx.conf,运行前端
把分散的 docker run 转成 docker-compose.yml
用 docker compose 统一启动、查看和停止项目

这里的 tlias、路径和镜像名是课程示例。实际项目需要替换为自己的应用名、配置和版本。


先理解手动多容器部署为何难维护

课件的服务拓扑列出了:

mysql、mq、redis、admin-server、order-server、tlias-server、nginx

如果每个服务都手工执行一条长 docker run,就要分别处理:

  • 镜像版本;
  • 容器名称;
  • 端口映射;
  • 数据卷或本地目录;
  • 自定义网络;
  • 启动顺序;
  • 日志、停止与重启。

服务数量一多,参数很容易不一致,也不便于在另一台机器重建同样的环境。Docker Compose 用一个 YAML 文件把这些容器定义为同一个项目,正是为了解决这种“手动部署繁琐、不便于统一管理”的问题。


服务端部署:从数据库准备到 Java 容器

课件给出的后端部署顺序如下。

1. 先准备 MySQL 与业务库

先创建并启动 MySQL 容器,准备 tlias 数据库和表结构。若 Java 服务和 MySQL 都在同一个自定义网络,后端连接地址应使用数据库容器名或 Compose 服务名,例如 mysql,而不是硬编码宿主机 IP。

docker network create itheima

docker run -d \
  --name mysql \
  --network itheima \
  -e TZ=Asia/Shanghai \
  -e MYSQL_ROOT_PASSWORD='请替换为强随机密码' \
  -v /root/mysql/data:/var/lib/mysql \
  -v /root/mysql/init:/docker-entrypoint-initdb.d \
  -v /root/mysql/conf:/etc/mysql/conf.d \
  mysql:8

如果 tlias.sql 放入 /root/mysql/init,官方 MySQL 镜像会在空数据目录第一次初始化时执行它。已有数据目录不会因为重启容器或更改环境变量而重新执行初始化脚本。

2. 修改应用的部署配置

课件要求在打包前修改两类配置:

配置项原因
数据库服务地址容器内部的 localhost 只指向当前 Java 容器,不指向 MySQL 容器;同网络中应写 MySQL 服务名。
logback 日志文件目录容器文件系统不是长期日志存储位置,应选择可挂载、可收集且拥有写权限的目录。

不要把数据库密码、密钥或生产日志路径直接硬编码到 Dockerfile 或镜像中。课程中用配置文件演示位置变更,真实环境建议按配置中心、环境变量、受控 env 文件或 secret 的方式分离敏感值。

3. 打 Jar、编写 Dockerfile、构建镜像

准备资源时,课件列出了:

服务端 JDK 17、应用 Jar、Dockerfile

Dockerfile 可以使用上一篇的 JDK + Jar 示例。构建时用小写镜像名:

docker build -t tlias-server:1.0 .

最后的 . 是 build context。COPY app.jar app.jar 所需的 Jar、JDK 压缩包和 Dockerfile 都必须位于这个上下文可见的范围内。应使用 .dockerignore 排除日志、IDE 文件、密钥和不必要构建产物。

4. 运行后端容器

假设应用监听 8080:

docker run -d \
  --name tlias-server \
  --network itheima \
  -p 8080:8080 \
  tlias-server:1.0

端口 8080 是否需要发布到宿主机,取决于是否有宿主机外部客户端直接访问它。若只由同网络中的 Nginx 反向代理访问,通常不必对外发布后端端口;课件这一层重点是“服务通过自定义网络与名称相连”,不是机械给每个服务添加 -p


前端部署:Nginx、静态资源与配置文件挂载

课件要求创建一个新的 Nginx 容器,并以本地目录挂载方式部署前端项目。两条挂载必须分别保留:

-v /root/tlias-nginx/html:/usr/share/nginx/html
-v /root/tlias-nginx/conf/nginx.conf:/etc/nginx/nginx.conf
挂载作用
/root/tlias-nginx/html:/usr/share/nginx/html将前端打包后的静态资源提供给 Nginx。
/root/tlias-nginx/conf/nginx.conf:/etc/nginx/nginx.conf用宿主机准备好的 Nginx 主配置覆盖容器默认配置。

在启动前,确保源目录存在、nginx.conf 是文件而不是目录、静态资源已放进 html

mkdir -p /root/tlias-nginx/html
mkdir -p /root/tlias-nginx/conf
test -f /root/tlias-nginx/conf/nginx.conf

然后运行:

docker run -d \
  --name nginx-tlias \
  --network itheima \
  -p 80:80 \
  -v /root/tlias-nginx/html:/usr/share/nginx/html \
  -v /root/tlias-nginx/conf/nginx.conf:/etc/nginx/nginx.conf \
  nginx:1.20.2

课件强调的本地目录规则仍然适用:/root/.../ 开始,所以是 bind mount;若误写成 html:/usr/share/nginx/html,Docker 会把 html 当作命名卷。

配置文件本身常包含反向代理、SPA 回退或静态缓存规则。若 Nginx 要代理同一 Docker 网络中的 Java 服务,可以使用 tlias-server 作为上游主机名。不要在 Nginx 配置中固化可能变化的容器 IP。


Docker Compose:用 YAML 定义一个多容器项目

Docker Compose 通过一个 Compose 文件定义一组关联服务。课件使用文件名:

docker-compose.yml

当前 Compose V2 的命令是:

docker compose

中间有空格。不要把它和旧的 docker-compose 独立二进制命令混写。

Project 与 Service

课件的关系是:

一个 Project
  └── 一个 docker-compose.yml
        ├── Service A
        ├── Service B
        └── Service C

每个 service 描述一个容器化应用。Compose 会为同一项目创建并管理相关容器、网络和其他资源。只要服务处于同一 Compose 项目的默认网络,通常就可通过 service 名互相解析,因此不必手工为每个容器重复创建网络。


docker run 翻译成 Compose 配置

课件给出了一条 Nginx 的 docker run

docker run -d \
  --name nginx-tlias \
  -v /usr/local/app/html:/usr/share/nginx/html \
  -v /usr/local/app/conf/nginx.conf:/etc/nginx/nginx.conf \
  --network itheima \
  -p 80:80 \
  nginx:1.20.2

它和 Compose YAML 字段的一一对应关系:

docker run 参数Compose 字段
--name nginx-tliascontainer_name: nginx-tlias
nginx:1.20.2image: nginx:1.20.2
每个 -vvolumes 列表的一项
--network itheima服务的 networks 列表和顶层网络定义
-p 80:80ports: ["80:80"]

对应的 YAML。YAML 缩进有语义,不能随意对齐:

services:
  nginx-tlias:
    image: 'nginx:1.20.2'
    container_name: nginx-tlias
    volumes:
      - '/usr/local/app/html:/usr/share/nginx/html'
      - '/usr/local/app/conf/nginx.conf:/etc/nginx/nginx.conf'
    networks:
      - itheima
    ports:
      - '80:80'

networks:
  itheima:
    name: itheima

课件的多行 docker run 截图中,第二个挂载行的反斜杠后有空格。Shell 的行续接要求反斜杠是该行最后一个字符,因此正文已改为规范格式。

container_name 能让课程示例名称固定,但会限制 Compose 的横向扩容。需要多个副本的服务通常让 Compose 自动命名容器,并通过 service 名发现彼此。


Compose 项目资源与整体部署步骤

课件中基于 Compose 快速部署 tlias 系统前,需要准备:

类别资源
数据库tlias.sql
服务端JDK 17、Jar 包、Dockerfile。
前端打包后的静态文件、nginx.conf
编排docker-compose.yml

推荐按下面顺序落地:

  1. 准备目录和配置,确认宿主机的 bind mount 源目录、文件类型和权限正确;
  2. 编写后端 Dockerfile,并构建或在 Compose 中声明 build;
  3. 在 Compose 文件中定义 MySQL、后端和 Nginx 服务及其挂载、网络和端口;
  4. 校验 YAML 缩进、镜像标签、数据库服务名和环境变量来源;
  5. 启动后先看 docker compose ps,再看 docker compose logs,最后访问前端和后端接口。

多服务项目中,“容器已经启动”不代表数据库已经可以接受连接。生产部署还应考虑 healthcheck、重试逻辑、restart policy 和备份策略。depends_on 只能表达启动顺序,不能自动替代服务就绪检查。


docker compose 命令

课件给出的总格式:

docker compose [OPTIONS] [COMMAND]

常用全局选项:

选项作用示例
-f指定 Compose 文件路径与名称docker compose -f deploy/docker-compose.yml up
-p指定项目名docker compose -p tlias up

常用命令:

命令作用常见写法
up创建并启动所有 service 容器docker compose up -d
down停止并移除本项目容器与网络docker compose down
ps列出项目启动的容器docker compose ps
logs查看指定服务日志docker compose logs 服务名
stop停止容器docker compose stop
start启动已停止容器docker compose start
restart重启容器docker compose restart
top查看服务容器中运行的进程docker compose top

最常用的启动与排错组合:

# 使用默认 docker-compose.yml,在后台创建并启动
docker compose up -d

# 指定文件和项目名
docker compose -f deploy/docker-compose.yml -p tlias up -d

# 查看容器状态与实时日志
docker compose ps
docker compose logs -f tlias-server

# 停止并移除项目容器与网络
docker compose down

不加 -ddocker compose up 会把日志附着到当前终端;按 Ctrl + C 会停止服务。docker compose down 默认不会删除命名数据卷,带 -v 时才会删除相关命名卷和匿名卷,因此包含数据库数据的项目必须确认备份和影响范围后再使用:

docker compose down -v

本篇命令清单

# 后端与前端容器
docker build -t tlias-server:1.0 .
docker run -d --name tlias-server --network itheima -p 8080:8080 tlias-server:1.0
docker run -d --name nginx-tlias --network itheima -p 80:80 \
  -v /root/tlias-nginx/html:/usr/share/nginx/html \
  -v /root/tlias-nginx/conf/nginx.conf:/etc/nginx/nginx.conf \
  nginx:1.20.2

# Compose
docker compose -f docker-compose.yml -p 项目名 up -d
docker compose down
docker compose ps
docker compose logs 服务名
docker compose logs -f 服务名
docker compose stop
docker compose start
docker compose restart
docker compose top

Docker Compose 的当前选项和子命令可查阅 Compose 官方参考。三篇文章至此覆盖了课件的讲授内容;重复目录页、空白页和两道课后练习没有单独展开。