Managing config (and secrets) in Docker builds
As of Docker 18.09 there is a much cleaner, natively supported way to achieve what this (and other) workarounds were doing.
See https://medium.com/@tonistiigi/build-secrets-and-ssh-forwarding-in-docker-18-09-ae8161d066 for details.
Fitting the pieces together for a smooth, automated and reliable continuous integration or delivery pipeline is hard.
From keeping a good test suite maintained, pulling and building dependencies to deploying via FTP or Git or Capistrano or something else. You may know all the steps there are but once you start, the details can be overwhelming.
One of those details is dealing with private dependencies, for example a composer or npm module you host privately on Github.
You might be reading this because, like me, you found it slightly more tricky than it should be to get this working. I won’t explain in too much detail the difficulties because you’ve probably already come across them. If not you either haven’t tried yet, or you’re simply smarter than me and you found it simple. Good for you!
We’re quite used to having our development SSH keys available or even using SSH forwarding in a deployment or development virtual machine. It’s harder with docker.
This article over on Cloud 66 explains some of the difficulties and also introduces a build tool, Habitus to solve the issues. Habitus looks great, but right now I’m not looking to learn and integrate a whole new tool into my already complicated workflow. I want to keep things as simple as possible.
Keypad
One solution is to run a small webserver which your Dockerfile can query to get those secrets. No environment variables or secrets hidden in docker layers to worry about.
You can do this simply with PHP or Python, as described here. In that case you’d need to install and run either one of those, and figure out your IP address (which will change as you move from work to home to a CI environment).
Keypad sits somewhere in the middle. It’s not a whole build flow tool, and it’s not a DIY hack-together a webserver. It’s a small server (~30MB) designed for just this.
docker run -d -p 80:80 outstack/keypad
Set keys:
curl --fail -X PUT http://127.0.0.1:80/secret/key -d "new secret"
Get keys:
# in your DockerfileARG KEYPAD
RUN curl --silent --fail "http://${KEYPAD}/secret/key"
The URLs can be anything — treat it like a namespace if you need to organise API keys, SSH keys or other configuration keys.
It’s not the first and it’s not perfect but it does the job. Consider it one more tool at your disposal. Check out the README on Github and let me know if you find it useful.