为暂存应用和生产应用使用不同的S3存储桶

7
我有一个使用Amazon S3存储Paperclip附件的Rails应用程序。我的database.yml文件分别为开发、测试和生产指定了不同的S3桶。
我在Heroku上有两个应用程序 - 一个生产应用程序和一个“暂存应用程序”,用于在启动前在平台上测试代码。
当前系统存在一个重要缺陷 - 它在暂存和生产中使用相同的S3桶。我该如何设置我的系统,使其根据是否编写git push production mastergit push staging master来使用不同的桶?

你如何编写你的Paperclip配置文件? - apneadiving
Apnea,你在说哪个文件? - sscirrus
在你的模型中,你如何将S3配置传递给Paperclip? - apneadiving
@apneadiving - 在每个具有附件的模型中,我都有这行代码 has_attached_file :whatever, :storage => :s3, :s3_credentials => "#{::Rails.root.to_s}/config/s3.yml", :path => "/whatever/:style/:id/:normalized_file_name" - sscirrus
2个回答

12

Heroku允许您通过持久性环境变量来配置任何您喜欢的内容,每个应用程序中的dyno / process都会使用这些变量启动。在同一应用程序的staging和production版本之间,环境变量不会共享。好好利用这一点。

has_attached_file :photo, 
  :styles => ...,
  :path => ...,
  :storage => :s3,
  :bucket => ENV['S3_BUCKET'], # <--- over here
  :s3_credentials => {
    :access_key_id => ENV['S3_KEY'],
    :secret_access_key => ENV['S3_SECRET']
  }

接下来:

# Configure the "staging" instance
$ heroku config:add \
    RACK_ENV=production \
    S3_KEY=my-staging-key \
    S3_SECRET=my-staging-secret \
    S3_BUCKET=my-staging-bucket \
    --app my-staging-app-name

# Configure the "production" instance
$ heroku config:add \
    RACK_ENV=production \
    S3_KEY=my-production-key \
    S3_SECRET=my-production-secret \
    S3_BUCKET=my-production-bucket \
    --app my-production-app-name
请注意,您的应用程序的每个实例都有一个RACK_ENV=production。不要使用Rails环境来区分应用程序的不同实例。相反,您的应用程序应该期望使用环境变量来配置特定于实例的方面。

是的,我在“staging”实例中设置了RACK_ENV=production。这是因为在Heroku上,您可以使用环境变量来配置所有内容,而不需要Rails环境的帮助。在您的 production.rb 中,您当然可以基于存在性、缺失或环境变量的值来设置属性,在您的Heroku“staging”环境中,这就是您应该做的。 - yfeldblum
非常感谢您提供这个超级有用的答案!我的问题是,当我尝试使用RACK_ENV=development和RAILS_ENV=development更改环境时,我一直收到错误消息,指出“错误R10(启动超时)-> Web进程在启动后60秒内未能绑定到$PORT”,这是为什么呢? - Kevin Zhao

1
在您的staging box上设置config:add RACK_ENV=staging,然后在您的代码中,您可以根据环境指定bucket。例如:
if Rails.env.production?
    has_attached_file :photo, 
    :styles => ...,
    :path => ...,
    :storage => :s3,
    :bucket => 'your_prod_bucket',
    :s3_credentials => {
      :access_key_id => ENV['S3_KEY'],
      :secret_access_key => ENV['S3_SECRET']
    }
  else
    has_attached_file :photo, 
    :styles => ...,
    :path => ...,
    :storage => :s3,
    :bucket => 'your_staging_bucket',
    :s3_credentials => {
      :access_key_id => ENV['S3_KEY'],
      :secret_access_key => ENV['S3_SECRET']
    }

  end

这篇Heroku文章似乎也表明,您可以通过为暂存和生产使用不同的S3凭据来轻松实现此目的。我猜您还需要在Amazon方面进行一些配置。无论如何,请看一下它是否有所帮助。 http://devcenter.heroku.com/articles/config-vars

3
我会把凭据存储在config/environments/文件夹中,避免在代码中散布潜在的条件逻辑。 - d11wtq

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接