简体   繁体   中英

How to run an export command within the docker entrypoint?

I'm trying to integrate Datadog APM tracing and log collection to a python application running on Docker. Within the Dockerfile, I need to activate the conda virtual env and export an env 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"]

I'm able to run the application using the above Dockerfile. However, it is required to export the env DD_AGENT_HOST for the application to connect with Datadog and the value of DD_AGENT_HOST has to be retrieved via an HTTP request.

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"]

I tried adding the export command to the ENTRYPOINT as above, which causes Docker run to fail with the error "export DD_AGENT_HOST=: command not found:.

What is the correct way of accomplishing this?

Since you're running it through an activated Conda environment, it should be possible to add an activation script to the environment that includes the command. For example, a file like:

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

#!/bin/sh

export DD_AGENT_HOST=$(wget <ip_address>)

See the documentation on Saving Environment Variables .

Note that for static environment variables (eg, strings you know a priori ), these could be directly integrated into your application.yaml file. See the documentation on Setting Environment Variables .

I was able to solve this by using the shell form of CMD and combining the command to export the environment variable and the command to start the application.

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

I had to add the --no-capture-output with SHELL to enable logs being written to sdout and stderr .

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

You're trying to put a lot into that single ENTRYPOINT line; I'd break it up a little bit.

First of all, the actual command you're trying to run is at the very end of that line, and I'd make that command be the Dockerfile CMD :

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

Having an actual CMD is valuable here mostly because it's easy to replace it. If you want to double-check whether the application is actually running inside the Conda environment, or the environment is being set properly, you can docker run --rm... sh -c 'echo $DD_AGENT_HOST' and that command will replace CMD , but still run via the ENTRYPOINT .

What goes in ENTRYPOINT ? You want to do two things now, and you can write them in a script:

#!/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 \
  "$@"

That script can then be the image's ENTRYPOINT .

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

In general, you can put anything in that script, and so long as the script ends with exec "$@" or some variant on it, everything in the script runs in order before it hands control over to the CMD .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM