How do you access environment variables exported in Bash from inside docker-compose?
I’m essentially trying to do what’s described in this answer but I don’t want to define a .env
file.
I just want to make a call like:
export TEST_NAME=test_widget_abc
docker-compose -f docker-compose.yml -p myproject up --build --exit-code-from myproject_1
and have it pass TEST_NAME
to the command inside my Dockerfile, which runs a unittest suite like:
ENV TEST_NAME ${TEST_NAME}
CMD python manage.py test $TEST_NAME
My goal is to allow running my docker container to execute a specific unittest without having to rebuild the entire image, by simply pulling in the test name from the shell at container runtime. Otherwise, if no test name is given, the command will run all tests.
As I understand, you can define environment variables in a .env
file and then reference them in your docker-compose.yml like:
version: "3.6"
services:
app_test:
build:
args:
- TEST_NAME=$TEST_NAME
context: ..
dockerfile: Dockerfile
but that doesn’t pull from the shell.
How would you do this with docker-compose?
2
Answers
Environment variables in your
docker-compose.yaml
will be substituted with values from the environment. For example, if I write:Then if I export
TEST_NAME
in my local environment:And bring up the stack:
I see that
TEST_NAME
inside the container has received the value from my local environment.It looks like you’re trying to pass the environment variable into your image build process, rather than passing it in at runtime. Even if that works once, it’s not going to be useful, because
docker-compose
won’t rebuild your image every time you run it, so whatever value was inTEST_NAME
at the time the image was built is what you would see inside the container.It’s better to pass the environment into the container at run time.
For the setup you describe, I’d
docker-compose run
a temporary containerThis uses all of the setup from the
docker-compose.yml
file except theports:
, and it uses the command you provide instead of the Composecommand:
or DockerfileCMD
. It will honordepends_on:
constraints to start related containers (you may need an entrypoint wrapper script to actually wait for them to be running).If the test code is built into your "normal" image you may not even need special Compose setup to do this; just point
docker-compose run
at your existing application service definition without defining a dedicated service for the integration tests.Since Compose does (simple) environment variable substitution you could also provide the per-execution
command:
in your Compose fileOr, with the Dockerfile you have, pass through the host’s environment variable; the
CMD
will run a shell to interpret the string when it starts upThese would both work with the Dockerfile and Compose setup you show in the question.