前提: 已经把rails app部署到阿里云,已有AWS账号,并且申请了AWS
S3,记录下密钥ID和私钥,Region,Bucket_name。
设置figaro
编辑config/application.yml
production:
SEND_CLOUD_USER_NAME: xxx
SEND_CLOUD_USER_KEY: xxxxx
secret_key_base: xxxxxxx
AWS_ACCESS_KEY_ID: xxxxxxxx
AWS_SECRET_ACCESS_KEY: hIMMHPxxxxxxx
AWS_REGION: ap-northeast-1
AWS_BUCKET_NAME: xxxxx
development:
SEND_CLOUD_USER_NAME: xxx
SEND_CLOUD_USER_KEY: xxxxx
secret_key_base: xxxxxxx
AWS_ACCESS_KEY_ID: xxxxxxxx
AWS_SECRET_ACCESS_KEY: hIMMHPxxxxxxx
AWS_REGION: ap-northeast-1
AWS_BUCKET_NAME: xxxxx
安装fog
另外还有fog-aws
可以用。
添加gem 'fog'
bundle install
新增carrierwave.rb文件,touch config/initializers/carrierwave.rb
编辑这个文件:
CarrierWave.configure do |config|
if Rails.env.production? #这里同样也用条件语句写明了不同环境用什么设置。
config.fog_provider = 'fog'
config.fog_credentials = {
provider: 'AWS', #这里写明了存储服务的提供商,下面就是各种aws的key
aws_access_key_id: ENV["AWS_ACCESS_KEY_ID"], # 这样写rails就会自动去figaro之前生成的application.yml中去抓对应名称的key和信息
# 如此这些rb文件被push上去就不会泄露信息
aws_secret_access_key: ENV["AWS_SECRET_ACCESS_KEY"],
region: ENV["AWS_REGION"] # 这个区域如果不清楚就去Amazon上查下建立的储存桶的信息
}
config.fog_directory = ENV["AWS_BUCKET_NAME"] # 这里写明储存桶的名称
else #这里写明非产品环境就存储在本地。
config.storage :file
end
end
使用fog存图片
在xxx_uploader.rb中设置,当在开发模式的时候就把图片存在本地文档中,如果是在产品模式,就用fog存图片。
uploaders/house_image_uploader.rb
if Rails.env.development?
storage :file
elsif Rails.env.production?
storage :fog
end
debug
做完这些,如果是部署到heroku的,还会有一步骤是要把figaro同步到heroku,figaro heroku:set -e production
,但我们是部署到阿里云的,就没有这一步。
提交代码到github,准备部署,执行cap production deploy
,过程中会报错:
00:22 deploy:assets:precompile
01 bundle exec rake assets:precompile
01 rake aborted!
01 ArgumentError: Missing required arguments: aws_access_key_id, aws_secret_access_key
01 /home/deploy/homey/shared/bundle/ruby/2.4.0/gems/fog-core-1.45.0/lib/fog/core/service.rb:244:in `validate…
01 /home/deploy/homey/shared/bundle/ruby/2.4.0/gems/fog-core-1.45.0/lib/fog/core/service.rb:268:in `handle_s…
01 /home/deploy/homey/shared/bundle/ruby/2.4.0/gems/fog-core-1.45.0/lib/fog/core/service.rb:98:in `new'
01 /home/deploy/homey/shared/bundle/ruby/2.4.0/gems/fog-core-1.45.0/lib/fog/core/services_mixin.rb:16:in `ne…
01 /home/deploy/homey/shared/bundle/ruby/2.4.0/gems/fog-core-1.45.0/lib/fog/storage.rb:27:in `new'
...
...
大概意思是说没有aws_access_key_id
和aws_secret_access_key
,可以理解,因为如果是heroku还要同步一下figaro的信息呢,而在阿里云的时候就缺少了这一步,明显不行。
然后开figaro的git资料,看到这一段:
Other Hosts
If you're not deploying to Heroku, you have two options:
Generate a remote configuration file
Set ENV variables directly
Generating a remote configuration file is preferred because of:
familiarity – Management of config/application.yml is like that of config/database.yml.
isolation – Multiple applications on the same server will not produce configuration key collisions.
大概意思大概是让我们自己建立一个application.yml放到云服务器了,只要不是放在github里就好。于是我连接远程服务器,在/appname/shared/config
下和/appname/current/config
两个地方都创建了application.yml
,并且把内容贴进去,保存退出。
再次运行,发现同样的问题还在!但是进入到远程服务器的console,用Figaro.env.aws_access_key_id
来测试又是能显示密钥来的。
irb(main):003:0> ENV["AWS_ACCESS_KEY_ID"]
=> "AKIAJNP35BSxxxxxxxxx"
irb(main):004:0> Figaro.env.AWS_ACCESS_KEY_ID
=> "AKIAJNP35BSxxxxxxxxx"
irb(main):005:0>
到底问题出在哪里?继续查资料,直到我看到这样的一段话:
And finally if we deploy application with Capistrano we have to deploy it properly. We should put local_env.yml to the Capistrano shared folder on the server and change config/deploy.rb like this:
before 'deploy:assets:precompile', :symlink_config_files
desc "Link shared files"
task :symlink_config_files do
symlinks = {
"#{shared_path}/config/database.yml" => "#{release_path}/config/database.yml",
"#{shared_path}/config/local_env.yml" => "#{release_path}/config/local_env.yml"
}
run symlinks.map{|from, to| "ln -nfs #{from} #{to}"}.join(" && ")
end
得到一些灵感,在自己的rails application中找到config/deploy.rb
,里面有一行是:
append :linked_files, "config/database.yml", "config/secrets.yml"
我把application.yml加到后面去:
append :linked_files, "config/database.yml", "config/secrets.yml", "config/application.yml"
再次尝试,部署成功!