Introduction
I was recently helping a friend set up Octobox and noticed they very handily provide a pre-built docker-compose.yml
file for Docker Compose users! Octobox (as with many other Dockerized apps) uses environment variables for configuration, so the docker-compose
command looks like this:
GITHUB_CLIENT_ID=yourclientid GITHUB_CLIENT_SECRET=yourclientsecret docker-compose up --build
For those unfamiliar with it, the GITHUB_CLIENT_ID
and GITHUB_CLIENT_SECRET
before the command are declaring environment variables for docker-compose
.
While I initially wrote this to help with Octobox setup, Octobox actually implements most of these steps already in their
docker-compose.yml
file. If you're setting up Octobox, skip down to "Going one better"; otherwise, read on!
Declare your environment with your app
But you don't want to have to remember those env vars every time you bring the application up, so let's get those out of the command line. In your docker-compose.yml
for any service
node, you can add an environment
key and include environment variables and their values in that:
services:
app:
image: ...
environment:
- VAR_NAME=value
- FOO="bar"
In the case of Octobox, the variables are already included, but other apps may not include them for you. For our Octobox configuration, we could replace the existing values in our docker-compose.yml
under the app service:
services:
app:
. . . #snipped
environment:
- GITHUB_CLIENT_ID=yourclientid
- GITHUB_CLIENT_SECRET=yourclientsecret
and we would simply run docker-compose up
as before and our environment variables would be captured and available inside the container.
Going one better
We can do one better than that! Having now included our id and secret in our docker-compose.yml
file, we must protect it very carefully, and we can't commit the file back to source control! However, since everything should be in source control and your InfoSec team would prefer your GitHub API keys weren't on the internet, there is an alternative: the .env
file.
Beside your docker-compose.yml
file, create a new text file called .env
. In it, add the following:
CLIENT_ID=yourclientid
CLIENT_SECRET=yourclientsecret
Now, open your docker-compose.yml
file again, and replace yourclientid
with ${CLIENT_ID}
and yourclientsecret
with ${CLIENT_SECRET}
. That is:
services:
app:
. . . #snipped
environment:
- GITHUB_CLIENT_ID=${CLIENT_ID}
- GITHUB_CLIENT_SECRET=${CLIENT_SECRET}
Now, when you run docker-compose up
, Docker will resolve the ${NAME}
variables to values from your .env
file. Now you can safely commit your docker-compose.yml
file without leaking your creds (as long as you don't commit the .env
file!).
Octobox includes the variables pre-declared in their provided
docker-compose.yml
so you can jump straight to adding your.env
file!
Summary
So in summary to provide environment variables to a container you can:
- Include
KEY=value
pairs in the command line right before callingdocker-compose
- Include them as an
environment
node for any service in yourdocker-compose.yml
- Add them to a
.env
file and reference them using${KEY}
syntax in yourdocker-compose.yml
file - Mix and match any of the above!
Personally I always include non-sensitive variables using method 2 (i.e. as an environment
node under the service
), but include sensitive data/secrets as variables in a .env
file (which I add to .gitignore
to prevent accidental checkins).
Note that what I've described here is only scratching the surface of how you can use environment variables in Docker (both directly and with Compose). Check out the full documentation for all the different methods available.
How do you manage your environment variables with Docker Compose? Let me know in the comments or on Twitter.