1 # -*- encoding: binary -*-
2 # frozen_string_literal: false
5 # Implements a simple DSL for configuring a unicorn server.
7 # See https://yhbt.net/unicorn/examples/unicorn.conf.rb and
8 # https://yhbt.net/unicorn/examples/unicorn.conf.minimal.rb
9 # example configuration files. An example config file for use with
10 # nginx is also available at
11 # https://yhbt.net/unicorn/examples/nginx.conf
13 # See the link:/TUNING.html document for more information on tuning unicorn.
14 class Unicorn::Configurator
18 attr_accessor :set, :config_file, :after_reload
20 # used to stash stuff for deferred processing of cli options in
21 # config.ru after "working_directory" is bound. Do not rely on
22 # this being around later on...
25 :host => Unicorn::Const::DEFAULT_HOST,
26 :port => Unicorn::Const::DEFAULT_PORT,
27 :set_listener => false,
28 :options => { :listeners => [] }
31 # Default settings for Unicorn
34 :logger => Logger.new($stderr),
35 :worker_processes => 1,
36 :after_fork => lambda { |server, worker|
37 server.logger.info("worker=#{worker.nr} spawned pid=#{$$}")
39 :before_fork => lambda { |server, worker|
40 server.logger.info("worker=#{worker.nr} spawning...")
42 :before_exec => lambda { |server|
43 server.logger.info("forked child re-executing...")
45 :after_worker_exit => lambda { |server, worker, status|
46 m = "reaped #{status.inspect} worker=#{worker.nr rescue 'unknown'}"
50 server.logger.error(m)
53 :after_worker_ready => lambda { |server, worker|
54 server.logger.info("worker=#{worker.nr} ready")
57 :early_hints => false,
58 :worker_exec => false,
59 :preload_app => false,
60 :check_client_connection => false,
61 :rewindable_input => true,
62 :client_body_buffer_size => Unicorn::Const::MAX_BODY,
66 def initialize(defaults = {}) #:nodoc:
67 self.set = Hash.new(:unset)
68 @use_defaults = defaults.delete(:use_defaults)
69 self.config_file = defaults.delete(:config_file)
71 # after_reload is only used by unicorn_rails, unsupported otherwise
72 self.after_reload = defaults.delete(:after_reload)
74 set.merge!(DEFAULTS) if @use_defaults
75 defaults.each { |key, value| self.__send__(key, value) }
76 Hash === set[:listener_opts] or
77 set[:listener_opts] = Hash.new { |hash,key| hash[key] = {} }
78 Array === set[:listeners] or set[:listeners] = []
82 def reload(merge_defaults = true) #:nodoc:
83 if merge_defaults && @use_defaults
84 set.merge!(DEFAULTS) if @use_defaults
86 instance_eval(File.read(config_file), config_file) if config_file
90 RACKUP[:set_listener] and
91 set[:listeners] << "#{RACKUP[:host]}:#{RACKUP[:port]}"
93 RACKUP[:no_default_middleware] and
94 set[:default_middleware] = false
96 # unicorn_rails creates dirs here after working_directory is bound
97 after_reload.call if after_reload
99 # working_directory binds immediately (easier error checking that way),
100 # now ensure any paths we changed are correctly set.
101 [ :pid, :stderr_path, :stdout_path ].each do |var|
102 String === (path = set[var]) or next
103 path = File.expand_path(path)
104 File.writable?(path) || File.writable?(File.dirname(path)) or \
105 raise ArgumentError, "directory for #{var}=#{path} not writable"
109 def commit!(server, options = {}) #:nodoc:
110 skip = options[:skip] || []
111 if ready_pipe = RACKUP.delete(:ready_pipe)
112 server.ready_pipe = ready_pipe
114 if set[:check_client_connection]
115 set[:listeners].each do |address|
116 if set[:listener_opts][address][:tcp_nopush] == true
118 "check_client_connection is incompatible with tcp_nopush:true"
122 set.each do |key, value|
123 value == :unset and next
124 skip.include?(key) and next
125 server.__send__("#{key}=", value)
129 def [](key) # :nodoc:
133 # sets object to the +obj+ Logger-like object. The new Logger-like
134 # object must respond to the following methods:
140 # The default Logger will log its output to the path specified
141 # by +stderr_path+. If you're running Unicorn daemonized, then
142 # you must specify a path to prevent error messages from going
145 %w(debug info warn error fatal).each do |m|
146 obj.respond_to?(m) and next
147 raise ArgumentError, "logger=#{obj} does not respond to method=#{m}"
153 # sets after_fork hook to a given block. This block will be called by
154 # the worker after forking. The following is an example hook which adds
155 # a per-process listener to every worker:
157 # after_fork do |server,worker|
158 # # per-process listener ports for debugging/admin:
159 # addr = "127.0.0.1:#{9293 + worker.nr}"
161 # # the negative :tries parameter indicates we will retry forever
162 # # waiting on the existing process to exit with a 5 second :delay
163 # # Existing options for Unicorn::Configurator#listen such as
164 # # :backlog, :rcvbuf, :sndbuf are available here as well.
165 # server.listen(addr, :tries => -1, :delay => 5, :backlog => 128)
167 def after_fork(*args, &block)
168 set_hook(:after_fork, block_given? ? block : args[0])
171 # sets after_worker_exit hook to a given block. This block will be called
172 # by the master process after a worker exits:
174 # after_worker_exit do |server,worker,status|
175 # # status is a Process::Status instance for the exited worker process
176 # unless status.success?
177 # server.logger.error("worker process failure: #{status.inspect}")
181 # after_worker_exit is only available in unicorn 5.3.0+
182 def after_worker_exit(*args, &block)
183 set_hook(:after_worker_exit, block_given? ? block : args[0], 3)
186 # sets after_worker_ready hook to a given block. This block will be called
187 # by a worker process after it has been fully loaded, directly before it
188 # starts responding to requests:
190 # after_worker_ready do |server,worker|
191 # server.logger.info("worker #{worker.nr} ready, dropping privileges")
192 # worker.user('username', 'groupname')
195 # Do not use Configurator#user if you rely on changing users in the
196 # after_worker_ready hook.
198 # after_worker_ready is only available in unicorn 5.3.0+
199 def after_worker_ready(*args, &block)
200 set_hook(:after_worker_ready, block_given? ? block : args[0])
203 # sets before_fork got be a given Proc object. This Proc
204 # object will be called by the master process before forking
206 def before_fork(*args, &block)
207 set_hook(:before_fork, block_given? ? block : args[0])
210 # sets the before_exec hook to a given Proc object. This
211 # Proc object will be called by the master process right
212 # before exec()-ing the new unicorn binary. This is useful
213 # for freeing certain OS resources that you do NOT wish to
214 # share with the reexeced child process.
215 # There is no corresponding after_exec hook (for obvious reasons).
216 def before_exec(*args, &block)
217 set_hook(:before_exec, block_given? ? block : args[0], 1)
220 # Strongly consider using link:/Application_Timeouts.html instead
221 # of this misfeature. This misfeature has done decades of damage
222 # to Ruby since it demotivates the use of fine-grained timeout
225 # Sets the timeout of worker processes to +seconds+. Workers
226 # handling the request/app.call/response cycle taking longer than
227 # this time period will be forcibly killed (via SIGKILL). This
228 # timeout is enforced by the master process itself and not subject
229 # to the scheduling limitations by the worker process. Due the
230 # low-complexity, low-overhead implementation, timeouts of less
231 # than 3.0 seconds can be considered inaccurate and unsafe.
233 # For running Unicorn behind nginx, it is recommended to set
234 # "fail_timeout=0" for in your nginx configuration like this
235 # to have nginx always retry backends that may have had workers
236 # SIGKILL-ed due to timeouts.
238 # upstream unicorn_backend {
239 # # for UNIX domain socket setups:
240 # server unix:/path/to/.unicorn.sock fail_timeout=0;
243 # server 192.168.0.7:8080 fail_timeout=0;
244 # server 192.168.0.8:8080 fail_timeout=0;
245 # server 192.168.0.9:8080 fail_timeout=0;
248 # See https://nginx.org/en/docs/http/ngx_http_upstream_module.html
249 # for more details on nginx upstream configuration.
251 set_int(:timeout, seconds, 3)
252 # POSIX says 31 days is the smallest allowed maximum timeout for select()
253 max = 30 * 60 * 60 * 24
254 set[:timeout] = seconds > max ? max : seconds
257 # Whether to exec in each worker process after forking. This changes the
258 # memory layout of each worker process, which is a security feature designed
259 # to defeat possible address space discovery attacks. Note that using
260 # worker_exec only makes sense if you are not preloading the application,
261 # and will result in higher memory usage.
263 # worker_exec is only available in unicorn 5.3.0+
264 def worker_exec(bool)
265 set_bool(:worker_exec, bool)
268 # sets the current number of worker_processes to +nr+. Each worker
269 # process will serve exactly one client at a time. You can
270 # increment or decrement this value at runtime by sending SIGTTIN
271 # or SIGTTOU respectively to the master process without reloading
272 # the rest of your Unicorn configuration. See the SIGNALS document
273 # for more information.
274 def worker_processes(nr)
275 set_int(:worker_processes, nr, 1)
278 # sets whether to add default middleware in the development and
279 # deployment RACK_ENVs.
281 # default_middleware is only available in unicorn 5.5.0+
282 def default_middleware(bool)
283 set_bool(:default_middleware, bool)
286 # sets whether to enable the proposed early hints Rack API.
287 # If enabled, Rails 5.2+ will automatically send a 103 Early Hint
288 # for all the `javascript_include_tag` and `stylesheet_link_tag`
289 # in your response. See: https://api.rubyonrails.org/v5.2/classes/ActionDispatch/Request.html#method-i-send_early_hints
290 # See also https://tools.ietf.org/html/rfc8297
291 def early_hints(bool)
292 set_bool(:early_hints, bool)
295 # sets listeners to the given +addresses+, replacing or augmenting the
296 # current set. This is for the global listener pool shared by all
297 # worker processes. For per-worker listeners, see the after_fork example
298 # This is for internal API use only, do not use it in your Unicorn
299 # config file. Use listen instead.
300 def listeners(addresses) # :nodoc:
301 Array === addresses or addresses = Array(addresses)
302 addresses.map! { |addr| expand_addr(addr) }
303 set[:listeners] = addresses
306 # Adds an +address+ to the existing listener set. May be specified more
307 # than once. +address+ may be an Integer port number for a TCP port, an
308 # "IP_ADDRESS:PORT" for TCP listeners or a pathname for UNIX domain sockets.
310 # listen 3000 # listen to port 3000 on all TCP interfaces
311 # listen "127.0.0.1:3000" # listen to port 3000 on the loopback interface
312 # listen "/path/to/.unicorn.sock" # listen on the given Unix domain socket
313 # listen "[::1]:3000" # listen to port 3000 on the IPv6 loopback interface
315 # When using Unix domain sockets, be sure:
316 # 1) the path matches the one used by nginx
317 # 2) uses the same filesystem namespace as the nginx process
318 # For systemd users using PrivateTmp=true (for either nginx or unicorn),
319 # this means Unix domain sockets must not be placed in /tmp
321 # The following options may be specified (but are generally not needed):
323 # [:backlog => number of clients]
325 # This is the backlog of the listen() syscall.
327 # Some operating systems allow negative values here to specify the
328 # maximum allowable value. In most cases, this number is only
329 # recommendation and there are other OS-specific tunables and
330 # variables that can affect this number. See the listen(2)
331 # syscall documentation of your OS for the exact semantics of
334 # If you are running unicorn on multiple machines, lowering this number
335 # can help your load balancer detect when a machine is overloaded
336 # and give requests to a different machine.
340 # Note: with the Linux kernel, the net.core.somaxconn sysctl defaults
341 # to 128, capping this value to 128. Raising the sysctl allows a
342 # larger backlog (which may not be desirable with multiple,
343 # load-balanced machines).
345 # [:rcvbuf => bytes, :sndbuf => bytes]
347 # Maximum receive and send buffer sizes (in bytes) of sockets.
349 # These correspond to the SO_RCVBUF and SO_SNDBUF settings which
350 # can be set via the setsockopt(2) syscall. Some kernels
351 # (e.g. Linux 2.4+) have intelligent auto-tuning mechanisms and
352 # there is no need (and it is sometimes detrimental) to specify them.
354 # See the socket API documentation of your operating system
355 # to determine the exact semantics of these settings and
356 # other operating system-specific knobs where they can be
359 # Defaults: operating system defaults
361 # [:tcp_nodelay => true or false]
363 # Disables Nagle's algorithm on TCP sockets if +true+.
365 # Setting this to +true+ can make streaming responses in Rails 3.1
366 # appear more quickly at the cost of slightly higher bandwidth usage.
367 # The effect of this option is most visible if nginx is not used,
368 # but nginx remains highly recommended with unicorn.
370 # This has no effect on UNIX sockets.
372 # Default: +true+ (Nagle's algorithm disabled) in unicorn
373 # This defaulted to +false+ in unicorn 3.x
375 # [:tcp_nopush => true or false]
377 # Enables/disables TCP_CORK in Linux or TCP_NOPUSH in FreeBSD
379 # This prevents partial TCP frames from being sent out and reduces
380 # wakeups in nginx if it is on a different machine. Since unicorn
381 # is only designed for applications that send the response body
382 # quickly without keepalive, sockets will always be flushed on close
385 # This has no effect on UNIX sockets.
388 # This defaulted to +true+ in unicorn 3.4 - 3.7
390 # [:ipv6only => true or false]
392 # This option makes IPv6-capable TCP listeners IPv6-only and unable
393 # to receive IPv4 queries on dual-stack systems. A separate IPv4-only
394 # listener is required if this is true.
396 # Enabling this option for the IPv6-only listener and having a
397 # separate IPv4 listener is recommended if you wish to support IPv6
398 # on the same TCP port. Otherwise, the value of \env[\"REMOTE_ADDR\"]
399 # will appear as an ugly IPv4-mapped-IPv6 address for IPv4 clients
400 # (e.g ":ffff:10.0.0.1" instead of just "10.0.0.1").
402 # Default: Operating-system dependent
404 # [:reuseport => true or false]
406 # This enables multiple, independently-started unicorn instances to
407 # bind to the same port (as long as all the processes enable this).
409 # This option must be used when unicorn first binds the listen socket.
410 # It cannot be enabled when a socket is inherited via SIGUSR2
411 # (but it will remain on if inherited), and it cannot be enabled
412 # directly via SIGHUP.
414 # Note: there is a chance of connections being dropped if
415 # one of the unicorn instances is stopped while using this.
417 # This is supported on *BSD systems and Linux 3.9 or later.
419 # ref: https://lwn.net/Articles/542629/
421 # Default: false (unset)
423 # [:tries => Integer]
425 # Times to retry binding a socket if it is already in use
427 # A negative number indicates we will retry indefinitely, this is
428 # useful for migrations and upgrades when individual workers
429 # are binding to different ports.
433 # [:delay => seconds]
435 # Seconds to wait between successive +tries+
437 # Default: 0.5 seconds
441 # Sets the file mode creation mask for UNIX sockets. If specified,
442 # this is usually in octal notation.
444 # Typically UNIX domain sockets are created with more liberal
445 # file permissions than the rest of the application. By default,
446 # we create UNIX domain sockets to be readable and writable by
447 # all local users to give them the same accessibility as
448 # locally-bound TCP listeners.
450 # This has no effect on TCP listeners.
452 # Default: 0000 (world-read/writable)
454 # [:tcp_defer_accept => Integer]
456 # Defer accept() until data is ready (Linux-only)
458 # For Linux 2.6.32 and later, this is the number of retransmits to
459 # defer an accept() for if no data arrives, but the client will
460 # eventually be accepted after the specified number of retransmits
461 # regardless of whether data is ready.
463 # For Linux before 2.6.32, this is a boolean option, and
464 # accepts are _always_ deferred indefinitely if no data arrives.
465 # This is similar to <code>:accept_filter => "dataready"</code>
468 # Specifying +true+ is synonymous for the default value(s) below,
469 # and +false+ or +nil+ is synonymous for a value of zero.
471 # A value of +1+ is a good optimization for local networks
472 # and trusted clients. There is no good reason to ever
473 # disable this with a +zero+ value with unicorn.
477 # [:accept_filter => String]
479 # defer accept() until data is ready (FreeBSD-only)
481 # This enables either the "dataready" or (default) "httpready"
482 # accept() filter under FreeBSD. This is intended as an
483 # optimization to reduce context switches with common GET/HEAD
486 # There is no good reason to change from the default.
488 # Default: "httpready"
489 def listen(address, options = {})
490 address = expand_addr(address)
491 if String === address
492 [ :umask, :backlog, :sndbuf, :rcvbuf, :tries ].each do |key|
493 value = options[key] or next
495 raise ArgumentError, "not an integer: #{key}=#{value.inspect}"
497 [ :tcp_nodelay, :tcp_nopush, :ipv6only, :reuseport ].each do |key|
498 (value = options[key]).nil? and next
499 TrueClass === value || FalseClass === value or
500 raise ArgumentError, "not boolean: #{key}=#{value.inspect}"
502 unless (value = options[:delay]).nil?
504 raise ArgumentError, "not numeric: delay=#{value.inspect}"
506 set[:listener_opts][address].merge!(options)
509 set[:listeners] << address
512 # sets the +path+ for the PID file of the unicorn master process
513 def pid(path); set_path(:pid, path); end
515 # Enabling this preloads an application before forking worker
516 # processes. This allows memory savings when using a
517 # copy-on-write-friendly GC but can cause bad things to happen when
518 # resources like sockets are opened at load time by the master
519 # process and shared by multiple children. People enabling this are
520 # highly encouraged to look at the before_fork/after_fork hooks to
521 # properly close/reopen sockets. Files opened for logging do not
522 # have to be reopened as (unbuffered-in-userspace) files opened with
523 # the File::APPEND flag are written to atomically on UNIX.
525 # In addition to reloading the unicorn-specific config settings,
526 # SIGHUP will reload application code in the working
527 # directory/symlink when workers are gracefully restarted when
528 # preload_app=false (the default). As reloading the application
529 # sometimes requires RubyGems updates, +Gem.refresh+ is always
530 # called before the application is loaded (for RubyGems users).
532 # During deployments, care should _always_ be taken to ensure your
533 # applications are properly deployed and running. Using
534 # preload_app=false (the default) means you _must_ check if
535 # your application is responding properly after a deployment.
536 # Improperly deployed applications can go into a spawn loop
537 # if the application fails to load. While your children are
538 # in a spawn loop, it is is possible to fix an application
539 # by properly deploying all required code and dependencies.
540 # Using preload_app=true means any application load error will
541 # cause the master process to exit with an error.
543 def preload_app(bool)
544 set_bool(:preload_app, bool)
547 # Toggles making \env[\"rack.input\"] rewindable.
548 # Disabling rewindability can improve performance by lowering
549 # I/O and memory usage for applications that accept uploads.
550 # Keep in mind that the Rack 1.x spec requires
551 # \env[\"rack.input\"] to be rewindable,
552 # but the Rack 2.x spec does not.
554 # +rewindable_input+ defaults to +true+ for compatibility.
555 # Setting it to +false+ may be safe for applications and
556 # frameworks developed for Rack 2.x and later.
557 def rewindable_input(bool)
558 set_bool(:rewindable_input, bool)
561 # The maximum size (in +bytes+) to buffer in memory before
562 # resorting to a temporary file. Default is 112 kilobytes.
563 # This option has no effect if "rewindable_input" is set to
565 def client_body_buffer_size(bytes)
566 set_int(:client_body_buffer_size, bytes, 0)
569 # When enabled, unicorn will check the client connection by writing
570 # the beginning of the HTTP headers before calling the application.
572 # This will prevent calling the application for clients who have
573 # disconnected while their connection was queued.
575 # This only affects clients connecting over Unix domain sockets
576 # and TCP via loopback (127.*.*.*). It is unlikely to detect
577 # disconnects if the client is on a remote host (even on a fast LAN).
579 # This option cannot be used in conjunction with :tcp_nopush.
580 def check_client_connection(bool)
581 set_bool(:check_client_connection, bool)
584 # Allow redirecting $stderr to a given path. Unlike doing this from
585 # the shell, this allows the unicorn process to know the path its
586 # writing to and rotate the file if it is used for logging. The
587 # file will be opened with the File::APPEND flag and writes
588 # synchronized to the kernel (but not necessarily to _disk_) so
589 # multiple processes can safely append to it.
591 # If you are daemonizing and using the default +logger+, it is important
592 # to specify this as errors will otherwise be lost to /dev/null.
593 # Some applications/libraries may also triggering warnings that go to
594 # stderr, and they will end up here.
595 def stderr_path(path)
596 set_path(:stderr_path, path)
599 # Same as stderr_path, except for $stdout. Not many Rack applications
600 # write to $stdout, but any that do will have their output written here.
601 # It is safe to point this to the same location a stderr_path.
602 # Like stderr_path, this defaults to /dev/null when daemonized.
603 def stdout_path(path)
604 set_path(:stdout_path, path)
607 # sets the working directory for Unicorn. This ensures SIGUSR2 will
608 # start a new instance of Unicorn in this directory. This may be
609 # a symlink, a common scenario for Capistrano users. Unlike
610 # all other Unicorn configuration directives, this binds immediately
611 # for error checking and cannot be undone by unsetting it in the
612 # configuration file and reloading.
613 def working_directory(path)
614 # just let chdir raise errors
615 path = File.expand_path(path)
617 ! config_file.start_with?('/') &&
618 ! File.readable?("#{path}/#{config_file}")
620 "config_file=#{config_file} would not be accessible in" \
621 " working_directory=#{path}"
624 Unicorn::HttpServer::START_CTX[:cwd] = ENV["PWD"] = path
627 # Runs worker processes as the specified +user+ and +group+.
628 # The master process always stays running as the user who started it.
629 # This switch will occur after calling the after_fork hook, and only
630 # if the Worker#user method is not called in the after_fork hook
631 # +group+ is optional and will not change if unspecified.
633 # Do not use Configurator#user if you rely on changing users in the
634 # after_worker_ready hook. Instead, you need to call Worker#user
635 # directly in after_worker_ready.
636 def user(user, group = nil)
637 # raises ArgumentError on invalid user/group
639 Etc.getgrnam(group) if group
640 set[:user] = [ user, group ]
643 # expands "unix:path/to/foo" to a socket relative to the current path
644 # expands pathnames of sockets if relative to "~" or "~username"
645 # expands "*:port and ":port" to "0.0.0.0:port"
646 def expand_addr(address) #:nodoc:
647 return "0.0.0.0:#{address}" if Integer === address
648 return address unless String === address
651 when %r{\Aunix:(.*)\z}
654 File.expand_path(address)
655 when %r{\A(?:\*:)?(\d+)\z}
657 when %r{\A\[([a-fA-F0-9:]+)\]\z}, %r/\A((?:\d+\.){3}\d+)\z/
658 canonicalize_tcp($1, 80)
659 when %r{\A\[([a-fA-F0-9:]+)\]:(\d+)\z}, %r{\A(.*):(\d+)\z}
660 canonicalize_tcp($1, $2.to_i)
667 def set_int(var, n, min) #:nodoc:
668 Integer === n or raise ArgumentError, "not an integer: #{var}=#{n.inspect}"
669 n >= min or raise ArgumentError, "too low (< #{min}): #{var}=#{n.inspect}"
673 def canonicalize_tcp(addr, port)
674 packed = Socket.pack_sockaddr_in(port, addr)
675 port, addr = Socket.unpack_sockaddr_in(packed)
676 addr.include?(':') ? "[#{addr}]:#{port}" : "#{addr}:#{port}"
679 def set_path(var, path) #:nodoc:
681 when NilClass, String
688 def check_bool(var, bool) # :nodoc:
693 raise ArgumentError, "#{var}=#{bool.inspect} not a boolean"
696 def set_bool(var, bool) #:nodoc:
697 set[var] = check_bool(var, bool)
700 def set_hook(var, my_proc, req_arity = 2) #:nodoc:
703 arity = my_proc.arity
704 (arity == req_arity) or \
706 "#{var}=#{my_proc.inspect} has invalid arity: " \
707 "#{arity} (need #{req_arity})"
709 my_proc = DEFAULTS[var]
711 raise ArgumentError, "invalid type: #{var}=#{my_proc.inspect}"
716 # this is called _after_ working_directory is bound. This only
717 # parses the embedded switches in .ru files
718 # (for "rackup" compatibility)
719 def parse_rackup_file # :nodoc:
720 ru = RACKUP[:file] or return # we only return here in unit tests
722 # :rails means use (old) Rails autodetect
724 File.readable?('config.ru') or return
728 File.readable?(ru) or
729 raise ArgumentError, "rackup file (#{ru}) not readable"
731 # it could be a .rb file, too, we don't parse those manually
732 ru.end_with?('.ru') or return
734 /^#\\(.*)/ =~ File.read(ru) or return
735 RACKUP[:optparse].parse!($1.split(/\s+/))
737 if RACKUP[:daemonize]
738 # unicorn_rails wants a default pid path, (not plain 'unicorn')
741 pid('tmp/pids/unicorn.pid') if spid.nil? || spid == :unset
743 unless RACKUP[:daemonized]
744 Unicorn::Launcher.daemonize!(RACKUP[:options])
745 RACKUP[:ready_pipe] = RACKUP[:options].delete(:ready_pipe)