docker - docker - 在构建期间将参数传递给脚本
问题描述
我想将参数(来自 docker 命令)传递给 Dockerfile 中的 shell 脚本。
这是 docker 命令行。
docker build --file=DockerfileTest --build-arg docker_image=PX-release-migration --tag=test-image:latest --rm=true .
这是在 Dockerfile 中调用的脚本。
#!/bin/sh -e
image_name=$1
echo "docker image is $image_name"
if [[ ($image_name == '') || ($image_name == *"-dev-"*) ]]; then
echo "This is development"
cp src/main/resources/application-dev.properties src/main/resources/application.properties
elif [[ $image_name == *"-preprod-"* ]]; then
echo "This is preprod"
cp src/main/resources/application-stg.properties src/main/resources/application.properties
elif [[ $image_name == *"-release-"* ]]; then
echo "This is production"
cp src/main/resources/application-prod.properties src/main/resources/application.properties
fi
当我单独执行脚本时,它可以工作,但确实可以
这是码头文件。
ARG spring_env=local
ARG docker_image=-local-
FROM maven:3.6.1-jdk-8
COPY . /apps/demo
WORKDIR /apps/demo
RUN chmod +x /apps/demo/initialize_env.sh
RUN ./initialize_env.sh $docker_image
RUN echo "spring_env is ${spring_env}"
所以基本上,我想根据 docker_image 名称在构建期间使用不同的 spring 应用程序属性文件。如果 docker 映像名称包含“发布”,我想在构建期间打包 application-prod.properties。
这是我收到的错误消息。
Step 1/8 : ARG spring_env=local
Step 2/8 : ARG docker_image=-local-
Step 3/8 : FROM maven:3.6.1-jdk-8
---> 4c81be38db66
Step 4/8 : COPY . /apps/demo
---> 41439197c465
Step 5/8 : WORKDIR /apps/demo
---> Running in 56bd408c2eb1
Removing intermediate container 56bd408c2eb1
---> 4c4025bf5f64
Step 6/8 : RUN chmod +x /apps/demo/initialize_env.sh
---> Running in 18dc3a5c1a54
Removing intermediate container 18dc3a5c1a54
---> 60d2037a0209
Step 7/8 : RUN ./initialize_env.sh $docker_image
---> Running in 2e049b2cf630
docker image is
./initialize_env.sh: 5: ./initialize_env.sh: Syntax error: word unexpected (expecting ")")
The command '/bin/sh -c ./initialize_env.sh $docker_image' returned a non-zero code: 2
当我单独执行脚本时,它可以工作,但它不在 docker 容器内。
解决方案
提示:使用ShellCheck检查脚本的语法错误。
#!/bin/sh -e
if [[ ($image_name == '') || ($image_name == *"-dev-"*) ]]; then
[[
是 bash 语法,但您的脚本被声明为使用普通 sh。它可以在您的机器上运行,大概是因为sh
它确实符号链接到bash
,但在容器内部并非如此。maven:3.6.1-jdk-8
基于debian:stretch
哪个使用破折号而不是bash。
改变shebang线。您也可以删除括号;他们是多余的。
#!/bin/bash -e
if [[ $image_name == '' || $image_name == *"-dev-"* ]]; then
您还可以使用case
块来简化重复检查。
case "$image_name" in
''|*-dev-*)
echo "This is development"
cp src/main/resources/application-dev.properties src/main/resources/application.properties
;;
*-preprod-*)
echo "This is preprod"
cp src/main/resources/application-stg.properties src/main/resources/application.properties
;;
*-release-*)
echo "This is production"
cp src/main/resources/application-prod.properties src/main/resources/application.properties
;;
esac
推荐阅读
- shell - 捕获 Makefile 目标的先决条件中的两个文件夹
- python - 如何在字典输出的每个第 n 个值之后添加破折号字符?
- python - from_personal_row() 接受 1 个位置参数,但给出了 2 个
- powerbi - 在 DAX/PBI 中将 SAMEPERIODLASTYEAR 偏移一周
- airflow - 登录自定义 Airflow 运算符
- c++ - 如果我在程序的主函数入口点结束时返回 EXIT_FAILURE,为什么什么也没有发生?
- c# - 从公共 Microsoft.IdentityModel.Tokens.JsonWebKey.JsonWebKey 转换为 RSAParameters(公共密钥)
- c - 如何解决“'main()'的多重定义”C编译错误?
- haskell - 使用 RankNTypes 编码的 System-F 自然数的“case”运算符无法进行类型检查
- ocaml - 在 Ocaml 中使用比较运算符会产生类型错误