2 $stdin.sync
= $stdout.sync
= $stderr.sync
= true
3 require 'unicorn' # require this first to populate Unicorn::DEFAULT_START_CTX
7 rails_pid
= File
.join(Unicorn
::HttpServer::DEFAULT_START_CTX[:cwd],
8 "/tmp/pids/unicorn.pid")
9 cmd
= File
.basename($0)
12 options
= { :listeners => listeners
}
13 host
, port
= Unicorn
::Const::DEFAULT_HOST, 3000
14 ENV['RAILS_ENV'] ||= "development"
15 map_path
= ENV['RAILS_RELATIVE_URL_ROOT']
17 opts
= OptionParser
.new("", 24, ' ') do |opts
|
18 opts
.banner
= "Usage: #{cmd} " \
19 "[ruby options] [#{cmd} options] [rackup config file]"
20 opts
.separator
"Ruby options:"
23 opts
.on("-e", "--eval LINE", "evaluate a LINE of code") do |line
|
24 eval line
, TOPLEVEL_BINDING
, "-e", lineno
28 opts
.on("-d", "--debug", "set debugging flags (set $DEBUG to true)") do
32 opts
.on("-w", "--warn", "turn warnings on for your script") do
36 opts
.on("-I", "--include PATH",
37 "specify $LOAD_PATH (may be used more than once)") do |path
|
38 $LOAD_PATH.unshift(*path
.split(/:/))
41 opts
.on("-r", "--require LIBRARY",
42 "require the library, before executing your script") do |library
|
46 opts
.separator
"#{cmd} options:"
48 # some of these switches exist for rackup command-line compatibility,
50 opts
.on("-o", "--host HOST",
51 "listen on HOST (default: #{Unicorn::Const::DEFAULT_HOST})") do |h
|
55 opts
.on("-p", "--port PORT", "use PORT (default: #{port})") do |p
|
59 opts
.on("-E", "--env ENVIRONMENT",
60 "use ENVIRONMENT for defaults (default: development)") do |e
|
64 opts
.on("-D", "--daemonize", "run daemonized in the background") do |d
|
65 daemonize
= d
? true : false
68 # Unicorn-specific stuff
69 opts
.on("-l", "--listen {HOST:PORT|PATH}",
70 "listen on HOST:PORT or PATH",
71 "this may be specified multiple times",
72 "(default: #{Unicorn::Const::DEFAULT_LISTEN})") do |address
|
76 opts
.on("-c", "--config-file FILE", "Unicorn-specific config file") do |f
|
77 options
[:config_file] = File
.expand_path(f
)
80 opts
.on("-P", "--path PATH", "Runs Rails app mounted at a specific path.",
85 # I'm avoiding Unicorn-specific config options on the command-line.
86 # IMNSHO, config options on the command-line are redundant given
87 # config files and make things unnecessarily complicated with multiple
88 # places to look for a config option.
90 opts
.separator
"Common options:"
92 opts
.on_tail("-h", "--help", "Show this message") do
97 opts
.on_tail("-v", "--version", "Show version") do
98 puts
" v#{Unicorn::Const::UNICORN_VERSION}"
105 require 'pp' if $DEBUG
107 # Loads Rails and the private version of Rack it bundles. Returns a
108 # lambda of arity==0 that will return *another* lambda of arity==1
109 # suitable for using inside Rack::Builder.new block.
110 rails_loader
= lambda
do ||
112 require 'config/boot'
113 defined?(::RAILS_ROOT) or abort
"RAILS_ROOT not defined by config/boot"
114 defined?(::RAILS_ENV) or abort
"RAILS_ENV not defined by config/boot"
115 defined?(::Rails::VERSION::STRING) or
116 abort
"Rails::VERSION::STRING not defined by config/boot"
118 abort
"#$0 must be run inside RAILS_ROOT (#{::RAILS_ROOT})"
121 if ENV['UNICORN_RAILS_USE_SYSTEM_RACK'].to_i
== 0
122 rails_ver
= Rails
::VERSION::STRING
124 # maps Rails versions to the vendorized Rack version they bundle
127 # 3.0.0 => false, # assuming 3.0.0 doesn't need vendorized Rack anymore
129 rack_ver
= version_map
[rails_ver
] or
130 warn
"Possibly unsupported Rails version: v#{rails_ver}"
134 when String
, NilClass
135 version_map
.values
.find_all
{ |v
| String
=== v
}.sort
.each
do |v
|
136 $LOAD_PATH.grep(%r
{/actionpack-[\d\.]+/lib
/?\z
}).each
do |path
|
137 rack_path
= File
.join(path
, "action_controller/vendor/rack-#{v}")
138 File
.directory
?(rack_path
) and break
144 "Unable to find Rails-vendorized Rack library.\n" \
145 "Perhaps this script is no longer with your" \
146 "Rails version (#{rails_ver}).\n")
147 puts
"vendorized Rack load path #{rack_path}"
148 $LOAD_PATH.unshift(rack_path
)
150 # using non-vendorized rack library (most likely via gems)
152 end # Vendorized Rack LOAD_PATH finder
154 # require Rack as late as possible in case $LOAD_PATH is modified
155 # in config.ru or command-line
159 config
= ::ARGV[0] || (File
.exist
?('config.ru') ? 'config.ru' : nil)
163 require "#{RAILS_ROOT}/config/environment"
164 ActionController
::Dispatcher.new
167 raw
= File
.open(config
, "rb") { |fp
| fp
.sysread(fp
.stat
.size
) }
168 # parse embedded command-line options in config.ru comments
170 opts
.parse
! $1.split(/\s+/)
171 require 'pp' if $DEBUG
173 lambda
{ || eval("Rack::Builder.new {(#{raw}\n)}.to_app", nil, config
) }
177 Object
.const_get(File
.basename(config
, '.rb').capitalize
)
182 # this won't run until after forking if preload_app is false
184 inner_app
= rails_loader
.call
185 require 'active_support'
186 require 'action_controller'
187 ActionController
::Base.relative_url_root
= map_path
if map_path
189 use Rails
::Rack::LogTailer unless daemonize
190 use Rails
::Rack::Debugger if $DEBUG
191 map(map_path
|| '/') do
192 use Rails
::Rack::Static
199 listener
= "#{host}:#{port}"
200 listeners
<< listener
205 :unicorn_options => options
,
207 :daemonize => daemonize
,
211 # only daemonize if we're not inheriting file descriptors from our parent
213 options
[:pid] = rails_pid
214 $stdin.reopen("/dev/null")
215 unless ENV['UNICORN_FD']
221 # We don't do a lot of standard daemonization stuff:
222 # * $stderr/$stderr can/will be redirected separately
223 # * umask is whatever was set by the parent process at startup
224 # and can be set in config.ru and config_file, so making it
225 # 0000 and potentially exposing sensitive log data can be bad
227 # * Don't bother to chdir here since Unicorn is designed to
228 # run inside APP_ROOT. Unicorn will also re-chdir() to
229 # the directory it was started in when being re-executed
230 # to pickup code changes if the original deployment directory
231 # is a symlink or otherwise got replaced.
234 # ensure Rails standard tmp paths exist
235 %w(cache pids sessions sockets
).each
do |dir
|
236 FileUtils
.mkdir_p("tmp/#{dir}")
238 Unicorn
.run(app
, options
)