我继承了在生产模式下运行时不能完全正常工作的Rails应用程序。对服务器的GET请求导致未找到路由匹配错误;但是,当服务器在开发模式下运行时,所有路由都可以工作,并且状态为200。
查看代码可以发现,除了成功的URL请求中使用的域之外,应用程序还希望有前缀的子域。
class ApplicationContext
def initialize(subdomain, host_with_port)
if subdomain.present?
case subdomain
when Rails.application.config.workninja.admin_subdomain
@environment = :admin
when Rails.application.config.workninja.mobile_subdomain
@environment = :mobile
else
@environment = :customer
end
else
raise 'Could not initialize ApplicationContext without subdomain'
end
@url_options = {subdomain: subdomain, host: host_with_port}
setup_method = "setup_#{@environment.to_s}_environment".to_sym
if respond_to?(setup_method, true)
send(setup_method, subdomain, host_with_port)
else
raise 'Unknown context environment'
end
end
attr_reader :environment
attr_reader :url_options
attr_reader :agency
def self.current
Thread.current['workninja:tenant_context']
end
def admin?
@environment == :admin
end
def mobile?
@environment == :mobile
end
def customer?
@environment == :customer
end
def ui_url_for(path, subdomain = url_options[:subdomain])
base = "#{Rails.application.config.workninja.https ? 'https' :
'http'}://#{subdomain}.#{Rails.application.config.workninja.domain}"
if Rails.application.config.workninja.html5mode
puts URI.join(base, path).to_s
else
puts URI.join(base, "/#/#{path}".gsub(/\/+/, '/')).to_s
end
end
应用程序附带的原始前端根据服务器在其中启动的环境来构造请求的URL。
{
"environment": "development",
"url": "http://admin.workninja.local:3000"
}
{
"environment": "production",
"url": "/api"
}
对我来说,生产URL没有意义,因为它所做的只是将“ / api”附加到托管前端的根域中。我只能假设它只是一个占位符,一旦它在实时环境中运行,就需要替换为托管Rails服务器的域名。该应用程序的功能开发版本中并未使用“ / api”路径,这使我进一步假设它是一个占位符。
根据以上内容,我将“ / api”替换为“ http://admin.workninja.com.au”。将应用程序托管在活动域上之后,我通过运行以下命令确认它可以正常工作:
curl http://admin.workninja.com.com.au/auth -X POST
这给了我一个关于未提供凭据的预期错误,但它表明服务器实际上正在接收某些信息。如果您尚未意识到在生产模式下启动时的rails服务器会响应POST请求,但不会响应GET。
这是我对问题的理解破裂的地方。如果
http://admin.workninja.local:3000/roles
在开发环境中工作正常(“ /角色是应用程序路线之一”)
http://admin.workninja.com.au/roles
在生产环境中也可以工作吗?您是否可以从这个事实中推断出ruby代码库中没有损坏某些东西?
以下是与生产环境中的rails应用程序的配置有关的一些文件。
/config/deploy/production.rb
set :branch, 'master'
server 'ec2-54-66-230-174.ap-southeast-2.compute.amazonaws.com', user: 'ubuntu', roles: %w{app web db worker}
/config/environments/production.rb
Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.
# Code is not reloaded between requests.
config.cache_classes = true
# Eager load code on boot. This eager loads most of Rails and
# your application in memory, allowing both threaded web servers
# and those relying on copy on write to perform better.
# Rake tasks automatically ignore this option for performance.
# This needs to be set to true in order for rails to launch in a production environment
config.eager_load = false
# Full error reports are disabled and caching is turned on.
config.consider_all_requests_local = false
config.action_controller.perform_caching = true
# Enable Rack::Cache to put a simple HTTP cache in front of your application
# Add `rack-cache` to your Gemfile before enabling this.
# For large-scale production use, consider using a caching reverse proxy like
# NGINX, varnish or squid.
# config.action_dispatch.rack_cache = true
# Disable serving static files from the `/public` folder by default since
# Apache or NGINX already handles this.
config.serve_static_files = ENV['RAILS_SERVE_STATIC_FILES'].present?
# Specifies the header that your server uses for sending files.
# config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
# config.force_ssl = true
# Use the lowest log level to ensure availability of diagnostic information
# when problems arise.
config.log_level = :warn
# Prepend all log lines with the following tags.
# config.log_tags = [ :subdomain, :uuid ]
# Use a different logger for distributed setups.
# config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new)
# Use a different cache store in production.
# config.cache_store = :mem_cache_store
# Enable serving of images, stylesheets, and JavaScripts from an asset server.
# config.action_controller.asset_host = 'http://assets.example.com'
# Ignore bad email addresses and do not raise email delivery errors.
# Set this to true and configure the email server for immediate delivery to raise delivery errors.
# config.action_mailer.raise_delivery_errors = false
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
# the I18n.default_locale when a translation cannot be found).
config.i18n.fallbacks = true
# Send deprecation notices to registered listeners.
config.active_support.deprecation = :notify
# Use default logging formatter so that PID and timestamp are not suppressed.
config.log_formatter = ::Logger::Formatter.new
# Do not dump schema after migrations.
config.active_record.dump_schema_after_migration = false
# Application hostname
config.surgeforce.domain = 'surgeforce.com.au'
config.surgeforce.https = false
config.surgeforce.html5mode = true
end
/config/puma.rb
threads 1, 6
workers Integer(ENV['PUMA_WORKERS'] || 3)
on_worker_boot do
require "active_record"
cwd = File.dirname(__FILE__)+"/.."
ActiveRecord::Base.connection.disconnect! rescue ActiveRecord::ConnectionNotEstablished
ActiveRecord::Base.establish_connection(ENV["DATABASE_URL"] || YAML.load_file("#{cwd}/config/database.yml")[ENV["RAILS_ENV"]])
end
如果您认为应用程序中的任何其他代码对调查至关重要,请告诉我,我将其包括在内。
答案 0 :(得分:1)
问题在于,Rails的subdomain
方法非常简单,对com.au
域的结构一无所知。对于您在生产中使用的"admin.workninja.com.au"
,subdomain
方法将返回"admin.workninja"
。从文档中:
将所有\ subdomains返回为一个字符串,因此
"dev.www"
将是 返回"dev.www.rubyonrails.org"
。您可以在“ www.rubyonrails.co.uk”中指定其他tld_length
,例如2以捕获"www"
而不是"www.rubyonrails"
。
而且–在不知道您的配置– "admin.workninja"
的情况下,很可能不再与您的config.workninja.admin_subdomain
配置匹配。
解决方案是在生产中使用configure a tld length of 2。只需将以下内容添加到config/environments/production.rb
中的配置块中即可:
config.action_dispatch.tld_length = 2 # Defaults to 1