【问题标题】:How to configure different dockerfile for development and production如何为开发和生产配置不同的 dockerfile
【发布时间】:2018-03-08 12:44:04
【问题描述】:

我使用 docker 进行 laravel 项目的开发和生产。对于开发和生产,我的 dockerfile 略有不同。例如,我在开发环境中将本地目录挂载到 docker 容器,这样我就不需要为代码的每次更改都进行 docker build。

由于挂载的目录只有在运行 docker 容器时才可用,所以我不能在 dockerfile 中放置“composer install”或“npm install”等命令进行开发。

目前我正在管理两个 docker 文件,有什么方法可以使用单个 docker 文件执行此操作,并通过发送参数来决定在执行 docker build 时运行哪些命令。

我想要实现的是

在 docker 文件中

...
IF PROD THEN RUN composer install
...

在 docker 构建期间

docker build [PROD] -t mytag .

【问题讨论】:

    标签: docker dockerfile


    【解决方案1】:

    作为一种最佳实践,您应该尝试使用一个 Dockerfile 来避免不同环境之间的意外错误。但是,您可能有一个无法做到这一点的用例。

    Dockerfile 语法不够丰富,无法支持这种情况,但是您可以使用 shell 脚本来实现。

    创建一个名为 install.sh 的 shell 脚本,它执行以下操作:

    if [ ${ENV} = "DEV" ]; then 
        composer install
    else
        npm install
    fi
    

    在你的 Dockerfile 中添加这个脚本,然后在构建时执行它

    ...
    COPY install.sh install.sh
    RUN chmod u+x install.sh && ./install.sh
    ...
    

    构建时传递一个构建参数来指定环境,例如:

    docker build --build-arg "ENV=PROD" ...
    

    【讨论】:

      【解决方案2】:

      更新(2020 年): 自从这是 3 年前写的,很多事情都发生了变化(包括我对这个话题的看法)。我建议的方法是使用 one dockerfile 并使用脚本。请参阅@yamenk's answer

      原文:

      您可以使用两个不同的 Dockerfile。

      # ./Dockerfile (non production)
      FROM foo/bar
      MAINTAINER ...
      
      # ....
      

      还有第二个:

      # ./Dockerfile.production
      FROM foo/bar
      MAINTAINER ...
      
      RUN composer install
      

      在调用构建命令时,您可以知道它应该使用哪个文件:

      $> docker build -t mytag .
      $> docker build -t mytag-production -f Dockerfile.production .
      

      【讨论】:

        【解决方案3】:

        您可以直接使用 build args 而无需提供额外的 sh 脚本。不过可能看起来有点乱。但它有效。

        Dockerfile 必须是这样的:

        FROM alpine
        ARG mode
        RUN if [ "x$mode" = "xdev" ] ; then echo "Development" ; else echo "Production" ; fi
        

        要检查的命令是:

        docker build -t app --build-arg mode=dev .
        docker build -t app --build-arg mode=prod .
        

        【讨论】:

        • 很好,但为什么 $mode 前面有“x”?一定是有原因的。
        • 只是插值的一个例子
        【解决方案4】:

        我已经尝试了几种方法,包括使用 docker-compose、多阶段构建、通过文件传递参数以及其他答案中使用的方法。我的公司需要一个好的方法来做到这一点,在尝试了这些之后,这是我的意见。

        最好的方法是通过 cmd 传递 arg。您可以在右键单击并选择构建映像时通过 vscode 传递它 Image of visual studio code while clicking image build 使用此代码:

        ARG BuildMode
        RUN echo $BuildMode
        RUN if [ "$BuildMode" = "debug" ] ; then apt-get update \
            && apt-get install -y --no-install-recommends \
               unzip \
            && rm -rf /var/lib/apt/lists/* \
            && curl -sSL https://aka.ms/getvsdbgsh | bash /dev/stdin -v latest -l /vsdbg ; fi
        

        在 dockerfile 的构建部分:

        ARG BuildMode
        ENV Environment=${BuildMode:-debug}
        RUN dotnet build "debugging.csproj" -c $Environment -o /app
        
        FROM build AS publish
        RUN dotnet publish "debugging.csproj" -c $Environment -o /app
        

        【讨论】:

          猜你喜欢
          • 2018-06-15
          • 2015-07-17
          • 2019-07-14
          • 1970-01-01
          • 2016-10-03
          • 2013-02-21
          • 1970-01-01
          • 1970-01-01
          • 2018-03-31
          相关资源
          最近更新 更多