如何使用shell脚本在dockerfile中的环境变量中设置动态值

如何使用shell脚本在dockerfile中的环境变量中设置动态值,shell,docker,environment-variables,dockerfile,Shell,Docker,Environment Variables,Dockerfile,我的设想如下 我需要将“项目”文件夹添加到docker容器中,用于生产构建,但对于开发构建,我希望将本地卷装载到容器的项目文件夹中 例如,在生产中添加project/var/www/html/project 开发中无任何内容(我可以在开发中复制虚拟文件夹) 如果我将整个项目文件夹复制到开发中的容器中,则项目文件夹中的任何更改都将使add命令后的层docker缓存无效。在开发中建立docker形象需要时间 我想对这两种环境使用相同的docker文件 为了实现这一点,我在docker文件中使用了添

我的设想如下

  • 我需要将“项目”文件夹添加到docker容器中,用于生产构建,但对于开发构建,我希望将本地卷装载到容器的项目文件夹中 例如,
    在生产中添加project/var/www/html/project

    开发中无任何内容(我可以在开发中复制虚拟文件夹)

    如果我将整个项目文件夹复制到开发中的容器中,则项目文件夹中的任何更改都将使add命令后的层docker缓存无效。在开发中建立docker形象需要时间

  • 我想对这两种环境使用相同的docker文件

  • 为了实现这一点,我在docker文件中使用了
    添加$PROJECT\u DIR/var/www/html/PROJECT
    ,其中$PROJECT\u DIR是环境变量

  • 在docker文件中设置环境变量,如
    ENV PROJECT\u DIR PROJECT
    ENV CONFIG\u file\u PATH dummy folder
    会将正确的文件夹添加到容器中,但每次都需要我更改docker文件

  • 我还可以在构建docker映像时传递“build arg”参数,如

    docker build -t myproject --build-arg "BUILD_TYPE=PROD" --build-arg "PROJECT_DIR=project" .   
    
    由于变量BUILD_TYPE和PROJECT_DIR是相关的,我想根据BUILD_TYPE设置CONFIG_FILE_PATH变量。这将防止我忘记更改一个参数的情况

  • 为了设置PROJECT_DIR变量,我编写了以下脚本“set_config_path.sh”

  • 然后,我在dockerfile中使用

    RUN . /root/set_project_folder.sh  
    
    为此,set_project_folder.sh脚本可以访问BUILD_类型变量,但project_DIR不会反映在docker文件中

  • 在本地计算机的终端中运行set_project_folder.sh时,project_DIR变量已更改,但无法与dockerfile一起使用
在上述问题中,我们是否可以从子shell脚本(例如“set\u config\u path.sh”)中更改环境变量?

如果可能的话,它可以在许多用例中使用,以使docker build动态化

我在这里做错什么了吗?


有没有其他好的方法来实现这一点?

您可以使用下面的方法

FROM alpine
ARG BUILD_TYPE=prod
ARG CONFIG_FILE_PATH=config-$BUILD_TYPE.yml
RUN echo "BUILD_TYPE=$BUILD_TYPE CONFIG_FILE_PATH=$CONFIG_FILE_PATH"
CMD echo "BUILD_TYPE=$BUILD_TYPE CONFIG_FILE_PATH=$CONFIG_FILE_PATH"
输出结果如下

Step 4/4 : RUN echo "BUILD_TYPE=$BUILD_TYPE CONFIG_FILE_PATH=$CONFIG_FILE_PATH"
 ---> Running in b5de774d9ebe
BUILD_TYPE=prod CONFIG_FILE_PATH=config-prod.yml
但是如果你运行图像

$ docker run 9df23a126bb1
BUILD_TYPE= CONFIG_FILE_PATH=
这是因为生成参数不是作为环境变量持久化的。如果您还想在图像中保留这些变量,则需要在下面添加

ENV BUILD_TYPE=$BUILD_TYPE CONFIG_FILE_PATH=$CONFIG_FILE_PATH
现在docker run也将输出

$ docker run c250a9d1d109
BUILD_TYPE=prod CONFIG_FILE_PATH=config-prod.yml

你可以使用下面的方法

FROM alpine
ARG BUILD_TYPE=prod
ARG CONFIG_FILE_PATH=config-$BUILD_TYPE.yml
RUN echo "BUILD_TYPE=$BUILD_TYPE CONFIG_FILE_PATH=$CONFIG_FILE_PATH"
CMD echo "BUILD_TYPE=$BUILD_TYPE CONFIG_FILE_PATH=$CONFIG_FILE_PATH"
输出结果如下

Step 4/4 : RUN echo "BUILD_TYPE=$BUILD_TYPE CONFIG_FILE_PATH=$CONFIG_FILE_PATH"
 ---> Running in b5de774d9ebe
BUILD_TYPE=prod CONFIG_FILE_PATH=config-prod.yml
但是如果你运行图像

$ docker run 9df23a126bb1
BUILD_TYPE= CONFIG_FILE_PATH=
这是因为生成参数不是作为环境变量持久化的。如果您还想在图像中保留这些变量,则需要在下面添加

ENV BUILD_TYPE=$BUILD_TYPE CONFIG_FILE_PATH=$CONFIG_FILE_PATH
现在docker run也将输出

$ docker run c250a9d1d109
BUILD_TYPE=prod CONFIG_FILE_PATH=config-prod.yml

您好,谢谢,您的解决方案将适用于我在问题上提出的条件,对不起,我忘了提到其他条件。我还想使用“BUILD_TYPE”变量复制一些用于生产构建的文件夹,但不用于开发构建。我将更新我的问题,包括alsoHi谢谢,您的解决方案将适用于我在问题上提出的条件,对不起,我忘了提到其他条件。我还想使用“BUILD_TYPE”变量复制一些用于生产构建的文件夹,但不用于开发构建。我将更新我的问题,将其也包括在内