How to stop a Daemon Server in Rails?

I am running my rails application using the following

  $script/server -d webrick

on my Ubuntu system , above command run the webrick server in background . I could kill the process using kill command

  $kill pid

Does rails provide any command to stop the background running daemon server ?

like the one provided by rails to start the server , Thanks .

EDIT When it is appropriate to start the daemon server ? Any real time scenario will help Thanks

55452 次浏览

如果你使用-d,我认为它不会。我只会终止这个过程。

In the future, just open up another terminal window instead and use the command without -d, it provides some really useful debugging output.

If this is production, use something like passenger or thin, so that they're easy to stop the processes or restart the servers

The process id of the daemon server is stored in your application directory tmp/pids/. You can use your standard kill process_id with the information you find there.

Like Ryan said:

the pid you want is in tmp/pids/

probably server.pid is the file you want.

You should be able to run kill -9 $(cat tmp/pids/server.pid) to bring down a daemonized server.

if it can be useful, on linux you can find which process is using a port (in this case 3000) you can use:

lsof -i :3000

it'll return the pid too

I came here because I were trying to (unsuccesfully) stop with a normal kill, and thought I'd being doing something wrong.

A kill -9 is the only sure way to stop a ruby on rails server? What!? Do you know the implications of this? Can be a disaster...

The only proper way to kill the Ruby on Rails default server (which is WEBrick) is:

kill -INT $(cat tmp/pids/server.pid)

If you are running Mongrel, this is sufficient:

kill $(cat tmp/pids/server.pid)

Use kill -9 if your daemon hung. Remember the implications of kill -9 - if the data kept in Active Record caches weren't flushed to disk, you will lose your data. (As I recently did)

How about a rake task?

desc 'stop rails'
task :stop do
pid_file = 'tmp/pids/server.pid'
pid = File.read(pid_file).to_i
Process.kill 9, pid
File.delete pid_file
end

run with rake stop or sudo rake stop

A Ruby ticket, http://bugs.ruby-lang.org/issues/4777, suggests it's a kernel (Linux) bug. They give a work around (essentially equivalent to the Ctrl-C/Ctrl-Z one), for use if you've demonized the server:

  1. kill -INT cat tmp/pids/server.pid
  2. kill -CONT cat tmp/pids/server.pid

This seems to cause the original INT signal to be processed, possibly allowing data flush and so on.

pguardiario beat me to it, though his implementation is a bit dangerous since it uses SIGKILL instead of the (recommended) SIGINT. Here's a rake task I tend to import into my development projects:

lib/tasks/stopserver.rake

desc 'stop server'
task :stopserver do
pid_file = 'tmp/pids/server.pid'
if File.file?(pid_file)
print "Shutting down WEBrick\n"
pid = File.read(pid_file).to_i
Process.kill "INT", pid
end
File.file?(pid_file) && File.delete(pid_file)
end

This issues an interrupt to the server if and only if the pidfile exists. It doesn't throw unsightly errors if the server isn't running, and it notifies you if it's actually shutting the server down.

If you notice that the server doesn't want to shut down using this task, add the following line after the Process.kill "INT" line, and try to upgrade to a kernel that has this bug fixed.

Process.kill "CONT", pid

(Hat tip: jackr)

In your terminal to find out the process id (PID):

$ lsof -wni tcp:3000

Then, use the number in the PID column to kill the process:

$ kill -9 <PID>
one-liner:  kill -INT `ps -e | grep ruby | awk '{print $1}'`

ps -e lists every process on the system
grep ruby searches that output for the ruby process
awk passes the first argument of that output (the pid) to kill -INT.


Try it with echo instead of kill if you just want to see the PID.

if kill process not works, then delete file server.pid from MyRailsApp/tmp/pids/

Here I leave a bash function which, if pasted in you .bashrc or .zshrc will alloy you do things like:

rails start # To start the server in development environment
rails start production # To start the server in production environment
rails stop # To stop the server
rails stop -9 # To stop the server sending -9 kill signal
rails restart # To restart the server in development environment
rails restart production # To restart the server in production environment
rails whatever # Will send the call to original rails command

Here it is the function:

function rails() {
if [ "$1" = "start" ]; then
if [ "$2" = "" ]; then
RENV="development"
else
RENV="$2"
fi
rails server -d -e "$RENV"
return 0
elif [ "$1" = "stop" ]; then
if [ -f tmp/pids/server.pid ]; then
kill $2 $(cat tmp/pids/server.pid)
return 0
else
echo "It seems there is no server running or you are not in a rails project root directory"
return 1
fi
elif [ "$1" = "restart" ]; then
rails stop && rails start $2
else
command rails $@
fi;
}

More information in the blog post I wrote about it.

Run this command:

locate tmp/pids/server.pid

output: Complete path of this file. Check your project directory name to find your concerned file if multiple files are shown in list.

Then run this command:

rm -rf [complete path of tmp/pids/server.pid file]

You can start your server in the background by adding -d to your command. For instance:

puma -d

To stop it, just kill whatever process is running on port 3000:

kill $(cat tmp/pids/server.pid)