First let me say thanks for Unicorn, it has helped us fill a gap that Passenger could not fill. Like many using Rails, we use capistrano for deployment. At the end of each deployment we use the standard capistrano deploy:cleanup task to remove old releases. Everything is fine until we cleanup the release directory from which unicorn_rails was originally launched. When this happens we get an error in our unicorn error log. reloading config_file=/home/deploy/public_html/rm/releases/20091116213921/config/unicorn.rb error reloading config_file=/home/deploy/public_html/rm/releases/20091116213921/config/unicorn.rb: Errno::ENOENT No such file or directory - /home/deploy/public_html/rm/releases/20091116213921/config/unicorn.rb I''m sure I''m not the only who has experienced this. Does anyone have any recommendations for handling this situation? Best regards, Michael Guterl
On Tue, Nov 17, 2009 at 12:50 PM, Michael Guterl <mguterl at gmail.com> wrote:> First let me say thanks for Unicorn, it has helped us fill a gap that > Passenger could not fill. > > Like many using Rails, we use capistrano for deployment. ?At the end > of each deployment we use the standard capistrano deploy:cleanup task > to remove old releases. ?Everything is fine until we cleanup the > release directory from which unicorn_rails was originally launched. > When this happens we get an error in our unicorn error log. > > reloading config_file=/home/deploy/public_html/rm/releases/20091116213921/config/unicorn.rb > error reloading > config_file=/home/deploy/public_html/rm/releases/20091116213921/config/unicorn.rb: > Errno::ENOENT No such file or directory - > /home/deploy/public_html/rm/releases/20091116213921/config/unicorn.rb > > I''m sure I''m not the only who has experienced this. ?Does anyone have > any recommendations for handling this situation? >I should also point out that in my unicorn logs when I start the app it references the path in it''s symbolic link form: I, [2009-11-17T17:06:10.215485 #30857] INFO -- : unlinking existing socket=/home/deploy/public_html/rm/current/tmp/sockets/unicorn.sock I, [2009-11-17T17:06:10.227485 #30857] INFO -- : listening on addr=/home/deploy/public_html/rm/current/tmp/sockets/unicorn.sock fd=3 I, [2009-11-17T17:06:10.227485 #30857] INFO -- : Refreshing Gem list But when I send HUP to restart, it references the actual path, not the symlink. reloading config_file=/home/deploy/public_html/rm/releases/20091117215841/config/unicorn.rb Refreshing Gem list done reloading config_file=/home/deploy/public_html/rm/releases/20091117215841/config/unicorn.rb Best regards, Michael Guterl
Michael Guterl <mguterl at gmail.com> wrote:> First let me say thanks for Unicorn, it has helped us fill a gap that > Passenger could not fill. > > Like many using Rails, we use capistrano for deployment. At the end > of each deployment we use the standard capistrano deploy:cleanup task > to remove old releases. Everything is fine until we cleanup the > release directory from which unicorn_rails was originally launched. > When this happens we get an error in our unicorn error log. > > reloading config_file=/home/deploy/public_html/rm/releases/20091116213921/config/unicorn.rb > error reloading > config_file=/home/deploy/public_html/rm/releases/20091116213921/config/unicorn.rb: > Errno::ENOENT No such file or directory - > /home/deploy/public_html/rm/releases/20091116213921/config/unicorn.rb > > I''m sure I''m not the only who has experienced this. Does anyone have > any recommendations for handling this situation?Hi Michael, Unicorn was definitely implemented with Cap in mind. Which version of Unicorn are you running? 0.94.0 got better symlink detection for non-GNU/Linux systems, so if you start in /home/deploy/public_html/rm/current, then it should detect it and use /home/deploy/public_html/rm/current/config/unicorn.rb. If you don''t start in your "current" symlink dir, 0.94.0 also got support for "working_directory" in your config file. -- Eric Wong
On Tue, Nov 17, 2009 at 5:20 PM, Eric Wong <normalperson at yhbt.net> wrote:> Michael Guterl <mguterl at gmail.com> wrote: >> First let me say thanks for Unicorn, it has helped us fill a gap that >> Passenger could not fill. >> >> Like many using Rails, we use capistrano for deployment. ?At the end >> of each deployment we use the standard capistrano deploy:cleanup task >> to remove old releases. ?Everything is fine until we cleanup the >> release directory from which unicorn_rails was originally launched. >> When this happens we get an error in our unicorn error log. >> >> reloading config_file=/home/deploy/public_html/rm/releases/20091116213921/config/unicorn.rb >> error reloading >> config_file=/home/deploy/public_html/rm/releases/20091116213921/config/unicorn.rb: >> Errno::ENOENT No such file or directory - >> /home/deploy/public_html/rm/releases/20091116213921/config/unicorn.rb >> >> I''m sure I''m not the only who has experienced this. ?Does anyone have >> any recommendations for handling this situation? > > Hi Michael, > > Unicorn was definitely implemented with Cap in mind. ?Which version of > Unicorn are you running? ?0.94.0 got better symlink detection for > non-GNU/Linux systems, so if you start in > /home/deploy/public_html/rm/current, then it should detect it and use > /home/deploy/public_html/rm/current/config/unicorn.rb. >I am using unicorn v0.94.0 on Ubuntu 8.04.> If you don''t start in your "current" symlink dir, 0.94.0 also got > support for "working_directory" in your config file. >I set this option in my config, however, it did not help. After some experimentation I realized the problem is in the script I use for managing unicorn via /etc/init.d -- http://gist.github.com/237953 Essentially start does this: cd ~/public_html/rm/current unicorn_rails -D -E production -c config/unicorn.rb I determined the -c config/unicorn.rb was the problem. If I change it to: unicorn_rails -D -E production -c ~/public_html/rm/current/config/unicorn.rb everything works fine. My updated init script is located at http://gist.github.com/237958 and it seems to work fine. Best regards, Michael Guterl
Michael Guterl <mguterl at gmail.com> wrote:> cd ~/public_html/rm/current > unicorn_rails -D -E production -c config/unicorn.rb > > I determined the -c config/unicorn.rb was the problem. If I change it to: > > unicorn_rails -D -E production -c ~/public_html/rm/current/config/unicorn.rb > > everything works fine.Hmm, maybe the config file path shouldn''t be expanded then. Especially since it''s only specified in the command-line. /me ponders a bit... -- Eric Wong
On Wed, Nov 18, 2009 at 12:21 PM, Eric Wong <normalperson at yhbt.net> wrote:> Michael Guterl <mguterl at gmail.com> wrote: >> cd ~/public_html/rm/current >> unicorn_rails -D -E production -c config/unicorn.rb >> >> I determined the -c config/unicorn.rb was the problem. ?If I change it to: >> >> unicorn_rails -D -E production -c ~/public_html/rm/current/config/unicorn.rb >> >> everything works fine. > > Hmm, maybe the config file path shouldn''t be expanded then. ?Especially > since it''s only specified in the command-line. ?/me ponders a bit... >I don''t mean to hijack my own thread, but the problem seems to be closely related. My application code is not being reloaded, when I send HUP to the unicorn master process. I get the following output in my log: reloading config_file=/home/deploy/public_html/rm/current/config/unicorn.rb Refreshing Gem list done reloading config_file=/home/deploy/public_html/rm/current/config/unicorn.rb reaped #<Process::Status: pid=7720,exited(0)> worker=0 reaped #<Process::Status: pid=7718,exited(0)> worker=3 listening on addr=127.0.0.1:9293 fd=6 worker=0 ready listening on addr=127.0.0.1:9296 fd=6 worker=3 ready reaped #<Process::Status: pid=7721,exited(0)> worker=1 reaped #<Process::Status: pid=7717,exited(0)> worker=2 listening on addr=127.0.0.1:9294 fd=7 worker=1 ready listening on addr=127.0.0.1:9295 fd=6 worker=2 ready My unicorn config is here: http://gist.github.com/238167 I am using Rails 2.3.2 (shame, shame, I know), but there are areas of incompatibility we cannot currently fix. If there is anything else I can provide to help, please let me know. Best regards, Michael Guterl
Michael Guterl <mguterl at gmail.com> wrote:> On Wed, Nov 18, 2009 at 12:21 PM, Eric Wong <normalperson at yhbt.net> wrote: > > Michael Guterl <mguterl at gmail.com> wrote: > >> cd ~/public_html/rm/current > >> unicorn_rails -D -E production -c config/unicorn.rb > >> > >> I determined the -c config/unicorn.rb was the problem. ?If I change it to: > >> > >> unicorn_rails -D -E production -c ~/public_html/rm/current/config/unicorn.rb > >> > >> everything works fine. > > > > Hmm, maybe the config file path shouldn''t be expanded then. ?Especially > > since it''s only specified in the command-line. ?/me ponders a bit... > > > > I don''t mean to hijack my own thread, but the problem seems to be > closely related. My application code is not being reloaded, when I > send HUP to the unicorn master process.Hi Michael, Application code is only reloaded by HUP when your preload_app setting is false. Otherwise you have to use USR2 + QUIT to upgrade your entire process. This behavior is documented in the Configurator, but not in the SIGNALS documented, I''ll fix the SIGNALS document in a few and disable expand_path in the launcher scripts. -- Eric Wong
Eric Wong <normalperson at yhbt.net> wrote:> Michael Guterl <mguterl at gmail.com> wrote: > > I don''t mean to hijack my own thread, but the problem seems to be > > closely related. My application code is not being reloaded, when I > > send HUP to the unicorn master process. > > Hi Michael, > > Application code is only reloaded by HUP when your preload_app setting > is false. Otherwise you have to use USR2 + QUIT to upgrade your entire > process. > > This behavior is documented in the Configurator, but not in the SIGNALS > documented, I''ll fix the SIGNALS document in a few and disable > expand_path in the launcher scripts.Just pushed the following change out for the SIGNALS doc. http://unicorn.bogomips.org/SIGNALS.html diff --git a/SIGNALS b/SIGNALS index 5c7295e..be96892 100644 --- a/SIGNALS +++ b/SIGNALS @@ -9,7 +9,12 @@ Unicorn and nginx. === Master Process -* HUP - reload config file, app, and gracefully restart all workers +* HUP - reloads config file and gracefully restart all workers. + If the "preload_app" directive is false (the default), then workers + will also pick up any application code changes when restarted. If + "preload_app" is true, then application code changes will have no + effect; USR2 + QUIT (see below) must be used to load newer code in + this case. * INT/TERM - quick shutdown, kills all workers immediately -- Eric Wong
Eric Wong <normalperson at yhbt.net> wrote:> Michael Guterl <mguterl at gmail.com> wrote: > > cd ~/public_html/rm/current > > unicorn_rails -D -E production -c config/unicorn.rb > > > > I determined the -c config/unicorn.rb was the problem. If I change it to: > > > > unicorn_rails -D -E production -c ~/public_html/rm/current/config/unicorn.rb > > > > everything works fine. > > Hmm, maybe the config file path shouldn''t be expanded then. Especially > since it''s only specified in the command-line. /me ponders a bit...Hi Michael, Just pushed this out, too. This should work better for you with: unicorn_rails -D -E production -c config/unicorn.rb Oddly, this has been a problem since the beginning of time and probably confused a good amount of people. Thanks Michael for finally bringing it to my attention. Most folks I know favor absolute ones (including myself), and don''t hit this problem... Of course let me know if I broke something for anyone, I hope not...>From 15217fe1162a400fa1cd2216e395d9f17be8083e Mon Sep 17 00:00:00 2001From: Eric Wong <normalperson at yhbt.net> Date: Wed, 18 Nov 2009 17:28:12 -0800 Subject: [PATCH] Do not expand paths given on the shell Shells already expand ''~'' before the executables see it, and relative paths inside symlinks can get set incorrectly to the actual directory name, and not the (usually desired) symlink name for things like Capistrano. Since our paths are now unexpanded, we must now check the "working_directory" directive and raise an error if the user specifies the config file in a way that makes the config file unreloadable. --- bin/unicorn | 4 +- bin/unicorn_rails | 2 +- lib/unicorn/configurator.rb | 7 ++++++ test/exec/test_exec.rb | 51 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 3 deletions(-) diff --git a/bin/unicorn b/bin/unicorn index 225e819..325afb3 100755 --- a/bin/unicorn +++ b/bin/unicorn @@ -68,7 +68,7 @@ opts = OptionParser.new("", 24, '' '') do |opts| opts.on("-P", "--pid FILE", "DEPRECATED") do |f| warn %q{Use of --pid/-P is strongly discouraged} warn %q{Use the ''pid'' directive in the Unicorn config file instead} - options[:pid] = File.expand_path(f) + options[:pid] = f end opts.on("-s", "--server SERVER", @@ -85,7 +85,7 @@ opts = OptionParser.new("", 24, '' '') do |opts| end opts.on("-c", "--config-file FILE", "Unicorn-specific config file") do |f| - options[:config_file] = File.expand_path(f) + options[:config_file] = f end # I''m avoiding Unicorn-specific config options on the command-line. diff --git a/bin/unicorn_rails b/bin/unicorn_rails index 36ed660..e46de70 100755 --- a/bin/unicorn_rails +++ b/bin/unicorn_rails @@ -75,7 +75,7 @@ opts = OptionParser.new("", 24, '' '') do |opts| end opts.on("-c", "--config-file FILE", "Unicorn-specific config file") do |f| - options[:config_file] = File.expand_path(f) + options[:config_file] = f end opts.on("-P PATH", "DEPRECATED") do |v| diff --git a/lib/unicorn/configurator.rb b/lib/unicorn/configurator.rb index 2d92aa3..e809b22 100644 --- a/lib/unicorn/configurator.rb +++ b/lib/unicorn/configurator.rb @@ -372,6 +372,13 @@ module Unicorn def working_directory(path) # just let chdir raise errors path = File.expand_path(path) + if config_file && + config_file[0] != ?/ && + ! test(?r, "#{path}/#{config_file}") + raise ArgumentError, + "config_file=#{config_file} would not be accessible in" \ + " working_directory=#{path}" + end Dir.chdir(path) HttpServer::START_CTX[:cwd] = ENV["PWD"] = path end diff --git a/test/exec/test_exec.rb b/test/exec/test_exec.rb index f6dfd6a..49762c0 100644 <snip ridiculously verbose test case> -- Eric Wong
On Wed, Nov 18, 2009 at 8:46 PM, Eric Wong <normalperson at yhbt.net> wrote:> Eric Wong <normalperson at yhbt.net> wrote: >> Michael Guterl <mguterl at gmail.com> wrote: >> > I don''t mean to hijack my own thread, but the problem seems to be >> > closely related. ?My application code is not being reloaded, when I >> > send HUP to the unicorn master process. >> >> Hi Michael, >> >> Application code is only reloaded by HUP when your preload_app setting >> is false. ?Otherwise you have to use USR2 + QUIT to upgrade your entire >> process. >> >> This behavior is documented in the Configurator, but not in the SIGNALS >> documented, I''ll fix the SIGNALS document in a few and disable >> expand_path in the launcher scripts. > > Just pushed the following change out for the SIGNALS doc. > ?http://unicorn.bogomips.org/SIGNALS.html > > diff --git a/SIGNALS b/SIGNALS > index 5c7295e..be96892 100644 > --- a/SIGNALS > +++ b/SIGNALS > @@ -9,7 +9,12 @@ Unicorn and nginx. > > ?=== Master Process > > -* HUP - reload config file, app, and gracefully restart all workers > +* HUP - reloads config file and gracefully restart all workers. > + ?If the "preload_app" directive is false (the default), then workers > + ?will also pick up any application code changes when restarted. ?If > + ?"preload_app" is true, then application code changes will have no > + ?effect; USR2 + QUIT (see below) must be used to load newer code in > + ?this case. > > ?* INT/TERM - quick shutdown, kills all workers immediately >This is great Eric, I had spent some time looking at Configurator, however, I was mostly looking at SIGNALS related to this problem. This adds much clarity to the docs! Best regards, Michael Guterl
On Wed, Nov 18, 2009 at 8:51 PM, Eric Wong <normalperson at yhbt.net> wrote:> Eric Wong <normalperson at yhbt.net> wrote: >> Michael Guterl <mguterl at gmail.com> wrote: >> > cd ~/public_html/rm/current >> > unicorn_rails -D -E production -c config/unicorn.rb >> > >> > I determined the -c config/unicorn.rb was the problem. ?If I change it to: >> > >> > unicorn_rails -D -E production -c ~/public_html/rm/current/config/unicorn.rb >> > >> > everything works fine. >> >> Hmm, maybe the config file path shouldn''t be expanded then. ?Especially >> since it''s only specified in the command-line. ?/me ponders a bit... > > Hi Michael, > > Just pushed this out, too. ?This should work better for you with: > > ?unicorn_rails -D -E production -c config/unicorn.rb > > Oddly, this has been a problem since the beginning of time and probably > confused a good amount of people. > > Thanks Michael for finally bringing it to my attention. ?Most folks I > know favor absolute ones (including myself), and don''t hit this > problem... ?Of course let me know if I broke something for anyone, > I hope not... >Thank you Eric, it has been my pleasure to put to use such a great tool in my ruby arsenal. Your contribution to the community is greatly appreciated. Michael Guterl