Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using linked container environment variables in application environment?

Tags:

docker

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?

like image 799
Andy Shinn Avatar asked Jun 19 '14 00:06

Andy Shinn


2 Answers

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.

like image 85
Ben Whaley Avatar answered Sep 27 '22 21:09

Ben Whaley


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.

like image 27
Greg Weber Avatar answered Sep 27 '22 20:09

Greg Weber