I have file template which has various variables. I would like to constitute these variables with values before I copy this file to running container. This what I do right now:
export $(grep -v '^#' /home/user/.env | xargs) && \
envsubst < template.yaml > new_connection.yaml && \
docker cp new_connection.yaml docker_container:/app && \
rm new_connection.yaml
This is working, however I'm sure there is a way I can skip file creation/copy/remove steps and do just something like: echo SOME_TEXT > new_connection.yaml
straight to the container. Could you help?
CodePudding user response:
This seems like a good application for an entrypoint wrapper script. If your image has both an ENTRYPOINT
and a CMD
, then Docker passes the CMD
as additional arguments to the ENTRYPOINT
. That makes it possible to write a simple script that rewrites the configuration file, then runs the CMD
:
#!/bin/sh
envsubst < template.yaml > /app/new_connection.yaml
exec "$@"
In the Dockerfile, COPY
the script in and make it the ENTRYPOINT
. (If your host system doesn't correctly preserve executable file permissions or Unix line endings you may need to do some additional fixups in the Dockerfile as well.)
COPY entrypoint.sh ./
ENTRYPOINT ["/app/entrypoint.sh"] # must be JSON-array form
CMD same command as the original image
When you run the container, you need to pass in the environment file, but there's a built-in option for this
docker run --env-file /home/user/.env ... my-image
If you want to see this working, any command you provide after the image name replaces the Dockerfile CMD
, but it will still be passed to the ENTRYPOINT
as arguments. So you can, for example, see the rewritten config file in a new temporary container:
docker run --rm --env-file /home/user/.env my-image \
cat /app/new_connection.yaml
CodePudding user response:
Generally, I agree with David Maze and the comment section. You should probably build your image in such a way that it picks up env vars on startup and uses them accordingly.
However, to answer your question, you can pipe the output of envsubst
to the running container.
$ echo 'myVar: ${FOO}' > env.yaml
$ FOO=bar envsubst < env.yaml | docker run -i busybox cat
myVar: bar
If you want to write that to a file, using redirection, you need to wrap it in a sh -c
because otherwise the redirection is treated as redirect the container output to some path on the host.
FOO=bar envsubst < env.yaml | docker run -i busybox sh -c 'cat > my-file.yaml'
I did it here with docker run
but you can do the same with exec
.
FOO=bar envsubst < env.yaml | docker exec -i <container> cat