Using God to monitor Unicorn - Start exited with non-zero code = 1
I haven't used unicorn as an app server, but I've used god for monitoring before.
If I remember rightly when you start god and give your config file, it automatically starts whatever you've told it to watch. Unicorn is probably already running, which is why it's throwing the error.
Check this by running god status
once you've started god. If that's not the case you can check on the command line what the comand's exit status is:
/usr/local/bin/unicorn_rails -c /home/my-linux-user/my-rails-app/config/unicorn.rb -E production -D;
echo $?;
that echo will print the exit status of the last command. If it's zero, the last command reported no errors. Try starting unicorn twice in a row, I expect the second time it'll return 1, because it's already running.
EDIT:
including the actual solution from comments, as this seems to be a popular response:
You can set an explicit user and group if your process requires to be run as a specific user.
God.watch do |w|
w.uid = 'root'
w.gid = 'root'
# remainder of config
end
god doesn't stop unicorn
Now we are using foreman and puma right now...this is our initializer:
web: bundle exec puma -q -d -e production -b 'unix:///home/api/shared/web.socket' -S /home/api/shared/web.state --control 'unix:///home/api/shared/web.ctl'
and deploying with capistrano, so that we can stop and restart the server like this
config/deploy.rb
# Puma commands
_cset(:puma_cmd) { "#{fetch(:bundle_cmd, 'bundle')} exec puma" }
_cset(:pumactl_cmd) { "#{fetch(:bundle_cmd, 'bundle')} exec pumactl" }
_cset(:puma_state) { "#{shared_path}/puma.state" }
_cset(:puma_role) { :app }
# Puma
namespace :puma do
desc 'Start puma'
task :start do
run "cd #{current_path} ; bundle exec foreman start web"
end
desc 'Stop puma'
task :stop, :roles => lambda { fetch(:puma_role) }, :on_no_matching_servers => :continue do
run "cd #{current_path} && #{fetch(:pumactl_cmd)} -S #{fetch(:puma_state)} stop"
end
desc 'Restart puma'
task :restart, :roles => lambda { fetch(:puma_role) }, :on_no_matching_servers => :continue do
run "cd #{current_path} && #{fetch(:pumactl_cmd)} -S #{fetch(:puma_state)} restart"
end
end
Using god only to kill
Answer to your question lies in question itself. you can kill ruby processes using god gem which is ruby process process monitor framework by github guys.
basically, here is how it works:
- configure god to monitor process it can be anything from apache,passenger,mongrel or just simple file doing a long-running task.
- Set conditionals in god's configuration file based upon which god will execute some predefined code.
here is a simple example(taken from docs). consider this as file long running process that runs undefiantly which we want to monitor for memory usage, lets call it simple.rb
loop do
puts 'Hello'
sleep 1
end
now, we install the god
gem & configure it to as run as superuser so it can kill/spawn processes and next create a configuration file. example(also taken from docs):
God.watch do |w|
w.name = "simple"
w.start = "ruby /full/path/to/simple.rb"
w.keepalive(:memory_max => 500.megabytes)
end
Here, as you may have got the idea if the process memory usage goes above 500 megabytes, god will restart it. here are few resources that might help, if you are getting started with process management using god
gem:
- Example gist - Passenger worker monitor to kill workers which use too much RAM(Don't use god, but spawns a new passenger worker instead)
- Project Homepage
- Github Page
- An indepth tutorial using god with rails & passenger
Now, please remember ALL configuration for god
is actually legal ruby code so you can get creative & do all sorts of things.
lastly, if you are frequently finding yourself running long running process, I advice you to try JRuby which is works much better with long running processes due to JVM & LOT faster than MRI
how to make foreman start god
You should not be running god with foreman. foreman is used to specify all the background (and web) processes in your application, and god is a process monitoring framework for those processes.
Typically, you should:
- Specify all your processes directly in your
Procfile
(instead ofservices.god
), and useforeman start
to run them in development. - Use god to monitor the processes in production. I use my foreman_god gem to load the Procfile directly with god. Alternatively, you can export a god config file.
That said, if you really want to run god from foreman: god runs as a daemon by default, and daemons don't work with foreman (see this wiki page). It should work if you pass the -D (Don't daemonize) option to god:
god: god -D -c services.god
Related Topics
Dry Ruby Initialization With Hash Argument
How to Avoid Nomethoderror For Nil Elements When Accessing Nested Hashes
What Does the "||=" Operand Stand for in Ruby
How to Remove Blank Elements from an Array
Undefined Method Raise_In_Transactional_Callbacks=' for Activerecord::Base:Class (Nomethoderror)
Counter_Cache With Has_Many :Through
Rails Browser Detection Methods
Can You Ask Ruby to Treat Warnings as Errors
Ruby Method Lookup Path For an Object
Using Www:Mechanize to Download a File to Disk Without Loading It All in Memory First
List of Ruby Operators That Can Be Overridden/Implemented
Ruby on Rails Best Practices - Big Controller VS Small Controller
Serving Static Files With Sinatra
Extending Devise Sessionscontroller to Authenticate Using JSON