【问题标题】:Use docker run command to pass arguments to CMD in Dockerfile使用 docker run 命令将参数传递给 Dockerfile 中的 CMD
【发布时间】:2017-04-13 21:05:49
【问题描述】:

我是 Docker 新手,我很难根据需要设置 docker 容器。我有一个 nodejs 应用程序在启动时可以带两个参数。例如,我可以使用

node server.js 0 dev

node server.js 1 prod

在生产模式和开发模式之间切换并确定是否应该打开集群。现在我想创建带有参数的 docker 图像来做类似的事情,到目前为止我唯一能做的就是调整 Dockerfile 有一行

CMD [ "node", "server.js", "0", "dev"]

docker build -t me/app . 构建 docker。

然后docker run -p 9000:9000 -d me/app 运行 docker。

但是如果我想切换到 prod 模式,我需要将 Dockerfile CMD 更改为

CMD [ "node", "server.js", "1", "prod"],

我需要终止监听端口 9000 的旧版本并重建映像。 我希望我能有类似的东西

docker run -p 9000:9000 environment=dev cluster=0 -d me/app

创建映像并使用“环境”和“集群”参数运行 nodejs 命令,因此我不需要更改 Dockerfile 并重新构建 docker。我怎样才能做到这一点?

【问题讨论】:

    标签: node.js docker dockerfile


    【解决方案1】:

    我在docker-compose not setting environment variables with flask找到了这个

    docker-compose.yml

    version: '2'
    
    services:
      app:
          image: python:2.7
          environment:
            - BAR=FOO
          volumes:
            - ./app.py:/app.py
          command: python app.py
    

    app.py

    import os
    
    print(os.environ["BAR"])
    

    【讨论】:

      【解决方案2】:

      不确定这是否有帮助,但我已经以这种方式使用它,它就像一个魅力

      CMD ["node", "--inspect=0.0.0.0:9229", "--max-old-space-size=256", "/home/api/index.js"]

      【讨论】:

        【解决方案3】:

        确保你的 Dockerfile 声明了一个环境变量 with ENV:

        ENV environment default_env_value
        ENV cluster default_cluster_value
        

        ENV <key> <value> 表单可以是 replaced inline

        那你可以pass an environment variable with docker run。请注意,每个变量都需要一个特定的-e 标志才能运行。

        docker run -p 9000:9000 -e environment=dev -e cluster=0 -d me/app
        

        或者你可以set them through your compose file:

        node:
          environment:
            - environment=dev
            - cluster=0
        

        您的 Dockerfile CMD 可以使用该环境变量,但是,如 issue 5509 中所述,您需要以 sh -c 的形式这样做:

        CMD ["sh", "-c", "node server.js ${cluster} ${environment}"]
        

        解释是shell负责扩展环境变量,而不是Docker。当您使用 JSON 语法 时,您明确要求您的命令绕过 shell 并直接执行。

        Builder RUN 相同的想法(也适用于CMD):

        与 shell 形式不同,exec 形式不调用命令 shell。
        这意味着不会发生正常的 shell 处理。

        例如,RUN [ "echo", "$HOME" ] 不会对 $HOME 进行变量替换。如果你想要 shell 处理,那么要么使用 shell 形式,要么直接执行 shell,例如:RUN [ "sh", "-c", "echo $HOME" ]

        当使用 exec 形式并直接执行 shell 时,与 shell 形式的情况一样,是 shell 进行环境变量扩展,而不是 docker。

        【讨论】:

        【解决方案4】:

        选项 1) 使用 ENV 变量

        Dockerfile

        # we need to specify default values
        ENV ENVIRONMENT=production
        ENV CLUSTER=1
        
        # there is no need to use parameters array
        CMD node server.js ${CLUSTER} ${ENVIRONMENT}
        

        Docker 运行

        $ docker run -d -p 9000:9000 -e ENVIRONMENT=dev -e CLUSTER=0 -me/app
        

        选项 2) 传递参数

        Dockerfile

        # use entrypoint instead of CMD and do not specify any arguments
        ENTRYPOINT node server.js
        

        Docker 运行

        在 docker 镜像名称之后传递参数

        $ docker run -p 9000:9000 -d me/app 0 dev
        

        【讨论】:

          【解决方案5】:

          有点跑题了,构建参数的存在允许您在构建时传递参数,这些参数表现为环境变量,以便在您的 docker 映像构建过程中使用:

          $ docker build --build-arg HTTP_PROXY=http://10.20.30.2:1234 .
          

          【讨论】:

          • 这就是我要找的……!!
          【解决方案6】:

          另一个选项是使用ENTRYPOINT 来指定node 是要运行的可执行文件,并使用CMD 来提供参数。文档在Exec form ENTRYPOINT example 中有一个示例。

          使用这种方法,您的 Dockerfile 将类似于

          FROM ...
          
          ENTRYPOINT [ "node",  "server.js" ]
          CMD [ "0", "dev" ]
          

          在 dev 中运行它会使用相同的命令

          docker run -p 9000:9000 -d me/app
          

          并在 prod 中运行它,您会将参数传递给运行命令

          docker run -p 9000:9000 -d me/app 1 prod
          

          您可能希望完全省略 CMD 并始终将 0 dev1 prod 作为参数传递给运行命令。这样您就不会意外在 dev 中启动 prod 容器或在 prod 中启动 dev 容器。

          【讨论】:

            【解决方案7】:

            在 Docker 容器中执行此操作的典型方法是传入环境变量:

            docker run -p 9000:9000 -e NODE_ENV=dev -e CLUSTER=0 -d me/app
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2018-12-29
              • 2017-01-12
              • 2021-10-29
              • 2021-10-20
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多