переменные среды с Redis
у меня есть приложение Rails, которое отправляет уведомления по электронной почте с помощью Gmail (в настоящее время только в режиме разработки). Я установил имя пользователя и пароль с переменными среды, как это
GMAIL_USERNAME='me@gmail.com' GMAIL_PASSWORD='mygreatpassword' rails s
и все работает нормально. Однако после того, как я добавил sidekiq/redis для отправки электронных писем в качестве фонового задания, я получаю ошибку аутентификации при попытке отправить электронное письмо.
2013-04-24T19:26:45Z 887 TID-ovdxl6qxs WARN: {"retry"=>true, "queue"=>"default", "timeout"=>30, "class"=>"Sidekiq::Extensions::DelayedMailer", "args"=>["---n- !ruby/class 'Notifier'n- :answer_updatedn- - !ruby/object:Answern attributes:n id: 32n content: Billyn accepted: n user_id: 37n question_id: 38n created_at: 2013-04-24 19:26:44.948753000 Zn updated_at: 2013-04-24 19:26:44.948753000 Zn - !ruby/object:Usern attributes:n id: 35n email: emailaddress@gmail.comn encrypted_password: aXLIJ6F1KNPOjbTUX3fqROE0oDHgf/WnSGE4OhCm7g.pzN1bzLS0qn reset_password_token: n reset_password_sent_at: n remember_created_at: 2013-04-19 19:28:52.926838000 Zn sign_in_count: 9n current_sign_in_at: 2013-04-24 19:17:31.694245000 Zn last_sign_in_at: 2013-04-22 18:24:29.946303000 Zn current_sign_in_ip: 127.0.0.1n last_sign_in_ip: 127.0.0.1n created_at: 2013-04-18 19:28:09.569895000 Zn updated_at: 2013-04-24 19:17:31.695692000 Zn name: emailaddress@gmail.comn lawyer: n student: n"], "jid"=>"4c9cb74b27080c4df581715c", "error_message"=>"530-5.5.1 Authentication Required. Learn more atn", "error_class"=>"Net::SMTPAuthenticationError", "failed_at"=>2013-04-24 19:26:45 UTC, "retry_count"=>0}
2013-04-24T19:26:45Z 887 TID-ovdxl6qxs WARN: 530-5.5.1 Authentication Required. Learn more at
после добавления sidekiq я запустил сервер rails таким же образом, с помощью Переменные среды GMAIL_USERNAME и GMAIL_PASSWORD, предшествующие команде "rails s". Я также начал redis таким образом
redis-server /usr/local/etc/redis.conf
и sidekiq, как это
bundle exec sidekiq
затем, после добавления redis, я использовал метод "задержки" sidekiq вместо "доставки" для отправки сообщения. Однако, как отмечалось выше, я получаю сообщение об ошибке аутентификации.
def after_create(answer)
answer.question.watchers.each do |user|
Notifier.delay.answer_updated(answer, user)
# Notifier.answer_updated(answer, user).deliver
end
обновление:
это мои настройки config action mailer
config.action_mailer.smtp_settings = {
address: "smtp.gmail.com",
port: 587,
domain: "localhost:3000",
authentication: "plain",
enable_starttls_auto: true,
user_name: ENV["GMAIL_USERNAME"],
password: ENV["GMAIL_PASSWORD"]
}
это что он говорит после "узнайте больше на"
2013-04-25T00:11:30Z 6904 TID-owuofcbno WARN: /Users/me/.rbenv/versions/1.9.3-p327/lib/ruby/1.9.1/net/smtp.rb:948:in `check_response'
/Users/me/.rbenv/versions/1.9.3-p327/lib/ruby/1.9.1/net/smtp.rb:917:in `getok'
/Users/me/.rbenv/versions/1.9.3-p327/lib/ruby/1.9.1/net/smtp.rb:832:in `mailfrom'
/Users/me/.rbenv/versions/1.9.3-p327/lib/ruby/1.9.1/net/smtp.rb:659:in `send_message'
/Users/me/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/mail-2.4.4/lib/mail/network/delivery_methods/smtp.rb:145:in `block in deliver!'
/Users/me/.rbenv/versions/1.9.3-p327/lib/ruby/1.9.1/net/smtp.rb:520:in `start'
/Users/me/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/mail-2.4.4/lib/mail/network/delivery_methods/smtp.rb:144:in `deliver!'
/Users/me/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/mail-2.4.4/lib/mail/message.rb:2034:in `do_delivery'
/Users/me/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/mail-2.4.4/lib/mail/message.rb:229:in `block in deliver'
/Users/me/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/actionmailer-3.2.12/lib/action_mailer/base.rb:415:in `block in deliver_mail'
/Users/me/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/activesupport-3.2.12/lib/active_support/notifications.rb:123:in `block in instrument'
/Users/me/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/activesupport-3.2.12/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
/Users/me/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/activesupport-3.2.12/lib/active_support/notifications.rb:123:in `instrument'
/Users/me/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/actionmailer-3.2.12/lib/action_mailer/base.rb:413:in `deliver_mail'
/Users/me/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/mail-2.4.4/lib/mail/message.rb:229:in `deliver'
/Users/me/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/sidekiq-2.10.1/lib/sidekiq/extensions/action_mailer.rb:23:in `perform'
/Users/me/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/sidekiq-2.10.1/lib/sidekiq/processor.rb:49:in `block (3 levels) in process'
/Users/me/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/sidekiq-2.10.1/lib/sidekiq/middleware/chain.rb:109:in `call'
/Users/me/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/sidekiq-2.10.1/lib/sidekiq/middleware/chain.rb:109:in `block in invoke'
/Users/me/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/sidekiq-2.10.1/lib/sidekiq/middleware/server/timeout.rb:11:in `block in call'
/Users/me/.rbenv/versions/1.9.3-p327/lib/ruby/1.9.1/timeout.rb:68:in `timeout'
/Users/me/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/sidekiq-2.10.1/lib/sidekiq/middleware/server/timeout.rb:10:in `call'
/Users/me/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/sidekiq-2.10.1/lib/sidekiq/middleware/chain.rb:111:in `block in invoke'
/Users/me/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/sidekiq-2.10.1/lib/sidekiq/middleware/server/active_record.rb:6:in `call'
/Users/me/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/sidekiq-2.10.1/lib/sidekiq/middleware/chain.rb:111:in `block in invoke'
/Users/me/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/sidekiq-2.10.1/lib/sidekiq/middleware/server/retry_jobs.rb:50:in `call'
/Users/me/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/sidekiq-2.10.1/lib/sidekiq/middleware/chain.rb:111:in `block in invoke'
/Users/me/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/sidekiq-2.10.1/lib/sidekiq/middleware/server/logging.rb:11:in `block in call'
/Users/me/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/sidekiq-2.10.1/lib/sidekiq/logging.rb:22:in `with_context'
/Users/me/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/sidekiq-2.10.1/lib/sidekiq/middleware/server/logging.rb:7:in `call'
/Users/me/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/sidekiq-2.10.1/lib/sidekiq/middleware/chain.rb:111:in `block in invoke'
/Users/me/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/sidekiq-2.10.1/lib/sidekiq/middleware/chain.rb:114:in `call'
/Users/me/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/sidekiq-2.10.1/lib/sidekiq/middleware/chain.rb:114:in `invoke'
/Users/me/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/sidekiq-2.10.1/lib/sidekiq/processor.rb:48:in `block (2 levels) in process'
/Users/me/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/sidekiq-2.10.1/lib/sidekiq/processor.rb:87:in `stats'
/Users/me/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/sidekiq-2.10.1/lib/sidekiq/processor.rb:47:in `block in process'
/Users/me/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/celluloid-0.12.4/lib/celluloid/calls.rb:23:in `call'
/Users/me/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/celluloid-0.12.4/lib/celluloid/calls.rb:23:in `public_send'
/Users/me/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/celluloid-0.12.4/lib/celluloid/calls.rb:23:in `dispatch'
/Users/me/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/celluloid-0.12.4/lib/celluloid/future.rb:18:in `block in initialize'
/Users/me/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/celluloid-0.12.4/lib/celluloid/internal_pool.rb:48:in `call'
/Users/me/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/celluloid-0.12.4/lib/celluloid/internal_pool.rb:48:in `block in create'
2 ответов
Sidekiq запускает собственную среду rails и пропускает переменные среды для настройки ActionMailer, поэтому вы получаете исключение при использовании sidekiq, но не при отправке внутри самого процесса rails server.
в основном вам просто нужно запустить работника sidekiq, используя те же переменные, что и сервер:
GMAIL_USERNAME='me@gmail.com' GMAIL_PASSWORD='mygreatpwd' bundle exec sidekiq
хотя это может работать нормально, подумайте об использовании чего-то вроде старшина для обработки этого (особенно в развитие.)
Я предполагаю, что переменные среды, которые вы устанавливаете в своей консоли, применяются только к процессу вашего веб-сервера (который запускается rails s
). Поэтому, когда sidekiq смотрит на конфигурацию mailer, он возвращает ноль из ENV["GMAIL_USERNAME"]
и ENV["GMAIL_PASSWORD"]
. Вам нужно поместить эти переменные среды, где процесс sidekiq может получить к ним доступ.
я выложу несколько вариантов ниже (#2 выглядит проще всего), но уже есть несколько ресурсов, которые объяснили это в более деталь (и кредит идет к ним для компиляции этих опций). Проверьте:
- http://railsapps.github.io/rails-environment-variables.html
-
https://devcenter.heroku.com/articles/config-vars#local-setup
- при развертывании на Heroku и хочу проверить локально
- только не забудьте поставить
.env
in.gitignore
опции
настройка среды vars в bash
Я бы не рекомендовал этот метод, но хотел бы включить его в качестве контрапункта к двум вариантам ниже.
export GMAIL_USERNAME="myemail@gmail.com"
запуск этого в консоли bash создаст значение в ~/.bashrc
доступно в ENV.
это решение, однако, не является специфичным для приложения (оно доступно в любом месте на вашей машине), и оно похоронено так далеко из вашего приложения вам может быть сложно отладить проблемы или забыть удалить/изменить эту личную информацию.
Фигаро
он также предоставляет помощники для загрузки этих конфигурационных vars в heroku, сохраняя при этом конфигурацию из ваших репозиториев git.
чтение из конфигурации yml файл
это в значительной степени то, что делает драгоценный камень Фигаро, но это стоит понять.
# 1. create a config file
touch config/gmail_config.yml
# 2. add the new file to .gitignore
# 3. add code to application.rb to load yml file
config.before_configuration do
env_file = File.join(Rails.root, 'config', 'local_env.yml')
YAML.load(File.open(env_file)).each do |key, value|
ENV[key.to_s] = value
end if File.exists?(env_file)
end
если файл выходит (т. е. вы находитесь на своем локальном компьютере), он загрузит файл и установит переменную. Если файл не существует, он не будет загружать файл, и вам нужно будет установить переменную в рабочей среде.