如何在docker-compose.yml环境变量中正确配置cron表达式
问题根因
报错本质是cron表达式中的*被容器启动阶段的shell识别为通配符,触发了当前工作目录的文件名匹配,刚好目录下存在proc.1文件,*被替换为该文件名后打乱了JAVA_OPTS的参数结构,Java将匹配到的文件名误判为启动主类,就抛出了类找不到的异常。
之前加的单/双引号不生效,是因为shell的引号解析优先级高于变量扩展,存在于环境变量值中的引号只会被当作普通字符,无法起到阻止通配符展开的作用。
解决方法
方案1:修正docker-compose.yml配置(无需修改容器内容,推荐)
直接对cron表达式中的*做转义,同时调整YAML写法避免多余的符号被带入环境变量,两种写法可选:
单行写法
cont1: image: some-image restart: unless-stopped volumes: - some_volume environment: - JAVA_OPTS=-Dserver.port=${DP_PORT:-8080} -Ddoc.office.viaFile=true -DdocumentCache.cleanUp.cron.timer=0 \*/1 \* ? \* \* \*
多行易读写法(用YAML折叠标量,自动忽略换行)
cont1: image: some-image restart: unless-stopped volumes: - some_volume environment: JAVA_OPTS: >- -Dserver.port=${DP_PORT:-8080} -Ddoc.office.viaFile=true -DdocumentCache.cleanUp.cron.timer=0 \*/1 \* ? \* \* \*
方案2:修改容器启动脚本(彻底避免类似参数解析问题)
如果有权限修改镜像内的启动脚本,可以将JAVA_OPTS的参数用数组传递,从根源避免通配符展开和参数分词错误:
# 将JAVA_OPTS按空格拆分存入数组 read -ra JAVA_ARGS <<< "$JAVA_OPTS" # 启动应用时传入数组参数 java "${JAVA_ARGS[@]}" -jar 你的应用包名.jar
验证方法
调整配置后可以先临时修改启动命令打印JAVA_OPTS确认参数正确:
cont1: # 其他配置不变 command: printenv JAVA_OPTS
启动容器后查看输出的环境变量,确认cron表达式没有多余符号、转义生效即可。
内容的提问来源于stack exchange,提问作者mrondrejduchon
相关产品推荐
相关产品推荐

