Хранение учетных данных Amazon S3 в переменных среды .bashrc приводит к сбою приложения Rails

StackOverflow https://stackoverflow.com/questions/2260957

Вопрос

Я разрабатываю приложение rails, которое использует paperclip для хранения материалов на Amazon S3.Приложение размещено на Heroku.Я разрабатываю на Ubuntu Karmic.

Проблема, которую я собираюсь описать, возникает при разработке (на моем локальном хостинге) и производстве (на Heroku).


Стандартный способ передачи S3 creds в paperclip - поместить их в 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

Затем они предлагают вам создать config/initializers/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 

Совершенно очевидно, что все это начинается внутри модуля storage.rb.Пошаговое выполнение трассировки стека:

Метод parse_credentials в строке 176 помечен - вот вызов в том виде, в каком он отображается в коде:

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 (которым я на самом деле собираюсь отправить по электронной почте эту ссылку в надежде, что они смогут ответить на него), и это также, возможно, вопрос к doods из thoughtbot.

Как я уже говорил в начале, мое приложение отлично работает, когда я использую стандартный подход вставки моего ключа и секрета в config / s3.yml, но я бы предпочел использовать метод, предложенный Heroku, потому что это значительно упрощает для меня задачу и означает, что я могу сохранить свой репозиторий на моей общедоступной странице github для использования другими, без необходимости писать какие-либо драйверы слияния клиентов в Git, чтобы мои ключи API не были общедоступными.

Я попытался вставить переменные ENV в etc / bash.bashrc, а также ~ /.bashrc, и после перезагрузки у меня все та же проблема.Проблемы возникают как на компьютере разработки, так и на Heroku.Я позаботился о том, чтобы перенести свои конфигурационные переменные и в 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 docs, чтобы сказать, что некоторым пользователям приходилось делать это таким образом.Но все же еще раз спасибо.

Другие советы

Переименуйте файл config/initializers/s3.yml Для config/initializers/s3.rb и дайте ему попробовать.

Вот в чем ваша проблема:

:bucket         => ENV['S3_BUCKET'],

должно быть

:bucket         => <%= ENV['S3_BUCKET'] %>,

т. е.задания не интерпретируются.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top