A software engineer focused on writing expressive code for humans (and computers).

January 8, 2017 ·

Killing the Rails Server

We’ve all seen it. You go to start the Rails server and are 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.
# Exiting

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

The quick fix

In case you don’t care about the “why?,” run the command below to free up the port:

# 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 one PID. That’s what is inside the server.pid file mentioned in the error above.

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

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

NOTE: The number inside server.pid varies as it’s assigned by the operating system.

Commanding it to die

One way to shut down a rogue server is with the kill command. For the PID output above, you could kill the corresponding stuck server using kill 42612.

# Sends `SIGTERM` to that process.
kill PID

And if that didn’t work, you could 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. SIGTERM signals the process to run its own shutdown procedure.

In contrast, SIGKILL is more like unplugging the computer or yanking out the battery. Instead of telling the process to shut down, it goes a step further and cuts the process off at the source.

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

Hunting down a process without a PID

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 the port is unavailable, then it means some previous development work wasn’t closed down properly.

What we need is a way to find which process (identifiable by PID) is using the desired port. We can 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 (terse listing) instructs the command to return PIDs. The -i:3000 filters the results down to include PIDs attached to port 3000. Used together they print out the IDs of all processes attached to port 3000 (or whichever port you pass to -i). With that command, you can find the stuck process 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, you can add a simple function to your .zshrc or .bashrc.

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

With that in place, you have your own killport plugin ✨:

killport 3000