我有一个在 ElasticBeanstalk 中运行良好的 Rails 应用程序。我现在正尝试在 Docker Phusion Passenger Container 中运行。
我的 Dockerfile 非常简单:
FROM phusion/passenger-ruby21:0.9.13
# Set correct environment variables.
ENV HOME /root
# Use baseimage-docker's init process.
CMD ["/sbin/my_init"]
RUN rm -f /etc/service/nginx/down
RUN rm /etc/nginx/sites-enabled/default
ADD webapp.conf /etc/nginx/sites-enabled/webapp.conf
#Preserver Env Vars set at run time
ADD passenger-envvars.conf /etc/nginx/main.d/passenger-envvars.conf
ENV APP_HOME /home/app/webapp/
RUN mkdir $APP_HOME
WORKDIR /tmp
ADD Gemfile /tmp/
ADD Gemfile.lock /tmp/
RUN bundle install
ADD . $APP_HOME
当我运行容器时,Passenger 给出了以下错误:
undefined method `[]' for nil:NilClass (NoMethodError)
/home/app/webapp/config/environment.rb:11:in `<top (required)>'
config.ru:3:in `require'
config.ru:3:in `block in <main>'
/var/lib/gems/2.1.0/gems/rack-1.5.5/lib/rack/builder.rb:55:in `instance_eval'
/var/lib/gems/2.1.0/gems/rack-1.5.5/lib/rack/builder.rb:55:in `initialize'
config.ru:1:in `new'
config.ru:1:in `<main>'
/usr/share/passenger/helper-scripts/rack-preloader.rb:112:in `eval'
/usr/share/passenger/helper-scripts/rack-preloader.rb:112:in `preload_app'
/usr/share/passenger/helper-scripts/rack-preloader.rb:158:in `<module:App>'
/usr/share/passenger/helper-scripts/rack-preloader.rb:29:in `<module:PhusionPassenger>'
/usr/share/passenger/helper-scripts/rack-preloader.rb:28:in `<main>'
我的 environment.rb 文件是:
require File.expand_path('../application', __FILE__)
if ENV['C_ENVIRONMENT']
%w(RACK_ENV RAILS_ENV).each do |key|
ENV[key] = ENV['C_ENVIRONMENT']
end
Rails.env = ENV['C_ENVIRONMENT'] if defined?(Rails)
end
CONFIG = YAML.load(ERB.new(File.read("config/config.yml")).result)[Rails.env]
T_CONFIG = CONFIG["tableau"]
CM_CONFIG = CONFIG["customer_metadata"]
LDAP_CONFIG = CONFIG["ldap"]
# Initialize the rails application
Ecommerce::Application.initialize!
我已经确认 NGinx 保留了我需要的所有环境变量。困难似乎出在这行(第 11 行):
CONFIG = YAML.load(ERB.new(File.read("config/config.yml")).result)[Rails.env]
config/config.yml 文件存在,并且具有与传递给它的 RAILS_ENV 变量匹配的必要配置。
我怀疑 Docker 容器难以将文件读入内存,这可能是因为 bundle install 是以 root 身份运行的,并且没有为 Rails 读取创建必要的 CONFIG 对象。
我不是 Ruby 开发人员(我是操作人员),因此请原谅我缺乏基本的 Ruby 知识。
答案1
和往常一样,5 分钟后我就明白了。
我的 Docker 运行时命令是:
docker run -p "8888:80" -it --name myapp-passenger --env-file ./envvars myapp-passenger
该envvars
文件包含我的环境变量。我已将这些变量加双引号,例如
C_ENVIRONMENT="integration"
相反,它们应该是:
C_ENVIRONMENT=integration