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 4.2.5.1 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