You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Tomcat Docker中配置环境变量传递给Spring Boot应用

问题根因
  • Dockerfile里的ARG仅在镜像构建流程中生效,不会自动成为容器运行时的环境变量。你写的setenv.sh是Tomcat启动(容器运行阶段)才会调用的脚本,此时脚本里引用的${SPRING_DATASOURCE_*}变量为空值,最终传给JVM的参数自然无效。
  • 复制进容器的setenv.sh默认没有可执行权限,Tomcat启动时不会自动加载执行该脚本,连带你配置的spring.profiles.active=deploy也不会生效。
  • 额外注意:通过-D传JVM参数时,直接传入Spring Boot原生识别的配置项(比如-Dspring.datasource.url=xxx)优先级高于配置文件占位符匹配,稳定性更好。
解决方案(按构建阶段注入要求实现)

你可以选两种实现方式,第二种是完全把值写入配置文件,更贴合“构建阶段传入供应用读取”的需求。

方案1:构建时将参数转为环境变量,启动时传入JVM

  1. 修改Dockerfile,把构建参数转为镜像内置环境变量,同时给脚本加执行权限:
FROM tomcat:9.0.56
# 声明构建入参
ARG SPRING_DATASOURCE_URL
ARG SPRING_DATASOURCE_USERNAME
ARG SPRING_DATASOURCE_PASSWORD
# 将构建参数固化为镜像内的环境变量,供运行时脚本读取
ENV SPRING_DATASOURCE_URL=${SPRING_DATASOURCE_URL}
ENV SPRING_DATASOURCE_USERNAME=${SPRING_DATASOURCE_USERNAME}
ENV SPRING_DATASOURCE_PASSWORD=${SPRING_DATASOURCE_PASSWORD}

COPY setenv.sh /usr/local/tomcat/bin/setenv.sh
# 给脚本加可执行权限
RUN chmod +x /usr/local/tomcat/bin/setenv.sh
COPY /app/target/api.war /usr/local/tomcat/webapps/ROOT.war

EXPOSE 8080
CMD ["catalina.sh", "run"]
  1. 修改setenv.sh,补全脚本解释器,直接传入Spring可识别的配置参数:
#!/bin/bash
JAVA_OPTS="$JAVA_OPTS -Dspring.profiles.active=deploy"
JAVA_OPTS="$JAVA_OPTS -Dspring.datasource.url=jdbc:mysql://${SPRING_DATASOURCE_URL}"
JAVA_OPTS="$JAVA_OPTS -Dspring.datasource.username=${SPRING_DATASOURCE_USERNAME}"
JAVA_OPTS="$JAVA_OPTS -Dspring.datasource.password=${SPRING_DATASOURCE_PASSWORD}"

构建镜像时通过--build-arg传入参数即可,例如:

docker build -t api-app \
  --build-arg SPRING_DATASOURCE_URL=mysql-host:3306/db_name \
  --build-arg SPRING_DATASOURCE_USERNAME=root \
  --build-arg SPRING_DATASOURCE_PASSWORD=your_pwd \
  .

方案2:构建时直接替换配置文件内的占位符(完全构建阶段注入)

这种方式会在镜像构建时直接把参数值写入war包内的application-deploy.properties文件,不需要依赖运行时环境变量传递,更贴合需求:

  1. 修改Dockerfile:
FROM tomcat:9.0.56
ARG SPRING_DATASOURCE_URL
ARG SPRING_DATASOURCE_USERNAME
ARG SPRING_DATASOURCE_PASSWORD

# 先复制war包
COPY /app/target/api.war /usr/local/tomcat/webapps/ROOT.war
# 安装unzip解压war包,直接替换配置文件里的占位符
RUN apt-get update && apt-get install -y --no-install-recommends unzip && \
    cd /usr/local/tomcat/webapps && \
    mkdir ROOT && unzip ROOT.war -d ROOT && rm ROOT.war && \
    sed -i "s|\${SPRING_DATASOURCE_URL}|${SPRING_DATASOURCE_URL}|g" ROOT/WEB-INF/classes/application-deploy.properties && \
    sed -i "s|\${SPRING_DATASOURCE_USERNAME}|${SPRING_DATASOURCE_USERNAME}|g" ROOT/WEB-INF/classes/application-deploy.properties && \
    sed -i "s|\${SPRING_DATASOURCE_PASSWORD}|${SPRING_DATASOURCE_PASSWORD}|g" ROOT/WEB-INF/classes/application-deploy.properties && \
    # 清理安装的依赖减小镜像体积
    apt-get purge -y --auto-remove unzip && rm -rf /var/lib/apt/lists/*

COPY setenv.sh /usr/local/tomcat/bin/setenv.sh
RUN chmod +x /usr/local/tomcat/bin/setenv.sh

EXPOSE 8080
CMD ["catalina.sh", "run"]
  1. 简化setenv.sh,只保留profile激活配置即可:
#!/bin/bash
JAVA_OPTS="$JAVA_OPTS -Dspring.profiles.active=deploy"

构建命令和方案1一致。

注意:构建阶段注入数据库地址、密码这类敏感信息会直接固化在镜像层中,只要能获取镜像就能提取到明文值,生产环境更建议在容器启动时通过-e参数传入环境变量,不要把敏感信息打进镜像。

内容的提问来源于stack exchange,提问作者carlonchoboy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 09:12:19