I would like to be able to use env variables inside docker-compose.yml, with values passed in at the time of docker-compose up. This is the example. I am doing this today with basic docker run command, which is wrapped around my own script. Is there a way to achieve it with compose, without any such bash wrappers?
proxy:
hostname: $hostname
volumes:
- /mnt/data/logs/$hostname:/logs
- /mnt/data/$hostname:/data
Use .env file to define dynamic values in docker-compse.yml. Be it port or any other value.
Sample docker-compose:
Inside .env file you can define the value of these variables:
The following is applicable for docker-compose 3.x Set environment variables inside the container
Create a .env file in the same location as the docker-compose.yml
and your compose file will be like
source
It seems that docker-compose has native support now for default environment variables in file.
all you need to do is declare your variables in a file named
.env
and they will be available in docker-compose.yml.For example, for
.env
file with contents:You could access your variable inside
docker-compose.yml
or forward them into the container:The DOCKER solution:
It looks like docker-compose 1.5+ has enabled variables substitution: https://github.com/docker/compose/releases
The latest Docker Compose allows you to access environment variables from your compose file. So you can source your environment variables, then run Compose like so:
Then you can reference the variables in docker-compose.yml using ${VARIABLE}, like so:
And here is more info from the docs, taken here: https://docs.docker.com/compose/compose-file/#variable-substitution
And I believe this feature was added in this pull request: https://github.com/docker/compose/pull/1765
The BASH solution:
I notice folks have issues with Docker's environment variables support. Instead of dealing with environment variables in Docker, let's go back to basics, like bash! Here is a more flexible method using a bash script and a
.env
file.An example .env file:
then run this bash script in the same directory, which should deploy everything properly:
Just reference your env variables in your compose file with the usual bash syntax (ie
${SECRET_KEY}
to insert theSECRET_KEY
from the.env
file).Note the
COMPOSE_CONFIG
is defined in my.env
file and used in my bash script, but you can easily just replace{$COMPOSE_CONFIG}
with themy-compose-file.yml
in the bash script.Also note that I labeled this deployment by naming all of my containers with the "myproject" prefix. You can use any name you want, but it helps identify your containers so you can easily reference them later. Assuming that your containers are stateless, as they should be, this script will quickly remove and redeploy your containers according to your .env file params and your compose YAML file.
Update Since this answer seems pretty popular, I wrote a blog post that describes my Docker deployment workflow in more depth: http://lukeswart.net/2016/03/lets-deploy-part-1/ This might be helpful when you add more complexity to a deployment configuration, like nginx configs, LetsEncrypt certs, and linked containers.
As far as I know, this is a work-in-progress. They want to do it, but it's not released yet. See 1377 (the "new" 495 that was mentioned by @Andy).
I ended up implementing the "generate .yml as part of CI" approach as proposed by @Thomas.