I have an application which uses an environment variable named REDIS_URL
. A typical REDIS_URL
would be redis://172.17.0.5:6379/0
. I'd like to be able to populate REDIS_URL
based on container linking:
docker run --name redis -d redis
docker run --name firehose --link redis:redis -e REDIS_URL="redis://$REDIS_PORT_6379_TCP_ADDR:$REDIS_PORT_6379_TCP_PORT/0" -d firehose/server
But depending on how I escape the environment variables, they are either evaluated in my shell at docker run time and are blank (redis://:/0
), or passed as literal strings (redis://$REDIS_PORT_6379_TCP_ADDR:$REDIS_PORT_6379_TCP_PORT/0
).
How can I populate my REDIS_URL
application environment variable based on conatiner linking?
The $REDIS_PORT_6379_TCP_ADDR
and $REDIS_PORT_6379_TCP_PORT
variables are not known at the time the docker run
command is executed so there's no way to construct it from the host.
However, there is a workaround. In the Dockerfile
for the firehose/server
image there must be a CMD
or ENTRYPOINT
that dictates what command is executed when the image is run. You can put a wrapper around that command that will construct the REDIS_URL
variable. Something like this:
#!/bin/sh
export REDIS_URL="redis://${REDIS_PORT_6379_TCP_ADDR}:${REDIS_PORT_6379_TCP_PORT}/0"
<run command>
Use the wrapper script as the CMD
or ENTRYPOINT
in the Dockerfile
.
Let me veer slightly off topic at first. If you wanted to convert an env variable to a CLI variable you can avoid a wrapper script by evaling the variable inside the docker container.
docker run image /bin/bash -c '/container-command $INSIDE_DOCKER'
Now you may complain about not being able to use shell variables from outside your container. The below technique works in that case:
docker run image /bin/bash -c "/container-command $OUTSIDE_DOCKER \$INSIDE_DOCKER"
Back to the original question. If you don't use the default command from the Dockerfile but instead specify it, you can use the same approach.
docker run image /bin/bash -c "export FOO=\${INSIDE_DOCKER}; echo \$FOO"
The potential advantage this has in your case over the wrapper inside the container is that wrapper inside the container is hard-coded to a port and a link name. There should be a way to write a wrapper all outside of docker that inspects published ports (possibly along with the default command) and sets the variables accordingly with the link command so that you are not relying on hard-coding anything.