Clone a repository during deployment on Heroku

50 views Asked by At

I have a Rails project PROJECTX, which is hosted on Heroku. For storing production configs and files, I am using a different repository PROJECTX-config. Is it possible to:

  1. clone PROJECTX-config,
  2. remove current config files, and
  3. symlink config files to PROJECTX-config files

Note that this has to be done on Heroku. Also I am aware that Heroku has options to maintain configs using environment variables, but this is not what I am looking for.

Thanks!

1

There are 1 answers

0
max On BEST ANSWER

No its not possible.

Each dyno gets its own ephemeral filesystem, with a fresh copy of the most recently deployed code. During the dyno’s lifetime its running processes can use the filesystem as a temporary scratchpad, but no files that are written are visible to processes in any other dyno and any files written will be discarded the moment the dyno is stopped or restarted. For example, this occurs any time a dyno is replaced due to application deployment and approximately once a day as part of normal dyno management.
- https://devcenter.heroku.com/articles/dynos#ephemeral-filesystem

Or at least not without a Rube Goldberg machine like setupe where you setup some kind of automation (like a post-commit hook) to merge repo A and repo B and push the result to heroku.

Also I believe that app config should not be present in environment variables, as it is tedious to maintain rather than maintaining a file.

Heroku does not agree here.

The traditional approach for handling such config vars is to put them under source - in a properties file of some sort. This is an error-prone process, and is especially complicated for open source apps which often have to maintain separate (and private) branches with app-specific configurations.
A better solution is to use environment variables, and keep the keys out of the code. On a traditional host or working locally you can set environment vars in your bashrc file. On Heroku, you use config vars. - https://devcenter.heroku.com/articles/config-vars

Although you might be overestimating what you actually need to store in ENV vars. You only need to store secrets such as API keys in ENV.

Other non-secret configuration such your settings for various gems can and should be setup in config/initializers.

If you still think using the GUI is that terrible then use YAML files which you parse and use to set the ENV vars:

require 'yaml'

yaml = YAML.load_file(File.join(__dir__, 'conf.yml'))

def create_key(*components)
  components.join('_').upcase
end

env_vars = yaml["production"].each_with_object({}) do |(key,value), memo|
  key_components = [key]
  if value.kind_of? Hash
    value.each_pair do |k,v|
      memo[create_key(*key_components.dup.push(k))] = v
    end
  else
    memo[create_key(*key_components)] = value
  end
end.each do |k,v|
  system("heroku config:set #{k}=#{v}")
  puts "Setting #{k} = #{v}; #{ $? }"
end

Or you could even store a serialized form (JSON or YAML) in a single env var - there is a total size limit of 32kb though.