Application Configuration
Rails application configuration controls how your application behaves across different environments and deployment scenarios. Understanding configuration management is essential for building maintainable, secure, and scalable Rails applications.
Configuration Files Structure
├── application.rb # Main application configuration
├── environment.rb # Loads Rails and application
├── boot.rb # Sets up Bundler and load paths
├── routes.rb # Application routing configuration
├── database.yml # Database configuration
├── credentials.yml.enc # Encrypted secrets
├── master.key # Encryption key for credentials
├── environments/ # Environment-specific configurations
│ ├── development.rb
│ ├── test.rb
│ ├── production.rb
│ └── staging.rb
├── initializers/ # Initialization scripts
│ ├── assets.rb
│ ├── backtrace_silencers.rb
│ ├── content_security_policy.rb
│ ├── cors.rb
│ ├── filter_parameter_logging.rb
│ ├── inflections.rb
│ ├── mime_types.rb
│ ├── permissions_policy.rb
│ ├── session_store.rb
│ ├── time_formats.rb
│ └── wrap_parameters.rb
└── locales/ # Internationalization files
└── en.yml
🔧 config/application.rb - The Heart of Configuration
The application.rb file contains the main configuration for your Rails application. This is where you set global application-wide settings that apply across all environments.
Complete application.rb Example
require_relative "boot"
require "rails/all"
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
module MyApplication
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version
config.load_defaults 7.0
# Configuration for the application, engines, and railties goes here
# Time zone configuration
config.time_zone = 'UTC'
# Localization configuration
config.i18n.default_locale = :en
config.i18n.available_locales = [:en, :es, :fr]
config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}').to_s]
# Asset configuration
config.assets.paths << Rails.root.join('app', 'assets', 'fonts')
config.assets.precompile += %w[admin.css admin.js]
# Generator configuration
config.generators do |g|
g.test_framework :rspec
g.fixture_replacement :factory_bot
g.view_specs false
g.helper_specs false
g.stylesheets false
g.javascripts false
end
# Active Job configuration
config.active_job.queue_adapter = :sidekiq
# CORS configuration
config.middleware.insert_before 0, Rack::Cors do
allow do
origins Rails.env.development? ? 'localhost:3001' : 'https://myapp.com'
resource '*', headers: :any, methods: [:get, :post, :patch, :put, :delete, :options]
end
end
# Security headers
config.force_ssl = Rails.env.production?
# Session configuration
config.session_store :cookie_store, key: '_myapp_session'
# Logging configuration
config.log_level = Rails.env.production? ? :info : :debug
config.log_formatter = ::Logger::Formatter.new
# Custom configuration
config.app_domain = Rails.env.production? ? 'https://myapp.com' : 'http://localhost:3000'
config.support_email = 'support@myapp.com'
# Autoloading configuration
config.autoload_paths += %W[#{config.root}/lib]
config.eager_load_paths += %W[#{config.root}/lib]
end
end
⚙️ Essential Configuration Options
🕐 Time Zone Configuration
Configure how your application handles time zones and date/time formatting:
config.time_zone = 'Eastern Time (US & Canada)'
# Database time zone (usually keep as UTC)
config.active_record.default_timezone = :utc
# Available time zones
Rails.application.config.time_zone # => "Eastern Time (US & Canada)"
Time.zone # => (GMT-05:00) Eastern Time (US & Canada)
Time.zone.now # => Current time in configured zone
# Common time zones:
# 'UTC', 'Eastern Time (US & Canada)', 'Central Time (US & Canada)'
# 'Mountain Time (US & Canada)', 'Pacific Time (US & Canada)'
# 'London', 'Paris', 'Tokyo', 'Sydney'
🌍 Internationalization (i18n)
Configure localization and internationalization for multi-language support:
config.i18n.default_locale = :en
# Available locales
config.i18n.available_locales = [:en, :es, :fr, :de, :ja]
# Load paths for translation files
config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}')]
# Fallback configuration
config.i18n.fallbacks = [I18n.default_locale]
# Enforce available locales (security)
config.i18n.enforce_available_locales = true
# Exception handling for missing translations
config.i18n.raise_on_missing_translations = Rails.env.development?
💡 Pro Tip: Use nested locale files in config/locales/ to organize translations by feature or page.
🎨 Asset Pipeline Configuration
Configure asset compilation, paths, and optimization:
config.assets.paths << Rails.root.join('app', 'assets', 'fonts')
config.assets.paths << Rails.root.join('vendor', 'assets', 'images')
# Precompile additional assets
config.assets.precompile += %w[
admin.css admin.js
email.css
print.css
*.png *.jpg *.jpeg *.gif *.svg
]
# Asset version for cache busting
config.assets.version = '1.0'
# Configure asset host (CDN)
config.asset_host = Rails.env.production? ? 'https://cdn.myapp.com' : nil
# Compress assets in production
config.assets.css_compressor = :sass
config.assets.js_compressor = :terser
🏗️ Generator Configuration
Configure Rails generators to match your project conventions:
# Test framework
g.test_framework :rspec, fixtures: true, view_specs: false, helper_specs: false
# Factory framework
g.fixture_replacement :factory_bot, dir: 'spec/factories'
# Template engine
g.template_engine :haml
# Skip files
g.stylesheets false
g.javascripts false
g.helper false
# Generate with namespaces
g.namespace_route true
# Assets
g.assets false
g.scss true
end
📄 Initializers - Custom Configuration Scripts
Initializers are Ruby files in config/initializers/ that run during application startup. They're perfect for configuring gems, setting up constants, and customizing Rails behavior.
Common Initializers
config/initializers/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins Rails.env.development? ?
['localhost:3000', 'localhost:3001', '127.0.0.1:3001'] :
['https://myapp.com', 'https://www.myapp.com']
resource '*',
headers: :any,
methods: [:get, :post, :put, :patch, :delete, :options, :head],
credentials: true
end
end
config/initializers/redis.rb
redis_url = ENV['REDIS_URL'] || 'redis://localhost:6379/0'
# Configure Redis connection
$redis = Redis.new(url: redis_url)
# Configure Rails cache store
Rails.application.config.cache_store = :redis_cache_store, {
url: redis_url,
expires_in: 1.hour,
namespace: Rails.application.class.module_parent_name.underscore,
pool_size: 5,
pool_timeout: 5
}
# Configure session store
Rails.application.config.session_store :redis_session_store, {
servers: [redis_url],
expire_after: 2.weeks,
key_prefix: "#{Rails.application.class.module_parent_name.underscore}:session:",
threadsafe: true
}
config/initializers/sidekiq.rb
require 'sidekiq'
require 'sidekiq/web'
redis_url = ENV['REDIS_URL'] || 'redis://localhost:6379/0'
Sidekiq.configure_server do |config|
config.redis = { url: redis_url, size: 10 }
# Enable cron-like functionality
config.cron 'daily_cleanup' do
CleanupJob.perform_async
end
end
Sidekiq.configure_client do |config|
config.redis = { url: redis_url, size: 5 }
end
# Authenticate Sidekiq Web UI
if Rails.env.production?
Sidekiq::Web.use Rack::Auth::Basic do |username, password|
username == ENV['SIDEKIQ_USERNAME'] && password == ENV['SIDEKIQ_PASSWORD']
end
end
config/initializers/content_security_policy.rb
Rails.application.configure do
config.content_security_policy do |policy|
policy.default_src :self, :https
policy.font_src :self, :https, :data
policy.img_src :self, :https, :data, 'https://images.unsplash.com'
policy.object_src :none
policy.script_src :self, :https
policy.style_src :self, :https, :unsafe_inline
# Allow unsafe eval in development for better debugging
if Rails.env.development?
policy.script_src :self, :https, :unsafe_eval, :unsafe_inline
policy.connect_src :self, :https, 'ws://localhost:3035', 'wss://localhost:3035'
end
end
# Generate session nonces for permitted importmap and inline scripts
config.content_security_policy_nonce_generator = ->(request) do
SecureRandom.base64(16)
end
config.content_security_policy_nonce_directives = %w[script-src]
end
🎯 Custom Application Configuration
Adding Custom Configuration Options
Rails allows you to add custom configuration options that can be accessed throughout your application:
module MyApplication
class Application < Rails::Application
# Custom configuration
config.app_domain = 'https://myapp.com'
config.support_email = 'support@myapp.com'
config.max_file_upload_size = 10.megabytes
config.feature_flags = {
new_dashboard: Rails.env.production? ? true : false,
beta_features: Rails.env.development?,
analytics_tracking: Rails.env.production?
}
# Third-party service configuration
config.stripe = {
publishable_key: Rails.application.credentials.stripe[:publishable_key],
secret_key: Rails.application.credentials.stripe[:secret_key]
}
# API configuration
config.api_rate_limit = 100
config.api_timeout = 30.seconds
end
end
Accessing Custom Configuration:
Rails.application.config.app_domain # => "https://myapp.com"
Rails.application.config.support_email # => "support@myapp.com"
Rails.application.config.feature_flags[:new_dashboard] # => true/false
# In controllers
if Rails.application.config.feature_flags[:beta_features]
render :beta_layout
else
render :standard_layout
end
💡 Configuration Best Practices
🔒 Security in Configuration
- Never hardcode secrets: Use encrypted credentials or environment variables for API keys and passwords
- Validate required configuration: Check for required environment variables at startup
- Use secure defaults: Configure security features like SSL, CSP, and CSRF protection by default
- Separate configuration by environment: Development should never use production credentials
📊 Organization and Maintainability
- Group related configuration: Keep similar settings together in the same file or initializer
- Comment complex configuration: Explain why configuration choices were made
- Use descriptive names: Choose clear, self-documenting configuration option names
- Version configuration changes: Track configuration changes in version control with clear commit messages
⚡ Performance Considerations
- Optimize for production: Use appropriate caching, asset compression, and eager loading
- Configure connection pools: Set database and Redis connection pools based on your deployment
- Enable query optimization: Configure slow query logging and N+1 detection in development
- Tune garbage collection: Configure Ruby GC settings for better performance in production
🧪 Testing Configuration
- Test environment isolation: Ensure tests don't interfere with each other or affect other environments
- Mock external services: Configure test doubles for third-party services
- Use test-specific configuration: Disable features like email delivery and external API calls in tests
- Validate configuration in tests: Test that your application behaves correctly with different configuration options
🔍 Configuration Troubleshooting
🚫 Common Configuration Issues
Issue: Application fails to start with "configuration not found" errors
rails runner "puts Rails.application.config.inspect"
# Check for typos in configuration keys
# Verify all required environment variables are set
Issue: Assets not loading or compiling incorrectly
rails runner "puts Rails.application.config.assets.paths"
# Precompile assets manually
rails assets:precompile
# Clear asset cache
rails assets:clobber
Issue: Time zone or localization not working correctly
rails runner "puts Time.zone"
rails runner "puts Rails.application.config.time_zone"
# Check available locales
rails runner "puts I18n.available_locales"
rails runner "puts I18n.default_locale"