容器化部署 Tomcat + MySQL 实战指南:从入门到进阶

🌟 背景与目标

在现代软件开发中,容器化部署 已成为主流方式。通过 Docker 部署 Tomcat 和 MySQL,可以实现快速构建、部署、调试和维护。本文将从最基础的镜像构建开始,逐步深入到数据持久化、配置热更新、日志管理、多服务编排 等进阶主题,并对比不同部署方案的优劣,帮助您构建一套可维护、可扩展、可复制的容器化部署方案。

🧱 第一:基础部署 ------ 构建自定义zprint_tomcat镜像

1. 创建zprint-tomcat镜像构建目录结构

bash 复制代码
zprint-tomcat/
├── Dockerfile
├── webapps/
│   └── ROOT  # 本应用目录为ROOT, 如果为app.WAR 会自动解压被tomcat 加载
├── conf/
│   └── server.xml
├── logs/
└── temp/

2. 编写 Dockerfile(zprint_Tomcat)

dockerfile

bash 复制代码
# 使用官方 Tomcat 8.5 作为基础镜像
FROM tomcat:8.5
# 设置环境变量(时区)
ENV TZ=Asia/Shanghai
# 创建 webapps 目录
RUN mkdir -p /usr/local/tomcat/webapps
# 拷贝您的应用到镜像中
COPY webapps/ /usr/local/tomcat/webapps/
# 拷贝自定义 server.xml(可选)
COPY conf/server.xml /usr/local/tomcat/conf/
# 暴露端口
EXPOSE 8099

3. 构建并推送zprint_tomcat镜像到阿里云

bash 复制代码
#!/bin/bash

# 构建自定义 Tomcat 镜像使用,如果使用已有镜像只需要允许zprint.yaml dockercompse这个文件即可自动组织zprint_mysql+zprint_tomcat容器允许
DOCKER_IMAGE_NAME=crpi-61kqwp5ugch8hao1.cn-hangzhou.personal.cr.aliyuncs.com/ylzzone/zprint_tomcat:8.5
# 构建镜像
docker build -t $DOCKER_IMAGE_NAME .

# 添加远程仓库标签
docker tag $DOCKER_IMAGE_NAME crpi-61kqwp5ugch8hao1.cn-hangzhou.personal.cr.aliyuncs.com/ylzzone/zprint_tomcat:8.5

# 登录阿里云私有仓库(如需推送)
echo "请手动执行登录(如需推送):"
echo "docker login --username=ailiylz crpi-61kqwp5ugch8hao1.cn-hangzhou.personal.cr.aliyuncs.com"

echo "构建完成。如需推送,请执行:"
echo "docker push crpi-61kqwp5ugch8hao1.cn-hangzhou.personal.cr.aliyuncs.com/ylzzone/zprint_tomcat:8.5"

🧱 第二层:基础部署 ------ 构建自定义zprint_mysql镜像

1. 创建zprint-tomcat镜像构建目录结构

bash 复制代码
zprint-mysql/
├── Dockerfile
├── conf.d/
│   └── custom.cnf
└── schema/
    ├── zprint_Schema.sql  <- 数据库结构初始化脚本
    └── zprint_Data.sql    <- 数据初始化脚本

2. 编写 Dockerfile(zprint_mysql)

bash 复制代码
# 使用基础 MySQL 5.7 镜像
FROM mysql:5.7
# 设置时区
ENV TZ=Asia/Shanghai
# 拷贝初始化脚本(容器启动时自动执行)
COPY schema/*.sql /docker-entrypoint-initdb.d/
# 拷贝自定义配置文件
COPY conf.d/custom.cnf /etc/mysql/conf.d/
# 设置工作目录
WORKDIR /usr/local/mysql

3. 构建并推送zprint_mysql镜像到阿里云

bash 复制代码
#!/bin/bash

# 构建自定义 Tomcat 镜像使用,如果使用已有镜像只需要允许zprint.yaml dockercompse这个文件即可自动组织zprint_mysql+zprint_tomcat容器允许
DOCKER_IMAGE_NAME=crpi-61kqwp5ugch8hao1.cn-hangzhou.personal.cr.aliyuncs.com/ylzzone/zprint_mysql:5.7
# 构建镜像
docker build -t $DOCKER_IMAGE_NAME .
# 添加远程仓库标签
docker tag $DOCKER_IMAGE_NAME crpi-61kqwp5ugch8hao1.cn-hangzhou.personal.cr.aliyuncs.com/ylzzone/zprint_mysql:5.7
# 登录阿里云私有仓库(如需推送)
echo "请手动执行登录(如需推送):"
echo "docker login --username=ailiylz crpi-61kqwp5ugch8hao1.cn-hangzhou.personal.cr.aliyuncs.com"
echo "构建完成。如需推送,请执行:"
echo "docker push crpi-61kqwp5ugch8hao1.cn-hangzhou.personal.cr.aliyuncs.com/ylzzone/zprint_mysql:5.7"

🧩 第三:服务编排 ------ 使用 zprint.yaml

🛠 示例 zprint.yaml 文件方式持久化

bash 复制代码
# 以文件方式挂载持久化
version: '3.8'

services:
  mysql:
    image: crpi-61kqwp5ugch8hao1.cn-hangzhou.personal.cr.aliyuncs.com/ylzzone/zprint-mysql:5.7
    container_name: zprint_db
    environment:
      TZ: Asia/Shanghai
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: zprint_db
      MYSQL_USER: Faurecia
      MYSQL_PASSWORD: 1qaz2wsx
    ports:
      - "33306:3306"
    volumes:
      - ./mysql_data:/var/lib/mysql
      - ./mysql_data:/etc/mysql/conf.d/
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 3s
      retries: 3
    networks:
      - zprint_net

  tomcat:
    image: crpi-61kqwp5ugch8hao1.cn-hangzhou.personal.cr.aliyuncs.com/ylzzone/zprint-tomcat:8.5
    container_name: zprint
    ports:
      - "8099:8099"
    environment:
      TZ: Asia/Shanghai
      LANG: C.UTF-8
      LC_ALL: C.UTF-8
    depends_on:
      mysql:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8099"]
      interval: 30s
      timeout: 10s
      retries: 5
    volumes:
      - ./tomcat_conf:/usr/local/tomcat/conf
      - ./tomcat_webapps:/usr/local/tomcat/webapps
      - ./tomcat_logs:/usr/local/tomcat/logs
      - ./tomcat_temp:/usr/local/tomcat/temp
    networks:
      - zprint_net

networks:
  zprint_net:
    driver: bridge

🛠 示例二 zprint.yaml 卷volumes方式持久化

bash 复制代码
# 已挂载卷方式持久化
services:
  mysql:
    image: crpi-61kqwp5ugch8hao1.cn-hangzhou.personal.cr.aliyuncs.com/ylzzone/zprint-mysql:5.7
    container_name: zprint_db
    environment:
      TZ: Asia/Shanghai
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: zprint_db
      MYSQL_USER: Faurecia
      MYSQL_PASSWORD: 1qaz2wsx
    ports:
      - "33306:3306"
    volumes:
      - zprint_mysql_data:/var/lib/mysql
      - zprint_mysql_conf:/etc/mysql/conf.d/
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 3s
      retries: 3
    networks:
      - zprint_net

  tomcat:
    image: crpi-61kqwp5ugch8hao1.cn-hangzhou.personal.cr.aliyuncs.com/ylzzone/zprint-tomcat:8.5
    container_name: zprint
    ports:
      - "8099:8099"
    environment:
      TZ: Asia/Shanghai
      LANG: C.UTF-8
      LC_ALL: C.UTF-8
    depends_on:
      mysql:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8099"]
      interval: 30s
      timeout: 10s
      retries: 5
    volumes:
      - zprint_tomcat_conf:/usr/local/tomcat/conf
      - zprint_tomcat_webapps:/usr/local/tomcat/webapps
      - zprint_tomcat_logs:/usr/local/tomcat/logs
      - zprint_tomcat_temp:/usr/local/tomcat/temp
    networks:
      - zprint_net

volumes:
  zprint_mysql_conf:
  zprint_mysql_data:
  zprint_tomcat_conf:
  zprint_tomcat_webapps:
  zprint_tomcat_logs:
  zprint_tomcat_temp:

networks:
  zprint_net:
    driver: bridge

🧪 启动和关闭服务

bash 复制代码
#"-d"参数表示在后台运行(daemon模式)
"up"命令会创建并启动容器
"down"命令会停止并移除容器、网络等资源
执行命令前确保在包含yaml文件的目录下
# bash
docker-compose -f zprint.yaml up -d # 
docker-compose -f zpirnt.yaml down  
# 使用默认的docker-compose.yaml文件
docker-compose up -d  # 启动
docker-compose down   # 停止

📦 第四:数据持久化与配置热更新

🧾 1. 命名卷 vs 绑定挂载 ------ 对比与选择

|----------|--------------------------------------------|-------------------------------|
| 对比项 | 命名卷 (Named Volume) | 绑定挂载 (Bind Mount) |
| 定义方式 | tomcat_logs:/usr/local/tomcat/logs | ./logs:/usr/local/tomcat/logs |
| 存储位置 | Docker 自动管理(如 /var/lib/docker/volumes/...) | 手动指定宿主机目录(如 ./logs) |
| 是否可见 | ❌ 不可见,需用 docker volume inspect 查看 | ✅ 可见,直接在宿主机上查看 |
| 是否便于维护 | ✅ 是,Docker 自动管理权限、生命周期等 | ⚠️ 否,需手动创建、维护目录 |
| 是否适合团队协作 | ✅ 是,不依赖本地路径结构 | ❌ 否,路径可能因人而异 |
| 是否推荐用于生产 | ✅ 是 | ⚠️ 否 |

2. centos 下命名卷挂载路径/var/lib/docker/volumes

4. ‌**推荐使用命名卷的场景:**‌

  • 多容器数据共享 ‌:如共享数据库或配置,命名卷允许跨容器访问同一数据源,支持 --volumes-from 继承配置,适合微服务架构‌。
  • 生产环境持久化存储‌:Docker 管理卷数据,独立于容器生命周期,删除容器后数据保留,适合关键业务数据(如数据库文件)‌。
  • 数据备份与迁移 ‌:卷存储在 Docker 托管目录(/var/lib/docker/volumes/),便于跨主机迁移或备份,避免依赖宿主机路径差异‌。
  • 高性能需求场景‌:在高并发或 I/O 密集型应用中,命名卷比绑定挂载性能更优,减少文件系统开销‌。

‌5.**推荐使用绑定挂载的场景:**‌

  • 开发与测试环境‌:实时同步宿主机代码到容器(如本地源码挂载到容器 Web 目录),支持热更新,无需重建镜像‌。
  • 访问宿主机特定文件 ‌:直接挂载主机配置文件(如 /etc/app/config)或日志目录(/var/log),容器可直接读写宿主机资源‌。
  • 简单数据共享‌:快速共享宿主机目录(如日志或临时数据),无需创建卷,适用于单次任务或调试。
  • 主机依赖型应用‌:当应用需强绑定宿主机文件系统结构时(如使用绝对路径的脚本),优先绑定挂载‌。

🧪 第五、容器常用命令及操作案例

|------------|------------------------------------------------------|
| 操作 | 命令 |
| 启动服务 | docker-compose -f docker-compose.yaml up -d |
| 停止服务 | docker-compose -f docker-compose.yaml stop |
| 重启 Tomcat | docker-compose -f docker-compose.yaml restart tomcat |
| 查看日志 | docker logs zprint |
| 进入容器调试 | docker exec -it zprint /bin/bash |
| 删除容器(保留数据) | docker-compose -f docker-compose.yaml down |

1. docker image 命令管理实例

bash 复制代码
[root@localhost ~]# docker image rm f41e0c55a09a
Untagged: crpi-61kqwp5ugch8hao1.cn-hangzhou.personal.cr.aliyuncs.com/ylzzone/zprint_tomcat:8.5
Untagged: crpi-61kqwp5ugch8hao1.cn-hangzhou.personal.cr.aliyuncs.com/ylzzone/zprint_tomcat@sha256:61a3748e8be4d27edb1a45a707bbad32cda9679773397db0fa79c828d4af0eee
Deleted: sha256:f41e0c55a09afa83a366e5292df4b980d833b7415dba37ea4f50d1b95e07e581
[root@localhost ~]# docker image ls
REPOSITORY                                                                        TAG             IMAGE ID       CREATED         SIZE
crpi-61kqwp5ugch8hao1.cn-hangzhou.personal.cr.aliyuncs.com/ylzzone/zprint_mysql   5.7             3fae0828f4b4   4 days ago      507MB
mysql                                                                             8.0             12a2ae8fe734   3 months ago    772MB
hello-world                                                                       latest          74cc54e27dc4   6 months ago    10.1kB
dpanel/dpanel                                                                     lite            6f81b76efea8   8 months ago    159MB
tomcat                                                                            8.5             0a2249be3d31   16 months ago   456MB
mysql                                                                             5.7             5107333e08a8   19 months ago   501MB
registry.cn-beijing.aliyuncs.com/dc3/iot-dc3-web                                  2023.4.0.demo   4f9cdb8a7a03   2 years ago     22.1MB
registry.cn-beijing.aliyuncs.com/dc3/dc3-mysql                                    2023.4.0.demo   ac415318842e   2 years ago     449MB
registry.cn-beijing.aliyuncs.com/dc3/dc3-gateway                                  2023.4.0.demo   7ca89202d3bc   2 years ago     244MB
registry.cn-beijing.aliyuncs.com/dc3/dc3-center-manager                           2023.4.0.demo   87a93b5cacf1   2 years ago     241MB
registry.cn-beijing.aliyuncs.com/dc3/dc3-center-data                              2023.4.0.demo   02507a999618   2 years ago     253MB
registry.cn-beijing.aliyuncs.com/dc3/dc3-center-auth                              2023.4.0.demo   37b010ca4c2f   2 years ago     239MB
registry.cn-beijing.aliyuncs.com/dc3/dc3-driver-virtual                           2023.4.0.demo   3ae832335eef   2 years ago     185MB
registry.cn-beijing.aliyuncs.com/dc3/dc3-mongo                                    2023.4.0.demo   61fa1629960b   2 years ago     736MB
registry.cn-beijing.aliyuncs.com/dc3/dc3-rabbitmq                                 2023.4.0.demo   3f30ca529949   2 years ago     108MB
registry.cn-beijing.aliyuncs.com/dc3/dc3-redis                                    2023.4.0.demo   0fafd8a3e04c   2 years ago     32.5MB
registry.cn-beijing.aliyuncs.com/dc3/dc3-center-register                          2023.4.0.demo   880a539df928   2 years ago     544MB
crpi-61kqwp5ugch8hao1.cn-hangzhou.personal.cr.aliyuncs.com/ylzzone/mydockerdemo   latest          97f57120105e   2 years ago     341MB

2. 镜像创建过程实例

bash 复制代码
[root@localhost ~]# cd /app/zprint-tomcat/
[root@localhost zprint-tomcat]# ls
conf  Dockerfile  logs  temp  webapps  zprint_tomcat_build.sh
[root@localhost zprint-tomcat]# sh zprint_tomcat_build.sh
[+] Building 7.3s (9/9) FINISHED                                                                                                                 docker:default
 => [internal] load build definition from Dockerfile                                                                                                       0.0s
 => => transferring dockerfile: 424B                                                                                                                       0.0s
 => [internal] load .dockerignore                                                                                                                          0.0s
 => => transferring context: 2B                                                                                                                            0.0s
 => [internal] load metadata for docker.io/library/tomcat:8.5                                                                                              0.0s
 => [1/4] FROM docker.io/library/tomcat:8.5                                                                                                                0.0s
 => [internal] load build context                                                                                                                          7.2s
 => => transferring context: 76.69MB                                                                                                                       7.0s
 => CACHED [2/4] RUN mkdir -p /usr/local/tomcat/webapps                                                                                                    0.0s
 => CACHED [3/4] COPY webapps/ /usr/local/tomcat/webapps/                                                                                                  0.0s
 => CACHED [4/4] COPY conf/server.xml /usr/local/tomcat/conf/                                                                                              0.0s
 => exporting to image                                                                                                                                     0.0s
 => => exporting layers                                                                                                                                    0.0s
 => => writing image sha256:20a4645b4bbe1445284b10730bcbf5fbc6aa94aae8a7951b3f253a8deb60e114                                                               0.0s
 => => naming to crpi-61kqwp5ugch8hao1.cn-hangzhou.personal.cr.aliyuncs.com/ylzzone/zprint_tomcat:8.5                                                      0.0s
请手动执行登录(如需推送):
docker login --username=ailiylz crpi-61kqwp5ugch8hao1.cn-hangzhou.personal.cr.aliyuncs.com
构建完成。如需推送,请执行:
docker push crpi-61kqwp5ugch8hao1.cn-hangzhou.personal.cr.aliyuncs.com/ylzzone/zprint_tomcat:8.5
[root@localhost zprint-tomcat]# docker login --username=ailiylz crpi-61kqwp5ugch8hao1.cn-hangzhou.personal.cr.aliyuncs.com
Password:
Error response from daemon: Get "https://crpi-61kqwp5ugch8hao1.cn-hangzhou.personal.cr.aliyuncs.com/v2/": Get "https://dockerauth.cn-hangzhou.aliyuncs.com/auth?account=ailiylz&client_id=docker&offline_token=true&service=registry.aliyuncs.com%3Acn-hangzhou%3A26842": read tcp 192.168.1.199:53244->120.55.35.37:443: read: connection reset by peer
[root@localhost zprint-tomcat]# docker login --username=ailiylz crpi-61kqwp5ugch8hao1.cn-hangzhou.personal.cr.aliyuncs.com
Password:
Error response from daemon: Get "https://crpi-61kqwp5ugch8hao1.cn-hangzhou.personal.cr.aliyuncs.com/v2/": Get "https://dockerauth.cn-hangzhou.aliyuncs.com/auth?account=ailiylz&client_id=docker&offline_token=true&service=registry.aliyuncs.com%3Acn-hangzhou%3A26842": read tcp 192.168.1.199:35932->120.55.35.34:443: read: connection reset by peer
[root@localhost zprint-tomcat]# docker login --username=ailiylz crpi-61kqwp5ugch8hao1.cn-hangzhou.personal.cr.aliyuncs.com
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded
[root@localhost zprint-tomcat]# ^C
[root@localhost zprint-tomcat]# docker push crpi-61kqwp5ugch8hao1.cn-hangzhou.personal.cr.aliyuncs.com/ylzzone/zprint_tomcat:8.5
The push refers to repository [crpi-61kqwp5ugch8hao1.cn-hangzhou.personal.cr.aliyuncs.com/ylzzone/zprint_tomcat]
24fc90e0759b: Layer already exists
acc82c5341a3: Layer already exists
5f70bf18a086: Pushed
2a0c096d3062: Layer already exists
fb0f37a0ea02: Layer already exists
02a99687e95e: Layer already exists
3e75af8aba85: Layer already exists
c2ef3e72aded: Layer already exists
d5a8ba654b65: Layer already exists
17031737aa00: Layer already exists
5498e8c22f69: Layer already exists
8.5: digest: sha256:4aaab71ca074a0f1266b0c646cd178923bf6eb00ae46caea73ec60441063c11b size: 2621
[root@localhost zprint-tomcat]#

3.docker-compse 容器管理实例

bash 复制代码
Last login: Mon Jul 21 16:14:42 2025 from 192.168.1.120
[root@localhost ~]# cd /app/zprint_test/
[root@localhost zprint_test]# ls
zprint.yaml

[root@localhost zprint_test]# docker-compose -f zprint.yaml up -d
[+] Running 4/4
 ✔ Network zprint_test_zprint_net              Created                                                                                                     0.1s
 ✔ Volume "zprint_test_zprint_tomcat_webapps"  Created                                                                                                     0.0s
 ✔ Container zprint_db                         Healthy                                                                                                     0.3s
 ✔ Container zprint_tomcat                     Started                                                                                                    12.0s
[root@localhost zprint_test]# docker-compose -f zprint.yaml down
[+] Running 3/3
 ✔ Container zprint_tomcat         Removed                                                                                                                 0.4s
 ✔ Container zprint_db             Removed                                                                                                                 1.3s
 ✔ Network zprint_test_zprint_net  Removed                                                                                                                 0.1s
[root@localhost zprint_test]# docker-compose -f zprint.yaml up -d
[+] Running 5/5
 ✔ Network zprint_test_zprint_net              Created                                                                                                     0.1s
 ✔ Volume "zprint_test_zprint_tomcat_conf"     Created                                                                                                     0.0s
 ✔ Volume "zprint_test_zprint_tomcat_webapps"  Created                                                                                                     0.0s
 ✔ Container zprint_db                         Healthy                                                                                                     0.0s
 ✔ Container zprint_tomcat                     Started                                                                                                     5.0s

4. 镜像离线传输tag 重新加载等操作

|---------------|---------------------------------------------------|
| 操作 | 命令 |
| 📦 打包镜像为 .tar | docker save -o <output_file.tar> <image_name> |
| 📤 加载镜像 | docker load -i <input_file.tar> |
| 📋 查看镜像列表 | docker images |
| 📦 查看 tar 包内容 | tar tf <file.tar> |

bash 复制代码
# 📦 打包镜像为 .tar 文件
docker save -o zprint-mysql.tar cn-hangzhou.personal.cr.aliyuncs.com/ylzzone/zprint-mysql:5.7
docker save -o zprint-tomcat.tar cn-hangzhou.personal.cr.aliyuncs.com/ylzzone/zprint-tomcat:8.5
# 这会将两个镜像分别保存为:
zprint-mysql.tar
zprint-tomcat.tar
# 重新加载
docker load -i zprint-mysql.tar
docker load -i zprint-tomcat.tar
--------------------------------------------------
# ⚠️ 不建议手动解压镜像文件,Docker 镜像是分层结构,手动解压无法还原完整镜像。
tar tf zprint-mysql.tar
# 输出示例:
./
./manifest.json
./config.json
./layer.tar
...
------------------------------------------------
# 🧪 更好建议 打包并压缩镜像(节省空间)
docker save cn-hangzhou.personal.cr.aliyuncs.com/ylzzone/zprint-mysql:5.7 | gzip > zprint-mysql.tar.gz
docker save cn-hangzhou.personal.cr.aliyuncs.com/ylzzone/zprint-tomcat:8.5 | gzip > zprint-tomcat.tar.gz

# 解压和重新加载
gunzip -c zprint-mysql.tar.gz | docker load
gunzip -c zprint-tomcat.tar.gz | docker load

🚨 第六:容器化部署 Tomcat + MySQL 常见易错点汇总

以下是我们沟通中总结的最容易出错的点,按类别分类整理,帮助您避免"踩坑"。


📁 1. 目录结构与挂载问题

错误点 描述 解决方案
📁 挂载路径错误 容器路径与宿主机路径不一致,导致配置或应用未生效 确保 volumes: 中路径匹配,如 - zprint_tomcat_webapps:/usr/local/tomcat/webapps
📁 webapps/ROOT/ 目录结构错误 应用文件不在正确路径下,导致 404 检查 /usr/local/tomcat/webapps/ROOT/ 下是否有 index.jsp
📁 WAR 包未解压 server.xmlunpackWARs="false" 导致 WAR 包未展开 修改为 true,并重启容器
📁 挂载卷未初始化 命名卷首次运行时未自动填充内容 使用绑定挂载或在构建镜像时复制内容进去
📁 挂载权限问题 宿主机文件权限导致 Tomcat 无法读取 使用 chmodchown 修改权限

⚙️ 2. 配置文件问题

错误点 描述 解决方案
📄 server.xml 配置错误 HostContext 配置不正确,导致应用未加载 确保 HostappBase="webapps"unpackWARs="true"
📄 web.xml 缺失或错误 导致 JSP 页面无法加载或 404 确保 WEB-INF/web.xml 存在且配置正确
📄 jdbc.properties 配置错误 数据库连接失败,导致页面空白或 500 错误 检查 jdbc.properties 中的 URL、用户名、密码
📄 context.xml 配置缺失 导致 JNDI 数据源未正确加载 添加 context.xml 配置文件
📄 server.xml 中未配置 Context 导致应用未自动加载 添加 <Context path="" docBase="ROOT" reloadable="false"/>

🧱 3. 镜像构建问题

错误点 描述 解决方案
📦 文件未正确复制到镜像中 构建时未复制 webapps/, conf/ 等目录 检查 Dockerfile 中的 COPY 指令
📦 构建后未推送镜像 本地构建后未 docker push,导致其他机器无法拉取 构建完成后执行 docker push
📦 镜像版本未更新 使用旧版本镜像,未生效新配置 明确指定镜像版本(如 :8.5
📦 镜像未包含依赖库 缺少 lib/*.jar,导致 JSP 编译失败 确保构建时复制所有依赖文件
📦 Dockerfile 未设置工作目录 导致文件复制路径错误 添加 WORKDIR /app 等指令确保路径正确

🧩 4. docker-compose 编排问题

错误点 描述 解决方案
🔄 服务启动顺序错误 Tomcat 启动时 MySQL 未就绪 使用 depends_on + condition: service_healthy
🔁 服务重启后数据丢失 未使用命名卷或绑定挂载 添加 volumes: 挂载数据目录
📦 镜像地址错误 使用了错误的镜像名或仓库地址 检查 image: 字段是否与推送镜像一致
📦 服务名错误 depends_on 中服务名拼写错误 检查服务名与 services: 中一致
📦 网络配置缺失 服务间无法通信 使用 networks: 定义共享网络

📁 5. 命名卷 vs 绑定挂载混淆

错误点 描述 解决方案
🧾 使用命名卷但未初始化数据 容器内无内容,导致应用未加载 使用绑定挂载或在构建时复制内容
🧾 使用绑定挂载路径错误 宿主机路径不存在或未正确映射 确保路径存在且映射正确
🧾 混合使用两种方式导致混乱 本地修改未生效 选择一种方式并统一使用
🧾 容器中路径与挂载路径不一致 导致配置未覆盖 确保挂载路径与容器路径一致,如 /usr/local/tomcat/conf
🧾 未查看卷实际路径 无法定位日志或配置文件 使用 docker volume inspect 查看实际路径

📊 6. 日志与调试问题

错误点 描述 解决方案
📝 日志未持久化 容器删除后日志丢失 使用 volumes: 挂载日志目录
📝 日志路径错误 查看日志时路径错误 检查容器内路径 /usr/local/tomcat/logs/
📝 未查看 Tomcat 日志 不知道应用启动失败原因 查看 catalina.outlocalhost.log
📝 未查看 MySQL 日志 不知道数据库连接失败原因 查看 mysql 容器日志
📝 使用 docker logs 时未指定容器名 查看日志时混淆多个容器 使用 docker logs zprint 指定容器名

🧩 7. 网络与访问问题

错误点 描述 解决方案
🌐 端口未正确映射 外部无法访问 Tomcat 或 MySQL 检查 ports: 配置,如 "8099:8099"
🌐 容器间网络不通 Tomcat 无法连接 MySQL 使用 networks: 定义共享网络
🌐 使用错误的 IP 地址访问 使用了容器 IP 而非宿主机 IP 使用宿主机 IP 访问应用
🌐 使用错误的上下文路径访问 应用部署为 /ROOT,但访问 /app 确保访问路径为 http://ip:8099/
🌐 未等待健康检查完成 Tomcat 启动后立即访问,MySQL 未准备好 等待 healthcheck 成功后再访问

🧪 8. 数据库连接问题

错误点 描述 解决方案
📥 数据库未初始化 表不存在或数据未导入 使用 docker-entrypoint-initdb.d/ 初始化脚本
📥 数据库连接失败 用户名、密码、URL 错误 检查 jdbc.propertiescontext.xml
📥 数据库未持久化 容器删除后数据丢失 使用 volumes: 持久化 /var/lib/mysql
📥 数据库连接池配置错误 连接池超时、最大连接数限制 调整 maxActive, maxWait 等参数
📥 数据库未暴露端口 外部无法访问数据库 检查 ports: 配置 "33306:3306"

🧰 9. 命令执行问题

错误点 描述 解决方案
📝 未使用 -f 指定 compose 文件 默认使用 docker-compose.yml 使用 docker-compose -f zprint.yaml up -d
📝 未重启服务 修改配置后未重启容器 使用 docker-compose restart tomcat
📝 使用 docker run 替代 compose 导致配置复杂且易错 优先使用 docker-compose
📝 未清理缓存 旧容器数据影响新部署 使用 docker-compose down -v 清理卷
📝 未查看容器运行状态 不知道服务是否运行正常 使用 docker ps 查看容器状态

📋 总结表格:常见错误点汇总

类别 错误点 原因 解决方案
📁 目录结构 webapps/ROOT/ 不存在或内容错误 Tomcat 无法加载应用 确保目录结构正确
📁 挂载问题 挂载路径错误或权限问题 应用未加载 使用绑定挂载调试
⚙️ 配置文件 server.xmlweb.xml 配置错误 JSP 页面未加载 检查配置文件
🧱 镜像构建 未复制文件或镜像未更新 应用未生效 检查 Dockerfile 和镜像版本
🧩 Compose 编排 服务顺序错误、网络不通 数据库连接失败 使用 depends_on + healthcheck
📁 卷挂载 WAR 未解压、文件未生效 应用未加载 检查 server.xmlunpackWARs
📊 日志查看 未查看日志 无法定位问题 查看 catalina.outlocalhost.log
🌐 网络访问 端口未映射、上下文路径错误 无法访问页面 检查端口和访问路径
🧪 命令执行 未重启服务、未查看容器状态 不知道服务是否正常 使用 docker-compose restartdocker ps

📌第七:异常操作查询及脚本

1. 常用DOCKER 排错命令

bash 复制代码
# 确认服务是否运行正常
# bash
docker ps
#查看 Tomcat 日志
docker exec -it zprint cat /usr/local/tomcat/logs/catalina.out
#进入容器检查应用目录
docker exec -it zprint ls /usr/local/tomcat/webapps/ROOT
#检查数据库连接
docker exec -it zprint mysql -h mysql -u Faurecia -p -e "use zprint_db; show tables;"
#重启服务
docker-compose -f zprint.yaml restart tomcat

2. zprint-check.sh 脚本

复制代码
# zprint-check.sh
# !/bin/bash

# 设置颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color

# 检查 docker-compose 文件是否存在
if [ ! -f "docker-compose.yaml" ]; then
  echo -e "${RED}❌ docker-compose.yaml 文件不存在,请确保当前目录正确。${NC}"
  exit 1
fi

# 获取当前目录
CURRENT_DIR=$(pwd)

# 检查容器是否运行
check_container_status() {
  echo -e "${YELLOW}🔍 检查容器运行状态...${NC}"
  docker-compose -f docker-compose.yaml ps | grep -E "zprint|zprint_db" | awk '{print $1, $2, $3, $5}'
}

# 检查容器健康状态
check_health_status() {
  echo -e "${YELLOW}🧬 检查容器健康状态...${NC}"
  docker inspect zprint | grep -i "health" | grep -v "Healthcheck" | head -n 3
  docker inspect zprint_db | grep -i "health" | grep -v "Healthcheck" | head -n 3
}

# 检查挂载目录
check_mounted_dirs() {
  echo -e "${YELLOW}📁 检查挂载目录是否存在...${NC}"
  if [ -d "./tomcat_webapps/ROOT" ]; then
    echo -e "${GREEN}✅ webapps/ROOT 目录存在${NC}"
  else
    echo -e "${RED}❌ webapps/ROOT 目录不存在,请检查挂载配置${NC}"
  fi

  if [ -d "./tomcat_conf" ]; then
    echo -e "${GREEN}✅ tomcat_conf 目录存在${NC}"
  else
    echo -e "${RED}❌ tomcat_conf 目录不存在,请检查挂载配置${NC}"
  fi
}

# 检查 Tomcat 日志
check_tomcat_logs() {
  echo -e "${YELLOW}📄 检查 Tomcat 日志是否有错误...${NC}"
  if [ -f "./tomcat_logs/catalina.out" ]; then
    ERROR_COUNT=$(grep -c "ERROR\|SEVERE\|Exception" ./tomcat_logs/catalina.out)
    if [ $ERROR_COUNT -gt 0 ]; then
      echo -e "${RED}❌ 日志中发现 $ERROR_COUNT 个错误,请检查:${NC}"
      grep -A 5 -B 5 "ERROR\|SEVERE\|Exception" ./tomcat_logs/catalina.out | head -n 20
    else
      echo -e "${GREEN}✅ 日志中未发现严重错误${NC}"
    fi
  else
    echo -e "${RED}❌ catalina.out 日志文件不存在,请检查挂载是否正确${NC}"
  fi
}

# 检查数据库连接
check_database_connection() {
  echo -e "${YELLOW}🔌 检查数据库连接...${NC}"
  docker exec -it zprint_db mysql -u Faurecia -p1qaz2wsx -e "use zprint_db; show tables;" 2>/dev/null
  if [ $? -eq 0 ]; then
    echo -e "${GREEN}✅ 数据库连接正常,已找到表${NC}"
  else
    echo -e "${RED}❌ 数据库连接失败,请检查用户名/密码/网络配置${NC}"
  fi
}

# 检查应用是否加载
check_app_deployment() {
  echo -e "${YELLOW}📦 检查 Tomcat 是否加载应用...${NC}"
  docker exec -it zprint ls /usr/local/tomcat/webapps/ROOT/index.jsp 2>/dev/null
  if [ $? -eq 0 ]; then
    echo -e "${GREEN}✅ 应用文件存在,index.jsp 已加载${NC}"
  else
    echo -e "${RED}❌ 应用文件未找到,请检查挂载或 WAR 解压配置${NC}"
  fi

  docker exec -it zprint cat /usr/local/tomcat/logs/catalina.out | grep -i "deployed" | grep -q "ROOT"
  if [ $? -eq 0 ]; then
    echo -e "${GREEN}✅ 应用已成功部署${NC}"
  else
    echo -e "${RED}❌ 应用未部署,请检查 server.xml 或挂载配置${NC}"
  fi
}

# 检查服务访问
check_service_access() {
  echo -e "${YELLOW}🌐 检查服务访问...${NC}"
  curl -s -o /dev/null -w "%{http_code}" http://localhost:8099/
  HTTP_CODE=$?
  if [ $HTTP_CODE -eq 0 ]; then
    echo -e "${GREEN}✅ 服务已响应 HTTP 200 OK${NC}"
  else
    echo -e "${RED}❌ 服务返回错误,请检查 Tomcat 或网络配置${NC}"
  fi
}

# 执行检查
check_container_status
check_health_status
check_mounted_dirs
check_tomcat_logs
check_database_connection
check_app_deployment
check_service_access

echo -e "
${GREEN}✅ 检查完成!请根据上述信息判断问题所在。${NC}"
echo -e "💡 提示:如需进一步分析,请查看日志文件 ./tomcat_logs/catalina.out"
  1. 执行zprint-check.sh bash 命令
bash 复制代码
chmod +x c:\your .sh file absulutly path\Tomcat 8.5\zprint-check.sh

📌第八: 下一步建议

希望这篇博文对您有帮助!如需进一步定制或扩展,请随时告诉我。

  • 是否需要我帮您生成一键备份脚本?
  • 是否需要我优化日志轮转策略?
  • 是否需要我演示如何动态更新 JDBC 配置?
  • 本地开发调试
  • 快速修改配置文件或日志
  • 需要直接访问宿主机文件内容
  • 生产环境部署
  • 多人协作项目
  • 需要镜像+卷组合发布的场景
  • 实现日志、配置、临时文件的持久化
  • 支持本地修改配置文件后重启容器生效
  • 使用 docker-compose 启动 MySQL 和 Tomcat 容器
  • 设置依赖关系,确保启动顺序正确
  • 构建包含 Web 应用的 Tomcat 镜像
  • 构建包含初始化数据的 MySQL 镜像