【问题标题】:How to run an export command within the docker entrypoint?如何在 docker 入口点中运行导出命令?
【发布时间】:2021-05-10 19:19:19
【问题描述】:

我正在尝试将 Datadog APM 跟踪和日志收集集成到在 Docker 上运行的 python 应用程序。 在 Dockerfile 中,我需要激活 conda 虚拟环境并导出一个环境 DD_AGENT_HOST。

FROM continuumio/miniconda3

WORKDIR /app

COPY src ./src
COPY application.yaml .
COPY wsgi.py .
COPY gunicorn.conf.py .
COPY logging.ini .

RUN conda env create -f application.yaml

SHELL ["conda", "run", "-n", "dd_venv", "/bin/bash", "-c"]

ENTRYPOINT ["conda", "run", "--no-capture-output", "-n", "dd_venv", "ddtrace-run", "gunicorn", "-c", "gunicorn.conf.py", "wsgi:app", "--preload"]

我可以使用上面的 Dockerfile 运行应用程序。但是,需要导出环境 DD_AGENT_HOST 以便应用程序连接 Datadog,并且必须通过 HTTP 请求检索 DD_AGENT_HOST 的值。

ENTRYPOINT ["conda", "run", "--no-capture-output", "-n", "dd_venv", "export DD_AGENT_HOST=$(wget <ip_ddress>)", "ddtrace-run", "gunicorn", "-c", "gunicorn.conf.py", "wsgi:app", "--preload"]

我尝试将导出命令添加到上面的 ENTRYPOINT,这导致 Docker 运行失败并出现错误 "export DD_AGENT_HOST=: command not found:.

完成此任务的正确方法是什么?

【问题讨论】:

  • 你试过"DD_AGENT_HOST=$(wget &lt;ip_address&gt;)",没有导出吗?
  • @merv 感谢您的帮助。我能够以不同的方式解决它。请参考下面我的回答。

标签: python docker conda gunicorn datadog


【解决方案1】:

由于您是通过激活的 Conda 环境运行它,因此应该可以将激活脚本添加到包含该命令的环境中。例如,像这样的文件:

/path/to/envs/dd_venv/etc/conda/activate.d/env_vars.sh

#!/bin/sh

export DD_AGENT_HOST=$(wget <ip_address>)

the documentation on Saving Environment Variables

请注意,对于静态环境变量(例如,您知道先验的字符串),这些可以直接集成到您的 application.yaml 文件中。见the documentation on Setting Environment Variables

【讨论】:

  • 我试过了。虽然 DD_AGENT_HOST 是从脚本初始化的,但它似乎无法被应用程序访问。我想知道这是否与 ENTRYPOINT 中的另一个“conda run”有关。
【解决方案2】:

我能够通过使用 CMD 的 shell 形式并结合导出环境变量的命令和启动应用程序的命令来解决这个问题。

CMD export DD_AGENT_HOST=$(wget <ip_address>); ddtrace-run gunicorn -c gunicorn.conf.py wsgi:app --preload

我必须在 SHELL 中添加 --no-capture-output 才能将日志写入 sdoutstderr

SHELL ["conda", "run", "--no-capture-output", "-n", "dd_venv", "/bin/bash", "-c"]

【讨论】:

    【解决方案3】:

    您正试图在 ENTRYPOINT 单行中投入很多;我会稍微分解一下。

    首先,您尝试运行的实际命令位于该行的最后,我将该命令设为 Dockerfile CMD

    CMD ["gunicorn", "-c", "gunicorn.conf.py", "wsgi:app", "--preload"]
    

    拥有一个实际的CMD 在这里很有价值,主要是因为它很容易替换它。如果你想仔细检查应用程序是否真的在 Conda 环境中运行,或者环境设置是否正确,你可以 docker run --rm ... sh -c 'echo $DD_AGENT_HOST' 并且该命令将替换 CMD,但仍然通过 ENTRYPOINT 运行。

    ENTRYPOINT 中有什么内容?你现在想做两件事,你可以把它们写在一个脚本里:

    #!/bin/sh
    # entrypoint.sh
    
    # 1. Set a dynamic environment variable
    export DD_AGENT_HOST=$(wget <ip_ddress>)
    
    # 2. Run whatever the command is, in the Conda environment,
    # with the tracing wrapper.
    exec conda run \
      --no-capture-output \
      -n dd_venv \
      ddtrace-run \
      "$@"
    

    然后该脚本可以是图像的ENTRYPOINT

    COPY entrypoint.sh .           # should be executable on the host already
    ENTRYPOINT ["./entrypoint.sh"] # must be JSON-array syntax
    

    一般来说,您可以在该脚本中放入任何内容,只要该脚本以exec "$@" 或其上的某个变体结尾,脚本中的所有内容都会在将控制权交给CMD 之前按顺序运行。

    【讨论】:

      猜你喜欢
      • 2018-02-05
      • 2017-09-29
      • 1970-01-01
      • 1970-01-01
      • 2020-07-01
      • 1970-01-01
      • 2018-05-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多