【问题标题】:Environment variables locally and Heroku本地环境变量和 Heroku
【发布时间】:2013-03-17 21:47:02
【问题描述】:

我有一个 sinatra 应用程序,其中我有一个 yml 文件来设置环境变量,我使用这种方法调用它们

module MyConfig

 def config
  environment = ENV["RACK_ENV"] || "development"
  YAML.load_file("./config/config.yml")[environment]
 end
 end

所以当我想使用变量时,我会这样做

aws_access_key_id = config['aws_access_key']

例如,我有一个 .gitignore 文件在推送到 github 时会忽略 config.yml。所以当我推送到 heroku 时,这些环境变量将无法访问?

所以这让我可以使用 heroku 方式来设置它们

heroku config:add aws_access_key= myapikey

但是 heroku 访问这些就像

aws_access_key_id = ENV['aws_access_key']

如何将我的开发环境设置为使用方法配置和 heroku 使用 ENV,我看错了吗?还是我的配置方法为我做这个?

任何帮助表示赞赏

瑞克文件

  require 'active_support/core_ext'
  require './config/config.rb'
  require 'bundler/setup'
  Bundler.require(:default)

   include MyConfig

  AssetSync.configure do |con|
  con.fog_provider = 'AWS'
  con.fog_region = 'eu-west-1'
  con.fog_directory = config['fog_directory']
  con.aws_access_key_id = config['aws_access_key']
  con.aws_secret_access_key = config['aws_secret_key']
  con.prefix = "assets"
  con.public_path = Pathname("./public")
  end

 namespace :assets do
 desc "Precompile assets"
 task :precompile do
  AssetSync.sync
 end
end

【问题讨论】:

    标签: heroku sinatra environment-variables gitignore foreman


    【解决方案1】:

    更新:

    我现在使用dotenv gem 代替下面的示例。因此,我现在使用 Git 忽略 .env 文件,而不是忽略 env.rb 文件。

    原帖:

    试试这个,

    # /env.rb
    
    ENV['aws_bucket'] = 'my_bucket'
    ENV['aws_access_key'] = 'my_access_key'
    ENV['aws_access_secret'] = 'my_access_secret'
    

    此文件设置与heroku config 相同的ENV 值。

    # /config.rb
    
    require './env' if File.exists?('env.rb')
    

    env.rb 仅在存在时才需要。

    # /.gitignore
    
    /env.rb
    

    env.rb 已添加到 .gitignore 文件中,因此它不会保存在 Git 中。

    然后您将使用ENV['key'] 而不是config['key'] 访问这些值。

    如果env.rbconfig.rb 文件不在同一目录中,您可能需要更改它的路径。

    编辑:

    从上一个问题中查看您的Rakefile,您需要将其更改为:

    # Rakefile
    
    require 'bundler/setup'
    Bundler.require(:default)
    require './env' if File.exists?('env.rb')
    
    AssetSync.configure do |con|
     con.fog_provider = 'AWS'
     con.fog_region = 'eu-west-1'
     con.fog_directory = ENV['aws_bucket']
     con.aws_access_key_id = ENV['aws_access_key']
     con.aws_secret_access_key = ENV['aws_access_secret']
     con.prefix = "assets"
     con.public_path = Pathname("./public")
    end
    
    namespace :assets do
      desc "Precompile assets"
      task :precompile do
        AssetSync.sync
      end
    end
    

    我假设/config/config.rb 中的唯一方法是config 方法,所以我删除了,

    require './config/config.rb'
    include MyConfig
    

    并将config[key] 替换为env.rb 中定义的ENV[key] 值。您可能需要更改 key 名称以匹配。

    【讨论】:

    • 再次感谢您的帮助 Sam,这次在运行 heroku run rake assets:precompile 我得到 No such file or directory - /config/config.yml,我理解它在 .gitignore 中文件?任何想法如何解决这个问题?
    • 尝试删除YAML.load_file("./config/config.yml")[environment]。由于您已将 YAML 文件替换为 env.rb 文件,因此不再需要包含它。
    • 是的,我试过了,但是我得到了未定义的方法或局部变量配置,因为我的 rake 文件调用了该方法,我发布了 rakefile
    • 您必须将所有 YAML config[key] 属性移动到 env.rb 并将它们更改为 ENV[key] 属性。然后删除MyConfig中对config[key]方法的所有引用。
    • 非常感谢,所以如果我不打算使用 heroku,我可以坚持使用 config.yml 方式,但是即使我没有使用 heroku,你的方法也同样有效
    【解决方案2】:

    您可以删除 yaml,并在 .env 文件中描述环境变量,然后使用 foreman start 启动您的应用程序。见https://devcenter.heroku.com/articles/config-vars#local-setup


    或者保留你的混合系统,在 dev 中加载一个 yaml,并在 heroku 上使用环境变量。

    【讨论】:

      【解决方案3】:

      我做了一些类似于 Sam 的建议的事情,但有点不同。我也有一个 YAML 配置文件,但我将读取它的内容包装在一个 Rake 任务中,然后运行该应用程序。

      # in the Rakefile
      
      require 'yaml'
      
      def set_connstring
        s = %Q!postgres://#{ENV["DB_APP"]}@localhost/#{ENV["DB_APP"]}!
        ENV['DATABASE_URL'] ||= ENV["RACK_ENV"] == "test" ? "#{s}.test" : s
      end
      
      
      def basic_environment
        warn "  Setting up environment..."
      
        file = File.expand_path( File.join File.dirname(__FILE__), "./config.yml" )
        if File.exist? file
          YAML.load_file(file).each do |k,v|
            warn "-> #{k}"
            ENV[k.upcase] = v
          end
        end
      
        set_connstring()
      end
      
      namespace :app do
      
        desc "Set up the environment locally"
        task :environment do
          basic_environment()
        end
      
        desc "Run the app locally"
        task :run_local => "app:environment" do
          exec "bin/rackup config.ru -p #{ENV['RUN_LOCAL_PORT']}"
        end
      end
      

      这意味着我可以在本地运行它,而无需应用程序内部的任何代码来处理这个问题。


      编辑:顺便说一句,我注意到你的 Rakefile 中有Bundler.require(:default)。如果您使用bundle install --binstubs,那么 Bundler 会将所有可执行文件安装到项目中名为“bin/”的目录中。然后,如果您运行任何这些可执行文件,它们会自动使用 Bundler 安装的库,而无需通过 Bundler。见http://gembundler.com/v1.2/man/bundle-exec.1.html

      【讨论】:

        【解决方案4】:

        直接从 heroku admin 导出: 设置 -> 显示配置变量

        然后打开浏览器 js 控制台,粘贴这个并输入回车...

        k=[];
        $(".config-var-list input").map(function(y, x){k.push($(x).val())});
        v=[];
        $(".config-var-list textarea").map(function(y, x){v.push($(x).val())});
        ret="";
        k.map(function(x, i){ret+=k[i]+"\t"+v[2*i]+"\n"});
        console.info(ret);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-05-19
          • 1970-01-01
          • 2014-03-16
          • 1970-01-01
          • 2018-03-25
          • 2021-12-26
          • 2017-06-25
          • 2018-06-14
          相关资源
          最近更新 更多