I have a base docker image which is used to run image analysis software. For each container created from the image, there are a set of configuration settings, some of which are secrets (encryption keys, customer information, etc.), that are used by the software to analyze and distribute the processed images. How can I safely pass these secrets to a container?
You have 3 methods to get secrets to an app inside a docker container. The first 2 involve docker configuration. The last one is to have your apps directly fetch secrets from a secret store.
1 - Environment variables
According to "The 12 Factor App" guide, secrets are merely config, and they should always be set in the environment. You could set your secrets as environment variables during the docker run, and your app accesses them from there.
2 - Mounted volumes
You could have your secrets all within a particular configuration/secrets file, then mount that to your instance as a mounted volume.
3 - Fetch from secret store
As @030 mentioned, you can use Hashicorp Vault (or "Amazon Secrets Manager", or any service like that).
Your app, or a sidecar app can fetch the secrets it needs directly, without having to deal with any configuration on the Docker container. This method would allow you to use Dynamically created secrets (a very appealing feature of such systems) and without having to worry about the secrets being view-able from the file system or from inspecting the env variables of the docker container.
I believe env variables is the way to go. It's easier to manage, and you can still pull from a secret store like Hashicorp Vault, if you have you CI build system pull the secrets during the build and set them when you deploy. You get the best of both worlds, and the added benefit of your developers not needing to write application code to fetch secrets.
Devs should be focused on their code functionality, and not dealing with admin tasks like fetching passwords.
Your application's code should be focused on it's own app functionality itself, and not dealing with backend tasks like fetching passwords. Just like the 12 Factor App states.
Edit: changed last sentence to remove implication of Developer vs SysAdmin silo-ing. The tasks themselves should be separate from a code perspective, but DevOps is about the same persons keeping both in mind and not be limited.
Personal Opinion (Update)
Per @Dirk's excellent comment (Passing secrets to a Docker container), there is a very strong argument to prioritize a secret store over ENV vars, due to not wanting to leak them.
There is another option only using pipe:
docker run -d -i --name $n alpine sh -c 'read A; echo "[$A]"; exec some-server' docker exec -i $n sh -c 'cat > /proc/1/fd/0' <<< _a_secret_
First, create the docker daemon with
-i, the command
read A will hang waiting for the input from
Then run the second docker command, reading the secret from stdin and redirect to the last hanging process.