Starting Rails Server With a Different Port in Development

September 20, 2016

Starting Rails Server With a Different Port in Development

Picture of ship in port

So recently, because I was working on a project where we had to boot up different Rails applications in a development environment, it became necessary to have each rails server boot up locally with a different default port.

Solution 1: The Typical Solution

The typical solution is to pass a port option at the command line as follows:

rails s -p 4000

Solution 2: Use rake

But obviously, it can be tiresome to keep typing rails s with a different port each time. You could use rake as well.

task :custom_serve do
  `rails s -p 4000`
end

Now you can type rake custom_serve at the command like to get the desired effect. Of course this means you have to have people be aware that they need to run a rake task to do this. It’s a slight inconvenience in my opinion.

Solution 3: Use foreman if you’re using something like Unicorn

Use foreman to start your web server via Procfile, and then specify the port number in the Unicorn config file. This is a perfectly fine setup, but sometimes you just want to get going with the Webrick you have, instead of the production server you want.

Solution 4 (Final Solution): Hack the bootup process in Rails 4/5

In Rails 4/5 projects, you typically get a setup as follows in bin/rails:

#!/usr/bin/env ruby
begin
load File.expand_path("../spring", **FILE**)
  rescue LoadError
end
APP_PATH = File.expand_path('../../config/application', **FILE**)
require_relative '../config/boot'
require 'rails/commands'
Modify the setup in bin/rails to the following:

#!/usr/bin/env ruby
begin
  load File.expand_path("../spring", __FILE__)
rescue LoadError<br />
end
APP_PATH = File.expand_path('../../config/application',  __FILE__)
require_relative '../config/boot'

###Added to start rails on port 4000 in development environment (the port number is arbitrary)

require 'rails/commands/server'
module DefaultOptions
  def default_options
    super.merge!(Port: 4000) if Rails.env.development?
  end
end
Rails::Server.send(:prepend, DefaultOptions)
require 'rails/commands'

Note the use of prepend. This is because prepend is private. You also need Ruby >= 2.0.0


Profile picture

Written by Bruce Park who lives and works in the USA building useful things. He is sometimes around on Twitter.