breaking into the unknown…

how rails boot : order of config files loading


Thinking on it for long, but only today get time to delve into it. Have you ever get curious of what going under the hood when you start the rails server, how your rails application get booted, when your gem gets loaded and config files get executed. Well there goes a lot of thing between you type rails s on your project folder from terminal and go to localhost:3000 in your browser.

I tried to see it myself. To get the basic idea I gone through rails doc on initialization . It is quite elaborative make me lost in the details. So I figure out my own way to get the sense of things : “I use puts statement in all the important files, relevant as per the rails doc”

Below is the output on console when I started the server (I am using rails 4.1.9):

$ rails server
	Iam in Gemfile
	Iam in config/boot.rb
	Iam in config/application.rb
	=> Booting Puma
	=> Rails 4.1.5 application starting in development on
	=> Run `rails server -h` for more startup options
	=> Notice: server is listening on all interfaces (
	=> Ctrl-C to shutdown server
	Iam in config/environments/development.rb
	Iam in config/initializer folder
        Iam in config/routes.rb
	Iam in config/environment.rb
	Iam in
	Puma 2.8.2 starting...
	* Min threads: 0, max threads: 16
	* Environment: development
	* Listening on tcp://


So, now you can see the order in which the files is getting loaded are as below:

Gemfile   -> boot.rb    ->  config/application.rb   -> basic server message get printed  -> config/environments/development.rb  ->  files in initializer foler  ->  config/routes.rb  ->  config/environment.rb  ->

Now lets see, how and from where they are getting loaded at the code level .

Step 1: Starting the Server

The story begin when you start the server with the below command

$rails server

any command which run from terminal is a executable, residing in one of the folder in load path of your system. You can see it with below command:


all the location separated by : is searched by your system to run any command you type on terminal, So it means rails executable (rails executable get installed when you install a rails gem) must be present in any one of these position.

But wait, what the second argument server is for ?  well it is argument to command rails . You can run without it

$ rails
Iam in Gemfile
Iam in Gemfile
Iam in boot.rb
Usage: rails COMMAND [ARGS]

The most common rails commands are:
 generate    Generate new code (short-cut alias: "g")
 console     Start the Rails console (short-cut alias: "c")
 server      Start the Rails server (short-cut alias: "s")
 dbconsole   Start a console for the database specified in config/database.yml
             (short-cut alias: "db")
 new         Create a new Rails application. "rails new my_app" creates a
             new application called MyApp in "./my_app"

So you can see that rails command still run without the server option, but it give you message how to use it properly.

O.K, lets find what code the rails executable have. It may be present in any of folder within the path above. search each of themfor rails . You will get it in bin. Open with nano command to see its content

$ nano bin/rails

#!/usr/bin/env ruby
  load File.expand_path("../spring", __FILE__)
rescue LoadError
APP_PATH = File.expand_path('../../config/application',  __FILE__)
require_relative '../config/boot'
require 'rails/commands'

So the code here first try to load a file spring, which basically have the code to load the gems as below:

$ nano bin/spring

#!/usr/bin/env ruby

unless defined?(Spring)
  require "rubygems"
  require "bundler"

  if match =^GEM$.*?^    spring \((.*?)\)$.*?^$/m)
    ENV["GEM_PATH"] = ([Bundler.bundle_path.to_s] + Gem.path).join(File::PATH_SEPARATOR)
    ENV["GEM_HOME"] = ""
    Gem.paths = ENV

    gem "spring", match[1]
    require "spring/binstub"

The remaining line of rails executable will craete a constant variable holding path of application.rb, load the boot file and the last line will load the commands file(located in installed rails gem at rails/railties/lib/rails/commands.rb )

So till now, you get to know, how the rails server start, why Gemfile are loaded first, followed by boot.rb file.

So we have understand upto :  Gemfile  -> boot.rb


Step 2:  Insight into boot.rb file:

We will look into boot.rb file and see how it influence the remaining order of things. It has below line of code

# Set up gems listed in the Gemfile.
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)

require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])

So boot.rb file do not have any other influence on the remaining sequence of things. It just install all your gems and done with its role


Step 3: Insight into way application.rb is loaded

we have noticed that the last line in rake executable is require ‘rails/commands’ , it basically load the file  rails/railties/lib/rails/commands.rb . It has below content

ARGV << '--help' if ARGV.empty? 
aliases = {   "g"  => "generate",
  "d"  => "destroy",
  "c"  => "console",
  "s"  => "server",
  "db" => "dbconsole",
  "r"  => "runner",
  "t"  => "test",

command = ARGV.shift
command = aliases[command] || command

require 'rails/commands/commands_tasks'!(command)

So you can see that, the above code creating aliase for different commands. now you know how you can use rails s also in place of rails server .

The last two line is important. It load command_task.rb file at(rails/railties/lib/rails/commands/commands_tasks.rb) and the last line run the command you passed i,e for server command , it becomes"server").run_command!(command)

basically the above line execute below line of code from the file rails/railties/lib/rails/commands/commands_tasks.rb

  def server
      require_command!("server") do |server|
        # We need to require application after the server sets environment,
        # otherwise the --environment option given to the server won't propagate.
        require APP_PATH

from here you can see that APP_PATH which store the application.rb file get loaded and the the server get started.

So upto now, you should have clarity on below sequence of flow

rails server -> Gemfile loaded -> boot.rb loaded -> application.rb loaded


Step 4: insight into server.start

in the above code after config/application is loaded(require APP_PATH), directroy changed to rails root folder and  server.start is called. The code is as below:

module Rails
 class Server < ::Rack::Server
   def start
    trap(:INT) { exit }
    log_to_stdout if options[:log_stdout]

    puts 'Exiting' unless @options && options[:daemonize]

  def print_boot_information
   url = "#{options[:SSLEnable] ? 'https' : 'http'}://#{options[:Host]}:#{options[:Port]}"
   puts "=> Booting #{ActiveSupport::Inflector.demodulize(server)}"
   puts "=> Rails #{Rails.version} application starting in #{Rails.env} on #{url}"
   puts "=> Run `rails server -h` for more startup options"

   puts "=> Ctrl-C to shutdown server" unless options[:daemonize]

So you can see that the start method doing basic stuff  like printing the boot message(the message you see after application.rb file loads), making temp directory etc and calling super, which means calling the method of same name from the parent class i,e from the Rack::Server class. Rack::Server is defined in another Gem rack .


Step 5: look into ::Rack::Server class
module Rack
  class Server

    attr_writer :options

    def initialize(options = nil)
      @options = options
      @app = options[:app] if options && options[:app]

    def app
      @app ||= options[:builder] ? build_app_from_string : build_app_and_options_from_config

    def start &blk
      # ... wrapped_app, options, &blk

    def server
      @_server ||= Rack::Handler.get(options[:server]) || Rack::Handler.default(options)

      def build_app_and_options_from_config
        if !::File.exist? options[:config]
          abort "configuration #{options[:config]} not found"

        app, options = Rack::Builder.parse_file(self.options[:config], opt_parser)
        self.options.merge! options

      def build_app_from_string

      def wrapped_app
        @wrapped_app ||= build_app app

So here you can see start calls wrapped_app function which call build_app function to which app function is passed which in turn call  build_app_and_options_from_config function, which have the code to load all the files in config folder.

Now you can understand, how all the files in config folder in rails are loaded automatically. The files are loaded from config folder in alphabetical order, the folder getting the first priority i,e config/environment folder/*.rb files  ->  config/initializer/*rb files -> other files in config folder

So we are done with the whole loading process below:

rails server -> Gemfile loaded -> boot.rb loaded -> application.rb loaded ->config/environments/development.rb   loaded -> config/initializers/* loaded    ->  config/environmet.rb loaded -> loaded -> server started



Author: arunyadav4u

over 7 years experience in web development with Ruby on Rails.Involved in all stage of development lifecycle : requirement gathering, planing, coding, deployment & Knowledge transfer. I can adept to any situation, mixup very easily with people & can be a great friend.

2 thoughts on “how rails boot : order of config files loading

  1. Pingback: how rails boot : order of config files loading | praveenatc42

  2. Thanks a lot! Extremly helpful article!

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s