ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

SSM应用Dockerfile容器化:生产级环境一致性实践

SSM应用Dockerfile容器化:生产级环境一致性实践 1. 项目概述为什么用 Dockerfile 打包 SSM 应用不是“多此一举”而是生产级落地的必经之路你手头有个基于 Spring SpringMVC MyBatisSSM的老牌 Java Web 项目可能是毕业设计、企业内部系统也可能是维护多年的后台管理平台。它跑在 Tomcat 8.5 上依赖 JDK 8数据库连着 MySQL 5.7配置文件散落在src/main/resources和web/WEB-INF/web.xml里部署时靠手动打 war 包、上传服务器、解压、改配置、重启 Tomcat——每次上线都像拆弹改一行配置就怕服务起不来。这时候有人告诉你“用 Docker 把它打包成镜像吧。”你第一反应可能是这玩意儿不就是个“高级压缩包”真有那么神其实Dockerfile 不是给 SSM 项目“套壳”而是给整个运行环境做可验证、可复现、可审计的声明式快照。它把“JDK 版本、Tomcat 参数、类路径、数据库连接池初始化策略、日志滚动规则、甚至 JVM 堆内存分配比例”这些原本藏在运维笔记或口头交接里的隐性知识全部显性化、版本化、自动化。我做过 3 个 SSM 项目的容器化迁移最深的体会是Dockerfile 写得越细后期排查问题越快写得越糙上线当天就越容易凌晨三点被电话叫醒。它解决的从来不是“能不能跑”而是“能不能稳定、安全、一致地跑”。尤其当你面对的是高校毕设答辩环境不同老师电脑装的 JDK 版本不一、外包交付客户对方服务器连 Maven 都没装、或者团队新成员接手老项目没人记得log4j.properties里那个maxBackupIndex5是干啥的时一个带完整构建上下文的 Dockerfile比十页 Word 部署文档更有说服力。它不替代架构设计但能兜住 80% 的环境差异引发的“在我机器上好好的”类故障。2. 核心设计思路为什么不用docker commit而必须手写 Dockerfile很多人第一次接触容器化会走捷径先docker run -it openjdk:8-jdk-slim进去手动装 Tomcat、拷 war 包、改配置、启动服务再docker commit生成镜像。看起来省事实则埋下三颗雷镜像不可追溯docker commit生成的镜像层就像黑盒录像——你不知道里面到底执行了哪些命令、删了哪些临时文件、漏配了哪个环境变量。下次要升级 Tomcat 补丁只能重走一遍手工流程无法做增量更新。体积失控手动操作必然残留大量缓存、日志、临时解压目录。我见过一个 80MB 的 SSM war 包commit出来的镜像高达 1.2GB因为里面塞了完整的apt-get update缓存、/tmp下未清理的编译中间件、甚至vi编辑器留下的.swp文件。安全审计失效生产环境要求镜像来源可审计。commit镜像没有明确的构建指令链安全扫描工具如 Trivy无法识别其中是否包含已知漏洞的旧版 Log4j 或 OpenSSL。所以Dockerfile 是唯一正解。它强制你把构建过程拆解为原子化指令每条RUN、COPY、ENV都是可审查、可测试、可回滚的单元。比如我们不会写RUN apt-get install -y tomcat8而是明确指定FROM tomcat:8.5.93-jre8-openjdk-slim—— 这个基础镜像本身已由 Apache 官方维护JRE 版本、OpenSSL 补丁、甚至默认的server.xml配置都经过验证。你只需要专注 SSM 项目本身的定制逻辑war 包怎么放、配置怎么覆盖、启动参数怎么调。更关键的是Dockerfile 天然支持分层缓存。当你只改了src/main/java里的业务代码重新构建时FROM、RUN apt-get update、COPY tomcat-config/ /usr/local/tomcat/conf/这些前置层全走缓存真正耗时的只有COPY target/*.war /usr/local/tomcat/webapps/这一步。实测下来二次构建时间从 3 分钟压到 12 秒这对 CI/CD 流水线是质的提升。3. Dockerfile 核心细节解析每一行背后的真实意图与避坑指南一个生产可用的 SSM Dockerfile绝不是网上搜来的模板拼凑。它必须回答三个核心问题环境怎么稳、配置怎么活、日志怎么管。下面逐行拆解我线上项目使用的精简版已脱敏重点讲清楚“为什么这么写”。# 3.1 基础镜像选择为什么选 jre8 而非 jdk8 FROM tomcat:8.5.93-jre8-openjdk-slim # 3.2 环境变量不是为了炫技而是解决“配置漂移” ENV TZAsia/Shanghai \ JAVA_HOME/usr/lib/jvm/java-8-openjdk-amd64 \ CATALINA_HOME/usr/local/tomcat \ CATALINA_BASE/usr/local/tomcat \ SPRING_PROFILES_ACTIVEprod # 3.3 时区校准避免日志时间戳错乱的隐形杀手 RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime echo $TZ /etc/timezone # 3.4 创建非 root 用户安全底线不妥协 RUN groupadd -g 1001 -r ssmgroup useradd -u 1001 -r -g ssmgroup ssmuser USER ssmuser # 3.5 拷贝应用 war 包注意路径和权限 COPY target/ssm-demo.war /usr/local/tomcat/webapps/ROOT.war # 3.6 覆盖 Tomcat 默认配置精准打击不碰无关文件 COPY tomcat-config/server.xml /usr/local/tomcat/conf/server.xml COPY tomcat-config/web.xml /usr/local/tomcat/conf/web.xml # 3.7 注入外部配置让数据库密码不硬编码在 war 包里 COPY config/application-prod.yml /app/config/application-prod.yml ENV SPRING_CONFIG_LOCATIONfile:/app/config/ # 3.8 暴露端口声明即契约不是可选项 EXPOSE 8080 # 3.9 启动脚本封装 JVM 参数避免命令行污染 COPY docker-entrypoint.sh /usr/local/bin/ RUN chmod x /usr/local/bin/docker-entrypoint.sh ENTRYPOINT [docker-entrypoint.sh]3.1 基础镜像选择为什么选jre8而非jdk8很多教程直接FROM openjdk:8-jdk-slim再手动装 Tomcat。这是典型误区。SSM 应用运行时只需 JREJava Runtime EnvironmentJDKJava Development Kit包含的javac、javadoc等开发工具在容器里纯属累赘不仅增大镜像体积约 120MB更增加攻击面。官方tomcat:8.5.93-jre8-openjdk-slim镜像已预装优化过的 OpenJDK 8 JRE 和 Tomcat 8.5.93且基于debian:slim剔除了apt、bash等非必要包。实测体积仅 287MB比自建 JDKTomcat 组合小 40%。更重要的是它的server.xml已禁用 AJP 连接器减少 CVE-2020-1938 风险catalina.sh中的JAVA_OPTS默认为空给你完全的 JVM 参数控制权。提示别迷信latest标签。tomcat:latest可能指向 Tomcat 10Servlet 5.0而 SSM 基于 Servlet 3.1强行升级会导致WebServlet注解失效。务必锁定具体版本号如8.5.93。3.2 环境变量不是为了炫技而是解决“配置漂移”ENV TZAsia/Shanghai看似简单却解决了一个高频痛点Java 应用获取系统时区失败。Tomcat 容器默认时区是 UTCnew Date()输出的时间戳比北京时间晚 8 小时导致日志时间错乱、定时任务执行时间偏差。SPRING_PROFILES_ACTIVEprod则让 Spring Boot或通过spring.profiles.active配置的 SSM自动加载application-prod.yml避免在 war 包里硬编码测试库地址。注意ENV指令设置的变量在构建时和运行时都生效但ARG只在构建时有效。如果数据库密码需在 CI 流水线中动态注入应使用ARG DB_PASSWORD--build-arg DB_PASSWORD$SECRET方式传入而非写死在 Dockerfile 里。3.3 时区校准避免日志时间戳错乱的隐形杀手RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime echo $TZ /etc/timezone这行是关键。单纯设ENV TZ不足以让 JavaSimpleDateFormat识别时区必须同步修改/etc/localtime符号链接和/etc/timezone文件。我曾遇到一个案例SSM 项目用Log4j记录操作日志因容器时区未校准日志里显示“2023-01-01 00:00:00”实际是北京时间 08:00审计时差点被误判为系统被篡改。3.4 创建非 root 用户安全底线不妥协RUN groupadd ... useradd ...创建ssmuser并切换USER ssmuser是 Docker 安全最佳实践。默认 root 用户拥有容器内最高权限一旦应用存在 RCE 漏洞如 Struts2 历史漏洞攻击者可直接执行rm -rf /。以非 root 用户运行即使被攻破权限也被限制在ssmuser目录下。注意Tomcat 默认监听 8080 端口而 Linux 规定 1024 以下端口需 root 权限绑定。因此我们保留EXPOSE 8080但通过server.xml中Connector port8080显式声明Tomcat 会自动降权绑定无需sudo。实操心得创建用户后务必检查webapps/目录权限。COPY操作默认以 root 用户执行可能导致ssmuser无权读取 war 包。解决方案是在COPY后加RUN chown -R ssmuser:ssmgroup /usr/local/tomcat/webapps/。3.5 拷贝应用 war 包注意路径和权限COPY target/ssm-demo.war /usr/local/tomcat/webapps/ROOT.war这里有两个细节文件名用ROOT.warTomcat 会将webapps/ROOT.war自动解压为webapps/ROOT/访问时 URL 无需加项目名如http://localhost:8080/而非http://localhost:8080/ssm-demo/符合生产环境简洁性要求。源路径target/ssm-demo.war确保你的 Mavenpom.xml中finalName设为ssm-demo且本地已执行mvn clean package。CI 流水线中建议在COPY前加RUN ls -l target/用于调试避免因 war 包未生成导致构建失败却无提示。3.6 覆盖 Tomcat 默认配置精准打击不碰无关文件COPY tomcat-config/server.xml /usr/local/tomcat/conf/server.xml不是简单替换而是最小化修改。原始server.xml有 200 行我们只改三处Connector port8080 protocolHTTP/1.1→ 加maxThreads200 minSpareThreads10控制线程池防突发流量打满Engine nameCatalina defaultHostlocalhost→ 加jvmRoutenode1为后续集群 session 复制铺路注释掉Valve classNameorg.apache.catalina.valves.AccessLogValve因日志统一由logback管理避免双写冗余。避坑不要COPY tomcat-config/ /usr/local/tomcat/conf/整个目录。Tomcat 8.5 的conf/下有logging.properties、context.xml等关键文件全量覆盖可能破坏日志级别或 JDBC 连接池默认行为。3.7 注入外部配置让数据库密码不硬编码在 war 包里COPY config/application-prod.yml /app/config/application-prod.ymlENV SPRING_CONFIG_LOCATIONfile:/app/config/是解耦关键。SSM 项目通常将jdbc.url、jdbc.username、jdbc.password写在application.yml里打包进 war。这导致密码明文暴露在 Git 仓库测试/生产环境切换需重新打包。通过SPRING_CONFIG_LOCATION指向外部挂载目录运行时用-v ./config:/app/config挂载真实配置war 包彻底纯净。application-prod.yml内容示例spring: datasource: url: jdbc:mysql://mysql:3306/ssm_demo?useUnicodetruecharacterEncodingutf8 username: ${DB_USER:root} password: ${DB_PASSWORD:123456}${DB_PASSWORD:123456}表示若环境变量DB_PASSWORD未设置则用默认值123456仅限测试生产环境务必通过-e DB_PASSWORDxxx注入。3.8 暴露端口声明即契约不是可选项EXPOSE 8080不开启端口只是文档化声明。但它影响docker run --link的自动端口映射且是 Docker 网络策略的基础。忽略它docker ps中看不到端口信息排查网络问题时多一层障碍。3.9 启动脚本封装 JVM 参数避免命令行污染docker-entrypoint.sh内容精简#!/bin/sh exec $CATALINA_HOME/bin/catalina.sh run -Duser.timezoneGMT8 -Xms512m -Xmx1024m -XX:UseG1GC $-Duser.timezoneGMT8强制 JVM 时区双重保险-Xms512m -Xmx1024m设置堆内存避免容器内存超限被 OOM Killer 杀死-XX:UseG1GC指定垃圾回收器SSM 应用多为短生命周期对象G1 比 CMS 更适合exec替换当前进程确保catalina.sh成为 PID 1接收SIGTERM信号优雅关闭。实操心得ENTRYPOINT用数组格式[docker-entrypoint.sh]而非字符串格式ENTRYPOINT docker-entrypoint.sh。后者会触发/bin/sh -c导致信号转发异常——docker stop时 Tomcat 无法捕获SIGTERM强制kill -9造成连接未释放。4. 完整构建与运行实操从本地测试到生产部署的闭环流程写完 Dockerfile 只是开始。真正的价值在于构建、测试、部署的全流程可控。下面以我实际操作的 SSM 学生信息管理系统为例展示每一步的命令、意图和现场记录。4.1 构建前准备目录结构与依赖检查项目根目录结构必须清晰这是构建可靠性的基石ssm-student-system/ ├── pom.xml # Maven 主配置确认 packagingwar/packaging ├── src/ │ └── main/ │ ├── java/ # SSM 业务代码 │ ├── resources/ # application.yml, mybatis-config.xml 等 │ └── webapp/ # WEB-INF/web.xml, static/, jsp/ ├── target/ # mvn package 后生成 ssm-demo.war ├── Dockerfile # 上文详解的 Dockerfile ├── tomcat-config/ # server.xml, web.xml 定制版 ├── config/ # application-prod.yml 外部配置 └── docker-entrypoint.sh # 启动脚本关键检查点运行mvn clean package -Dmaven.test.skiptrue确认target/ssm-demo.war生成且大小合理我的项目约 18MB。若报错Could not resolve dependencies说明本地 Maven 仓库缺spring-webmvc等依赖需先mvn dependency:resolve。检查pom.xml中maven-war-plugin版本SSM 项目推荐2.6避免3.x版本因archiveClasses默认值变更导致 classpath 错乱。4.2 本地构建验证 Dockerfile 语法与镜像完整性# 在项目根目录执行 docker build -t ssm-demo:1.0.0 .-t ssm-demo:1.0.0为镜像打标签1.0.0对应项目版本号便于追踪。构建过程实时输出重点关注Step 3/12 : RUN ln -snf ...是否成功返回0Step 6/12 : COPY target/ssm-demo.war ...是否找到文件若提示no such file检查target/路径最终Successfully built abcdef123456后运行docker images | grep ssm-demo确认镜像 ID 和 SIZE应接近 300MB。实操心得首次构建慢约 2 分钟因需下载基础镜像。后续修改Dockerfile后利用分层缓存仅COPYwar 包那步耗时。若想跳过缓存强制重建加--no-cache参数但慎用——会拖慢 CI 流水线。4.3 本地运行测试模拟生产环境暴露真实问题# 启动容器挂载外部配置连接本地 MySQL docker run -d \ --name ssm-test \ -p 8080:8080 \ -v $(pwd)/config:/app/config \ -e DB_USERroot \ -e DB_PASSWORD123456 \ -e MYSQL_HOSThost.docker.internal \ ssm-demo:1.0.0-p 8080:8080将容器 8080 映射到宿主机 8080-v $(pwd)/config:/app/config挂载配置目录SPRING_CONFIG_LOCATION生效-e MYSQL_HOSThost.docker.internal是 Windows/macOS Docker Desktop 的特殊 DNS指向宿主机 localhost。Linux 需改用--add-hostmysql:host-gateway。验证步骤docker logs ssm-test查看启动日志确认INFO [main] org.apache.catalina.startup.Catalina.start Server startup in [X] ms浏览器访问http://localhost:8080/login输入默认账号admin/123456点击“学生列表”检查页面是否正常渲染F12 看 Network 请求返回200 OKdocker exec -it ssm-test ps aux | grep java确认 JVM 进程参数含-Xms512mdocker exec -it ssm-test ls -l /app/config/验证application-prod.yml已挂载。常见问题速查表现象可能原因排查命令docker logs显示java.lang.ClassNotFoundException: org.springframework.web.servlet.DispatcherServletwar 包未正确解压或web.xml中 servlet-class 路径错误docker exec ssm-test ls -l /usr/local/tomcat/webapps/ROOT/WEB-INF/lib/页面 404但docker logs无报错server.xml中Context路径配置错误或ROOT.war未自动解压docker exec ssm-test ls -l /usr/local/tomcat/webapps/登录后跳转空白页Network 显示500 Internal Server Errorapplication-prod.yml中jdbc.url的mysqlhost 解析失败docker exec ssm-test ping -c 2 mysql4.4 生产部署与 Nginx 反向代理、MySQL 容器协同单容器只是起点。生产环境需组合编排。我的部署方案如下MySQL 容器docker run -d --name mysql-prod -e MYSQL_ROOT_PASSWORD123456 -p 3306:3306 -v /data/mysql:/var/lib/mysql mysql:5.7.39Nginx 容器作为反向代理和静态资源服务nginx.conf关键配置upstream ssm_backend { server ssm-demo:8080; } server { listen 80; location / { proxy_pass http://ssm_backend; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } location /static/ { alias /usr/share/nginx/html/static/; } }SSM 容器启动时 --link 到 MySQL并挂载 Nginx 静态目录docker run -d \ --name ssm-prod \ --link mysql-prod:mysql \ -v /path/to/nginx/html/static:/usr/local/tomcat/webapps/ROOT/static \ -v /path/to/config:/app/config \ -e DB_USERroot \ -e DB_PASSWORD123456 \ ssm-demo:1.0.0实操心得SSM 项目前端常含js/css静态文件若全由 Tomcat 服务性能不如 Nginx。将static/目录挂载到 Nginx 容器既减轻 Tomcat 压力又利用 Nginx 的 gzip 压缩和缓存能力。挂载时注意权限Nginx 容器以nginx用户运行需chown -R 101:101 /path/to/nginx/html/static101 是 nginx 用户 UID。4.5 CI/CD 集成GitHub Actions 自动化构建与推送本地验证通过后接入自动化流水线。我的github/workflows/docker-build.yml核心步骤name: Build and Push SSM Docker Image on: push: tags: [v*.*.*] # 仅 tag 推送触发 jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkoutv3 - name: Set up JDK 8 uses: actions/setup-javav3 with: java-version: 8 distribution: temurin - name: Build with Maven run: mvn -B clean package -Dmaven.test.skiptrue - name: Set up Docker Buildx uses: docker/setup-buildx-actionv2 - name: Login to Docker Hub uses: docker/login-actionv2 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - name: Build and push uses: docker/build-push-actionv4 with: context: . push: true tags: user/ssm-demo:${{ github.event.tag_name }}on.push.tags确保只有打v1.0.0这类语义化版本 tag 时才构建避免 master 分支频繁提交触发无效构建setup-javav3指定 Temurin JDK 8兼容 SSMdocker/build-push-actionv4原生支持 BuildKit构建速度比传统docker build快 30%且自动处理多平台镜像如linux/amd64,linux/arm64。注意Docker Hub 免费账户仅允许 1 个私有仓库。生产环境建议用阿里云 ACR 或腾讯云 TCR国内拉取速度快且提供镜像扫描、漏洞告警等企业功能。5. 常见问题与深度排查技巧那些 Dockerfile 里不会写的实战教训Dockerfile 写得再完美运行时仍可能翻车。以下是我在 3 个项目中踩过的坑附带独家排查技巧。5.1 “War 包解压失败”不是 Docker 问题而是 Tomcat 的静默陷阱现象容器启动后docker logs显示Server startup in [X] ms但访问http://localhost:8080返回 404docker exec ssm-test ls /usr/local/tomcat/webapps/发现只有ROOT.war没有解压出ROOT/目录。根本原因Tomcat 8.5 默认启用autoDeploytrue但若ROOT.war文件权限为600仅 owner 可读Tomcat 以ssmuser身份运行时无权读取解压失败却无日志。ls -l显示-rw------- 1 root root 18M ... ROOT.war。解决方案构建时加RUN chmod 644 /usr/local/tomcat/webapps/ROOT.war或在DockerfileCOPY后立即RUN chown ssmuser:ssmgroup /usr/local/tomcat/webapps/ROOT.war。排查技巧docker exec ssm-test cat /usr/local/tomcat/logs/catalina.out | grep deployWAR若看到SEVERE [localhost-startStop-1] org.apache.catalina.core.StandardContext.startInternal Error starting static Resources基本锁定权限问题。5.2 “JDBC 连接超时”容器网络的 DNS 迷雾现象SSM 页面登录时报org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connectiondocker logs显示Communications link failure。常见误区以为是 MySQL 密码错了反复检查application-prod.yml。实则根源在容器 DNS 解析。当 SSM 容器用--link mysql-prod:mysql启动时/etc/hosts会自动添加172.17.0.3 mysql。但若 MySQL 容器重启IP 变更/etc/hosts不会自动更新导致 DNS 缓存失效。终极解法弃用--link改用 Docker 自定义网络docker network create ssm-net docker run -d --name mysql-prod --network ssm-net -e MYSQL_ROOT_PASSWORD123456 mysql:5.7.39 docker run -d --name ssm-prod --network ssm-net -e MYSQL_HOSTmysql-prod ssm-demo:1.0.0Docker 内置 DNS 服务会动态解析mysql-prod到当前 IP彻底规避 IP 漂移。实操心得docker network inspect ssm-net可查看所有容器 IP 和 DNS 配置比ping更直观。5.3 “中文乱码”三层编码的连锁反应现象SSM 页面显示“???”数据库查询结果中文字段为问号。三重编码检查清单MySQL 服务端docker exec mysql-prod mysql -uroot -p123456 -e SHOW VARIABLES LIKE character_set%;确认character_set_serverutf8mb4JDBC 连接串application-prod.yml中jdbc.url必须含?useUnicodetruecharacterEncodingutf8mb4Tomcat 连接器server.xml中Connector加URIEncodingUTF-8属性否则 GET 请求参数乱码。独家技巧在docker-entrypoint.sh开头加echo JAVA_OPTS: $JAVA_OPTS确认-Dfile.encodingUTF-8是否生效。若未设置可在ENV中追加JAVA_TOOL_OPTIONS-Dfile.encodingUTF-8。5.4 “内存溢出 OOM”容器限制与 JVM 参数的博弈现象容器运行几小时后自动退出docker ps -a显示Exited (137)这是 OOM Killer 杀死进程的标志。根源分析Docker 默认不限制内存但若宿主机内存不足内核会 kill 掉占用内存最多的进程。SSM 应用若未设-XmxJVM 会按宿主机内存比例分配堆如 16GB 机器分配 4GB远超容器实际可用内存。解决方案启动容器时加--memory1g --memory-swap1g限制内存docker-entrypoint.sh中JAVA_OPTS必须设-Xms512m -Xmx512m且Xmx≤--memory的 75%留 25% 给 Metaspace、Direct Memory添加-XX:PrintGCDetails -Xloggc:/usr/local/tomcat/logs/gc.log定期分析 GC 日志。排查命令docker stats ssm-prod实时查看内存使用率docker exec ssm-prod jstat -gc $PID查看 JVM 堆各区域使用情况。5.5 “配置热更新失效”Spring Boot 与 SSM 的本质差异现象挂载application-prod.yml后修改文件SSM 无反应必须重启容器。残酷真相SSM 基于 Spring 3.x/4.x不支持配置文件热更新Value(${xxx})注解在 Bean 初始化时读取一次之后不再监听文件变化。这与 Spring Boot 2.x 的ConfigurationPropertiesspring-boot-devtools有本质区别。务实方案接受“配置即代码”理念每次配置变更都打新镜像v1.0.1或在application-prod.yml中用${ENV_VAR:default}占位符通过-e ENV_VARnew_value动态注入无需重启若真需热更新改造为 Spring Boot 项目但需重写web.xml和DispatcherServlet配置成本较高。实操心得在Dockerfile中RUN echo Config loaded from: $SPRING_CONFIG_LOCATION构建时打印路径避免因挂载路径错误导致配置未生效。6. 后续演进方向从单机 Docker 到云原生的平滑过渡完成 Dockerfile 封装只是容器化的起点。基于这个坚实基础你可以自然延伸到更高阶场景无需推倒重来。6.1 多环境配置用 Docker Compose 管理 dev/test/prod 差异将docker run的长命令收敛为docker-compose.ymlversion: 3.8 services: ssm-dev: image: ssm-demo:1.0.0 ports: [8080:8080] environment: - SPRING_PROFILES_ACTIVEdev - DB_PASSWORDdev123 volumes: - ./config-dev:/app/config ssm-prod: image: ssm-demo:1.0.0 ports: [8081:8080] environment: - SPRING_PROFILES_ACTIVEprod - DB_PASSWORD${PROD_DB_PASSWORD} volumes: - ./config-prod:/app/config - /data/ssm-logs:/usr/local/tomcat/logsdocker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d即可一键启停生产环境环境变量通过.env文件注入彻底告别命令行拼接。6.2 镜像瘦身用多阶段构建砍掉 60% 体积当前镜像含 Tomcat 全量文件lib/下 50 jar。多阶段构建可剥离# 第一阶段构建 war 包 FROM maven
返回列表