January 8, 2017 · rails shell

Killing the Rails Server

We’ve all seen it. You go to start a Rails server and you’re confronted with this nasty reality.

rails server
=> Booting WEBrick
=> Rails application starting in development on http://localhost:3000
=> Run `rails server -h` for more startup options
=> Ctrl-C to shutdown server
A server is already running. Check ./tmp/pids/server.pid.

The server is already running 😱. This happens when the server is shut down incorrectly leaving the port permanently stuck in use. When the new server attempts to run, it is unable to bind itself to the occupied port.

The quick fix

In case you don’t care about the “why?,” you can just run the command below:

# kills any process attached to port 3000
lsof -ti:3000 | xargs kill -9

A story of PIDs

Once upon a time there were three little PIDs… well, actually just one. That’s what’s inside of server.pid mentioned in the error above.

cat ./tmp/pids/server.pid
=> 42612

The file contains a single number: the PID (Process ID). The Rails server uses this number to track the server’s process. The end.

Commanding it to die

One way to shut down a rouge server is with the kill command. The previously mentioned server is stopped by entering kill 42612 (42612 is the unique number found in server.pid).

# Sends `SIGTERM` to that process.
kill PID

If that doesn’t work, you can try kill -9 42612.

# Sends a `SIGKILL` command.
kill -9 PID

What’s the difference between SIGTERM and SIGKILL?

The SIGTERM command is akin to shutting a computer down via the user interface. You click the shutdown button, then the computer closes out everything it’s working on and shuts down. Likewise SIGTERM signals the process to run its own shutdown procedure.

On the other hand, SIGKILL is more like unplugging the computer or yanking out the battery. Instead of telling the process to shutdown, it goes a level higher and has the process cut off at the source.

Source: https://major.io/2010/03/18/sigterm-vs-sigkill/

Hunting down a process without a PID

So we’ve discussed how to kill a process by PID, but what if you don’t know the PID? You start with what you do know: the port you’re trying to use.

In development it’s common to use ports 3000, 4000, 4200, etc. If these are occupied, then it means some previous development work wasn’t closed down properly.

What we need is a way to find what PID is currently using the desired port. We’ll use the lsof command to find it. The command stands for “list open files” or in this case, processes.

lsof -ti:3000
=> 42612

The -t flag instructs the command to only return PIDs; it’s less verbose. The -i:3000 filters the results down to only include PIDs for port 3000. Used together they print out the IDs of all processes currently attached to port 3000 (or whichever port is passed to -i).

With that command, you can find the process already occupying the port, then pass the resulting PID to the kill command.

A one-liner command

You can do both the finding and killing in the same command if you like.

lsof -ti:3000 | xargs kill -9

This pipes the results of the PID search to the kill command.

Wrapping it up (in a function)

Instead of remembering the one-liner, a simple function can be added to your .zshrc or .bashrc.

killport() { lsof -ti:$1 | xargs kill -9 }

With that in place, you have your own killport plugin. Just pass in the troublesome port number and watch it die 💥🔫.

killport 3000