【问题标题】:ENV in docker file not getting replaceddocker文件中的ENV没有被替换
【发布时间】:2021-03-24 04:25:21
【问题描述】:

我有一个非常简单的 docker 文件

FROM python:3
WORKDIR /usr/src/app
ENV CODEPATH=default_value
ENTRYPOINT ["python3"]
CMD ["/usr/src/app/${CODEPATH}"]

这是我的容器命令

docker run -e TOKEN="subfolder/testmypython.py"  --name mycontainer -v /opt/testuser/pythoncode/:/usr/src/app/  -t -d  python-image:latest

当我看到容器日志时,它会显示

python3: 无法打开文件 '/usr/src/app/${TOKEN}': [Errno 2] 没有这样的文件或目录

【问题讨论】:

  • CMD 不进行环境变量替换。这是由 shell 完成的。
  • env 名称 CODEPATH 但您将 TOKEN 设置为 env?请尝试 doker run -e CODEPATH="subfolder/testmypython.py" --name mycontainer -v /opt/testuser/pythoncode/:/usr/src/app/ -t -d python-image:latest

标签: python docker containers


【解决方案1】:

看起来您想要做的是覆盖启动容器时运行的 python 文件的默认路径。无需将此选项作为环境变量传递,您只需将文件的路径作为参数传递给 docker run,这就是 CMD in your dockerfile 的目的。您设置为 CMD 选项的内容是默认值,您的图像用户可以通过将参数传递给 docker run 命令轻松覆盖该选项。

doker run --name mycontainer -v /opt/testuser/pythoncode/:/usr/src/app/ -t -d python-image:latest "subfolder/testmypython.py"

【讨论】:

    【解决方案2】:

    环境变量名称CODEPATH,但您将TOKEN 设置为环境变量。 您能否尝试按照以下方式将 CODEPATH 设置为 env

    doker run -e CODEPATH="subfolder/testmypython.py" --name mycontainer -v /opt/testuser/pythoncode/:/usr/src/app/ -t -d python-image:latest 
    

    【讨论】:

      【解决方案3】:

      您拆分ENTRYPOINTCMD 的方式没有意义,并且无法在此处进行变量扩展。你应该把这两部分组合成一个CMD,然后使用shell形式运行它:

      # no ENTRYPOINT
      CMD python3 /usr/src/app/${CODEPATH}
      

      (完成此操作后,最好还是使用@allan's answer 和直接docker run python-image python3 other-script-name.py 中的方法。)

      Dockerfile 语法不允许在RUNENTRYPOINTCMD 命令中使用environment expansion。相反,这些命令有两种形式。 Exec form 要求您将命令格式化为 JSON 数组,并且不对您提供的内容进行任何处理;它使用一组确切的 shell 字和命令中的确切字符串运行命令。 Shell form 没有任何特殊语法,而是将命令包装在 sh -c 中,并且该 shell 处理您希望 shell 执行的所有正常操作。

      RUN为例:

      # These are the same:
      RUN ["ls", "-la", "some directory"]
      RUN ls -la 'some directory'
      
      # These are the same (and print a dollar sign):
      RUN ["echo", "$FOO"]
      RUN echo \$FOO
      
      # These are the same (and a shell does variable expansion):
      RUN echo $FOO
      RUN ["/bin/sh", "-c", "echo $FOO"]
      

      如果您同时拥有ENTRYPOINTCMD,则此扩展将分别针对每一半进行。这就是你遇到的分裂导致麻烦的地方:这些选项都不起作用:

      # Docker doesn't expand variables at all in exec form
      ENTRYPOINT ["python3"]
      CMD ["/usr/src/app/${CODEPATH}"]
      # ["python3", "/usr/src/app/${CODEPATH}"] with no expansion
      
      # The "sh -c" wrapper gets interpreted as an argument to Python
      ENTRYPOINT ["python3"]
      CMD /usr/src/app/${CODEPATH}
      # ["python3", "/bin/sh", "-c", "/usr/src/app/${CODEPATH}"]
      
      # "sh -c" only takes one argument and ignores the rest
      ENTRYPOINT python3
      CMD ["/usr/src/app/${CODEPATH}"]
      # ["/bin/sh", "-c", "python3", ...]
      

      这个ENTRYPOINT/CMD拆分唯一真正的效果是制作一个只能运行Python脚本的容器,无需特殊配置(尴尬的docker run --entrypoint选项);您仍然在CMD 中提供大部分命令行,但不是全部。我倾向于建议将整个命令放入CMD,并将ENTRYPOINT 保留用于一些更专业的用途;还有一种将完整的命令放入ENTRYPOINT 并尝试使用CMD 部分来传递选项的模式。无论哪种方式,如果将整个命令放在一个指令或另一个指令中,事情会更好。

      【讨论】:

        猜你喜欢
        • 2021-01-03
        • 1970-01-01
        • 2020-02-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多