Docker Swarm Secrets - Reading config from files

Docker swarm uses the concept of secret files for sharing config secrets to services launched within a swarm.

I would ideally like to leverage this for passing database credentials and API keys to a service running in a swarm.

First attempt I tried this anon function defined at the top of my config/prod.exs

secret_file = 
  fn(file_path)->
    if File.exists?(file_path) do
      File.read!(file_path)
    else
       nil
    end
  end

I then used the following pattern to attempt setting config vars based on either secret files, or typical env vars passed to a release with REPLACE_OS_VARS=true

...
url: secret_file.("${DATABASE_URL_FILE}") || "${DATABASE_URL}",
...

This did not work as expected - am about to give up on reading from files and just do it from env vars…

Any suggestions or guidance on this?
Should I be defining the secret_file/1 function in a module?
Help is much appreciated!

2 Likes

I would give conform a try: https://github.com/bitwalker/conform

Allow fetching information dynamically when the configuration is evaluated.

potentially a custom type that does the File.read in one place for all the different secrets
https://hexdocs.pm/conform/custom-types.html#content

unfortunately I’m not experienced with docker swarm, and I’m yet to have to use conform - so no guarantees.

conform does seem to be the best option, was kinda hoping for something even easier… - thanks @outlog!

Will post my solution / conform custom-type when i get to it for others to reference.

2 Likes

Hi, @harmon25 what was your final solution for this? I have hit a similar roadblock.

does Config.Provider — Elixir v1.12.3 fit the bill nowadays?

Currently using config/runtime.exs for most runtime config needs.
Config providers should also work nicely!