App-config

Learn about app-config in Ruby on Rails development.

Beginner 1 min read

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

config/
├── 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

# config/application.rb
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:

# Set application time zone
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:

# Default locale
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:

# Add asset paths
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:

config.generators do |g|
# 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
# Cross-Origin Resource Sharing configuration
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 configuration for caching and sessions
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
# Sidekiq configuration for background jobs
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
# Content Security Policy configuration
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:

# In config/application.rb
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:
# Anywhere in your application
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

# Debug configuration loading
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

# Check asset paths
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

# Check time zone configuration
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"