.bashrc 환경 변수에 Amazon S3 자격 증명을 저장하면 Rails 앱이 실패합니다.
-
20-09-2019 - |
문제
Paplip을 사용하여 Amazon S3에 물건을 저장하는 Rails 앱을 개발하고 있습니다. 이 앱은 Heroku에서 호스팅됩니다. 나는 Ubuntu Karmic에서 개발 중입니다.
내가 설명하려는 문제는 개발 (내 지역 호스트)과 생산 (Heroku)에서 발생합니다.
S3 Creds를 Pachclip에 전달하는 표준 방법은 config/s3.yml과 같은 것입니다.
access_key_id: 12345678
secret_access_key: 903490409fdf09fshsfdoif/43432
내가 이것을 할 때, 모든 것이 잘 작동합니다. 그러나 이것은 내 코드를 다른 사람들과 공유하기가 어렵 기 때문에 Heroku는 대체 방법을 제안합니다. http://docs.heroku.com/config-vars.
그들은 당신이 당신의 s3_key와 s3_secret를 당신의 .bashrc에 넣어야한다고 조언합니다.
S3_KEY=12345678
export S3_KEY
S3_SECRET=903490409fdf09fshsfdoif/43432
export S3_SECRET
그런 다음 구성/이니셜 라이저/S3.yml (약간 다른 경로 참고)을 작성하고 다음을 해당 파일에 넣을 것을 제안합니다.
AWS::S3::Base.establish_connection!(
:access_key_id => ENV['S3_KEY'],
:secret_access_key => ENV['S3_SECRET']
)
그러나이 작업을 수행하면 종이 클립이 흔들림을 던지고 다음 오류 메시지를 뱉어냅니다.
undefined method `stringify_keys' for #<String:0xb6d6c3f4>
/vendor/plugins/paperclip/lib/paperclip/storage.rb:176:in `parse_credentials'
/vendor/plugins/paperclip/lib/paperclip/storage.rb:138:in `extended'
/vendor/plugins/paperclip/lib/paperclip/storage.rb:137:in `instance_eval'
/vendor/plugins/paperclip/lib/paperclip/storage.rb:137:in `extended'
.... other stuff
스토리지 내부에서 모든 것이 분명히 시작됩니다. 스택 추적을 통해 스텝핑 :
176 행의 parse_credentials 메소드가 표시되었습니다. 코드에 나타나는 호출은 다음과 같습니다.
def parse_credentials creds
creds = find_credentials(creds).stringify_keys
(creds[RAILS_ENV] || creds).symbolize_keys
end
parse_credentials 방법은 다른 방법 인 find_credentials를 호출하려고 시도하며 이것이 문제가 있다고 생각하는 곳입니다. 그녀는 find_credentials의 코드입니다.
def find_credentials creds
case creds
when File
YAML::load(ERB.new(File.read(creds.path)).result)
when String
YAML::load(ERB.new(File.read(creds)).result)
when Hash
creds
else
raise ArgumentError, "Credentials are not a path, file, or hash."
end
end
find_credentials 메소드가 .bashrc 파일에서 값을 읽을 수있는 방법을 알 수 없습니다. Yaml에서 읽을 수있는 두 가지와 해시를 찾고있는 두 가지 사례가 있습니다.
내 모델은 다음과 같은 자격 증명을 참조합니다.
has_attached_file :photo,
(some code removed)
:s3_credentials => "#{RAILS_ROOT}/config/initializers/s3.yml",
모델에서 s3_credentials 해시를 제거하면 Stringify_keys 오류가 사라지고 Rails 콘솔은 find_credentials 메소드의 끝에 나타나는 오류 메시지를 던졌습니다. "자격 증명은 경로, 파일 또는 해시"가 아닙니다.
그래서 난 그만 둔다. 나는 이것이 Heroku의 사람들에게 질문 일 것임을 알고 있으며 (실제로 그들이 대답 할 수 있기를 희망 하여이 링크를 이메일로 보내려고합니다) Thoughtbot의 Doods에게도 질문 일 것입니다.
처음에 말했듯이, 내 키와 비밀을 config/s3.yml에 고착시키는 표준 접근 방식을 취할 때 앱은 잘 작동하지만 Heroku가 제안하는 방법을 사용하는 것이 좋습니다. 이는 공개 GitHub 페이지에 저장소를 저장할 수 있도록 다른 사람들이 GIT에 운전자 병합 드라이버를 작성하여 API 키를 공개 도메인에서 벗어나지 않아도 사용할 수 있도록 저장할 수 있음을 의미합니다.
etc/bash.bashrc와 ~/.bashrc에 ENV 변수를 고수하려고 시도했으며 재부팅 후에도 여전히 같은 문제가 있습니다. 문제는 개발 기계와 Heroku에서도 발생합니다. Config-Vars도 Heroku로 밀어 넣었습니다.
해결책
많은 검색 후 여기에서 답을 찾았습니다. http://tammersaleh.com/posts/managing-heroku-environment-variables-for-local-development
속임수는 S3.RB 파일을 모두 제거하고 다음과 같은 모델의 ENV 변수를 참조하는 것입니다.
has_attached_file :photo,
#...
:storage => :s3,
:bucket => ENV['S3_BUCKET'],
:s3_credentials => { :access_key_id => ENV['S3_KEY'],
:secret_access_key => ENV['S3_SECRET'] }
어쨌든, 데이비드, 제안 해주셔서 감사합니다. Heroku 문서를 업데이트하여 일부 사용자가 이런 식으로 수행해야한다고 말하고 싶은지 모르겠습니다. 그래도 다시 감사합니다.
다른 팁
파일의 이름을 바꿉니다 config/initializers/s3.yml
에게 config/initializers/s3.rb
그리고 그것을 시도하십시오.
여기에 문제가 있습니다.
:bucket => ENV['S3_BUCKET'],
될 필요가있다
:bucket => <%= ENV['S3_BUCKET'] %>,
즉, 과제는 해석되지 않습니다.