前提: 已經把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"
再次嘗試,部署成功!