├── files └── common │ ├── Procfile │ ├── config │ ├── timeout.rb │ ├── rollout.rb │ ├── database.yml.erb │ ├── puma.rb │ ├── rollbar.rb │ └── newrelic.yml.erb │ ├── env │ ├── env_sample │ └── Gemfile ├── generator.rb └── README.md /files/common/Procfile: -------------------------------------------------------------------------------- 1 | web: bundle exec puma -C config/puma.rb 2 | -------------------------------------------------------------------------------- /files/common/config/timeout.rb: -------------------------------------------------------------------------------- 1 | # config/initializers/timeout.rb 2 | Rack::Timeout.timeout = Integer(ENV["RACK_TIMEOUT_SECONDS"] || 20) # seconds -------------------------------------------------------------------------------- /files/common/config/rollout.rb: -------------------------------------------------------------------------------- 1 | require 'redis' 2 | 3 | $redis = Redis.new(url: ENV.fetch("REDISCLOUD_URL", "redis://localhost:6379")) 4 | $rollout = Rollout.new($redis) 5 | -------------------------------------------------------------------------------- /files/common/env: -------------------------------------------------------------------------------- 1 | # SET YOUR DEVELOPMENT ENVIRONMENT VARIABLES HERE 2 | # 3 | # DO NOT COMMIT THIS TO GIT 4 | # 5 | # WEB_CONCURRENCY=1 6 | # UNICORN_TIMEOUT=30 7 | # RACK_TIMEOUT_SECONDS=10 8 | -------------------------------------------------------------------------------- /files/common/env_sample: -------------------------------------------------------------------------------- 1 | # SET YOUR DEVELOPMENT ENVIRONMENT VARIABLES HERE 2 | # 3 | # COMMIT THIS FILE TO GIT TO SHARE WITH YOUR FELLOW DEVELOPERS VARS FOR 4 | # YOU APPLICATION. KEEP IT UP TO DATE! 5 | # 6 | # WEB_CONCURRENCY=1 7 | # MAX_THREADS=5 8 | # PORT=3000 9 | # RACK_TIMEOUT_SECONDS=10 10 | -------------------------------------------------------------------------------- /files/common/config/database.yml.erb: -------------------------------------------------------------------------------- 1 | default: &default 2 | adapter: postgresql 3 | pool: 5 4 | 5 | development: 6 | <<: *default 7 | database: <%= app_name %>_development 8 | 9 | # Warning: The database defined as "test" will be erased and 10 | # re-generated from your development database when you run "rake". 11 | # Do not set this db to the same as development or production. 12 | test: 13 | <<: *default 14 | database: <%= app_name %>_test 15 | -------------------------------------------------------------------------------- /files/common/config/puma.rb: -------------------------------------------------------------------------------- 1 | workers Integer(ENV['WEB_CONCURRENCY'] || 2) 2 | threads_count = Integer(ENV['MAX_THREADS'] || 5) 3 | threads threads_count, threads_count 4 | 5 | preload_app! 6 | 7 | rackup DefaultRackup 8 | port ENV['PORT'] || 3000 9 | environment ENV['RACK_ENV'] || 'development' 10 | 11 | on_worker_boot do 12 | # Worker specific setup for Rails 4.1+ 13 | # See: https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server#on-worker-boot 14 | defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection 15 | end 16 | -------------------------------------------------------------------------------- /files/common/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | ruby '2.2.1' 4 | 5 | gem 'rails' 6 | gem 'pg' 7 | gem 'rack-timeout' 8 | gem 'puma' 9 | gem 'foreman' 10 | 11 | gem 'oj' 12 | gem 'oj_mimic_json' 13 | 14 | gem 'slim' 15 | gem 'devise' 16 | gem 'devise-i18n' 17 | gem 'simple_form' 18 | gem 'sass-rails', '~> 4.0.3' 19 | gem 'jquery-rails' 20 | gem 'uglifier' 21 | gem 'high_voltage' 22 | 23 | gem 'rollout' 24 | gem 'rollbar' 25 | gem 'logarage' 26 | 27 | group :development do 28 | gem 'spring' 29 | gem 'spring-commands-rspec' 30 | gem 'spring-commands-spinach' 31 | gem 'guard' 32 | gem 'guard-rspec', require: false 33 | gem 'guard-spinach', require: false 34 | gem 'rb-fsevent', require: false 35 | end 36 | 37 | group :development, :test do 38 | gem 'awesome_print' 39 | gem 'byebug' 40 | gem 'dotenv-rails' 41 | gem 'factory_girl_rails' 42 | gem 'pry-rails' 43 | gem 'rspec-rails' 44 | gem 'quiet_assets' 45 | gem 'letter_opener' 46 | end 47 | 48 | group :test do 49 | gem 'capybara-webkit', '>= 1.2.0' 50 | gem 'database_cleaner' 51 | gem 'formulaic' 52 | gem 'launchy' 53 | gem 'webmock' 54 | gem 'vcr' 55 | end 56 | 57 | group :production do 58 | gem 'rails_12factor' 59 | gem 'newrelic_rpm' 60 | gem 'heroku-deflater' 61 | end 62 | -------------------------------------------------------------------------------- /generator.rb: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------------------------ 2 | # 3 | # Heroku Rails Template Generator 4 | # 5 | # John Beynon 6 | # http://github.com/johnbeynon/heroku-rails-template 7 | # 8 | # ----------------------------------------------------------------------------- 9 | 10 | # Helper methods 11 | def source_paths 12 | [File.expand_path(File.dirname(__FILE__))] 13 | end 14 | 15 | def copy_from_repo(filename, destination) 16 | repo = 'https://raw.github.com/codegram/heroku-rails-template/master/files/' 17 | get repo + filename, destination 18 | end 19 | 20 | def inject_into_environment(rails_env, config) 21 | inject_into_file( "config/environments/#{rails_env}.rb", "\n\n #{config}", before: "\nend") 22 | end 23 | 24 | say 'Heroku Rails Application Generator' 25 | 26 | copy_from_repo 'common/Gemfile', 'Gemfile' 27 | 28 | # Add Puma config 29 | copy_from_repo 'common/config/puma.rb', 'config/puma.rb' 30 | 31 | # Add Rack::Timeout config 32 | copy_from_repo 'common/config/timeout.rb', 'config/initializers/timeout.rb' 33 | 34 | # Add newrelic.yml 35 | copy_from_repo 'common/config/newrelic.yml.erb', 'config/newrelic.yml.erb' 36 | template 'config/newrelic.yml.erb', 'config/newrelic.yml.erb' 37 | 38 | # Add a Procfile 39 | copy_from_repo 'common/Procfile', 'Procfile' 40 | 41 | # Add a .env file for local environment variables 42 | copy_from_repo 'common/env', '.env' 43 | 44 | # Add .env_sample for sample local variables 45 | copy_from_repo 'common/env_sample', '.env_sample' 46 | 47 | # Ensure local .env file is added to .gitignore 48 | run "echo '.env' >> .gitignore" 49 | 50 | # Remove database.yml 51 | # Replace with postgres friendly database.yml for local development 52 | remove_file 'config/database.yml' 53 | copy_from_repo 'common/config/database.yml.erb', 'config/database.yml.erb' 54 | template 'config/database.yml.erb', 'config/database.yml' 55 | 56 | lograge = <<-RUBY 57 | 58 | config.lograge.enabled = true 59 | RUBY 60 | 61 | inject_into_environment('production', lograge) 62 | -------------------------------------------------------------------------------- /files/common/config/rollbar.rb: -------------------------------------------------------------------------------- 1 | require 'rollbar/rails' 2 | Rollbar.configure do |config| 3 | # Without configuration, Rollbar is enabled in all environments. 4 | # To disable in specific environments, set config.enabled=false. 5 | 6 | if Rails.env.production? 7 | config.access_token = ENV['ROLLBAR_ACCESS_TOKEN'].to_s 8 | config.enabled = true 9 | else 10 | config.enabled = false 11 | end 12 | 13 | # By default, Rollbar will try to call the `current_user` controller method 14 | # to fetch the logged-in user object, and then call that object's `id`, 15 | # `username`, and `email` methods to fetch those properties. To customize: 16 | # config.person_method = "my_current_user" 17 | # config.person_id_method = "my_id" 18 | # config.person_username_method = "my_username" 19 | # config.person_email_method = "my_email" 20 | 21 | # If you want to attach custom data to all exception and message reports, 22 | # provide a lambda like the following. It should return a hash. 23 | # config.custom_data_method = lambda { {:some_key => "some_value" } } 24 | 25 | # Add exception class names to the exception_level_filters hash to 26 | # change the level that exception is reported at. Note that if an exception 27 | # has already been reported and logged the level will need to be changed 28 | # via the rollbar interface. 29 | # Valid levels: 'critical', 'error', 'warning', 'info', 'debug', 'ignore' 30 | # 'ignore' will cause the exception to not be reported at all. 31 | # config.exception_level_filters.merge!('MyCriticalException' => 'critical') 32 | # 33 | # You can also specify a callable, which will be called with the exception instance. 34 | # config.exception_level_filters.merge!('MyCriticalException' => lambda { |e| 'critical' }) 35 | 36 | # Enable asynchronous reporting (uses girl_friday or Threading if girl_friday 37 | # is not installed) 38 | # config.use_async = true 39 | # Supply your own async handler: 40 | # config.async_handler = Proc.new { |payload| 41 | # Thread.new { Rollbar.process_payload(payload) } 42 | # } 43 | 44 | # Enable asynchronous reporting (using sucker_punch) 45 | # config.use_sucker_punch 46 | 47 | # Enable delayed reporting (using Sidekiq) 48 | # config.use_sidekiq 49 | # You can supply custom Sidekiq options: 50 | # config.use_sidekiq 'queue' => 'my_queue' 51 | end 52 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Heroku Rails Template 2 | ===================== 3 | 4 | A Rails template for generating a skeleton Rails application that will deploy to 5 | Heroku with no changes and sets up the application following Heroku guidelines and best practices. 6 | 7 | What this template does 8 | ======================= 9 | 10 | Generates a new Rails application and then: 11 | 12 | Common: 13 | 14 | * Adds rack-timeout to Gemfile (defaults to 10 secs, override via environment variable) [Read More](http://www.neilmiddleton.com/using-rack-timeout-with-heroku/) 15 | * Switches sqlite to postgres [Read 16 | More](https://devcenter.heroku.com/articles/sqlite3) 17 | * Sets up Unicorn according to Heroku guidelines (defaults to 3 processes with 18 | 30 second timeout, override via environment variable) 19 | [Read More](https://devcenter.heroku.com/articles/rails-unicorn) 20 | * Adds Procfile [Read More](https://devcenter.heroku.com/articles/procfile) 21 | * Adds .env file for local environment variables [Read 22 | More](http://ddollar.github.io/foreman/#ENVIRONMENT) 23 | * (Added 13 Aug 2013) Excludes .env from git via .gitignore 24 | * (Added 13 Aug 2013) Adds .env_sample to communicate required ENV vars to other developers 25 | * Removes standard database.yml replacing it with Postgres version 26 | * Adds newrelic.yml (You will still need to add the addon to your application) 27 | [Read More](https://devcenter.heroku.com/articles/newrelic#copy-yml) 28 | * Add rails_12_factor to Gemfile [Read More 29 | * (Added 29 Aug 2013) Adds required rails_12_factor to Gemfile [Read More](https://devcenter.heroku.com/articles/rails4) following [this](https://devcenter.heroku.com/changelog-items/318) changelog entry to prevent deprecation notices in logs. 30 | 31 | Rails 4 32 | 33 | * (Added 05 Feb 2014) Adds sprockets_better_errors gem and enables it for development mode [Read 34 | More](https://github.com/schneems/sprockets_better_errors) - Only for Rails 35 | 4.0.x.x 36 | 37 | Rails 3 38 | 39 | * Prevent application initializing assets on boot [Read 40 | More](https://devcenter.heroku.com/articles/rails-asset-pipeline) 41 | 42 | Usage 43 | ===== 44 | 45 | ``` 46 | rails new myapp -m https://raw.github.com/johnbeynon/heroku-rails-template/master/generator.rb 47 | ``` 48 | 49 | Assumptions 50 | =========== 51 | 52 | * You have Ruby (2.0.0) installed via either RVM or RBENV 53 | * Rails is already installed (confirm via $ rails -v ) 54 | * Postgres is installed locally 55 | 56 | Notes 57 | ===== 58 | 59 | If you get an error during deployment to Heroku along the lines of 60 | 61 | ``` 62 | rake aborted! could not connect to server: Connection refused 63 | Is the server running on host "127.0.0.1" and accepting 64 | TCP/IP connections on port 5432? 65 | ``` 66 | 67 | Then you need to enable the User environment labs feature 68 | 69 | ``` 70 | heroku labs:enable user-env-compile -a myapp 71 | ``` 72 | 73 | I've found this can occur when you have certain Rails validations in your models 74 | which require a DB hit during the application initialization which occurs when 75 | assets are precompiled. 76 | 77 | Read more about this feature 78 | [here](https://devcenter.heroku.com/articles/labs-user-env-compile) 79 | 80 | See Also 81 | ======== 82 | 83 | Sister project [heroku-new](https://github.com/johnbeynon/heroku-new) that adds 84 | to the Heroku CLI 85 | 86 | heroku new:rails [APP_PATH] 87 | 88 | rather than having to remember to type the template URL directly. 89 | -------------------------------------------------------------------------------- /files/common/config/newrelic.yml.erb: -------------------------------------------------------------------------------- 1 | # Here are the settings that are common to all environments 2 | common: &default_settings 3 | # ============================== LICENSE KEY =============================== 4 | 5 | # You must specify the license key associated with your New Relic 6 | # account. This key binds your Agent's data to your account in the 7 | # New Relic service. 8 | license_key: '<%= ENV["NEW_RELIC_LICENSE_KEY"] %>' 9 | 10 | # Agent Enabled (Rails Only) 11 | # Use this setting to force the agent to run or not run. 12 | # Default is 'auto' which means the agent will install and run only 13 | # if a valid dispatcher such as Mongrel is running. This prevents 14 | # it from running with Rake or the console. Set to false to 15 | # completely turn the agent off regardless of the other settings. 16 | # Valid values are true, false and auto. 17 | # 18 | # agent_enabled: auto 19 | 20 | # Application Name Set this to be the name of your application as 21 | # you'd like it show up in New Relic. The service will then auto-map 22 | # instances of your application into an "application" on your 23 | # dashboard page. If you want to map this instance into multiple 24 | # apps, like "AJAX Requests" and "All UI" then specify a semicolon 25 | # separated list of up to three distinct names, or a yaml list. 26 | # Defaults to the capitalized RAILS_ENV or RACK_ENV (i.e., 27 | # Production, Staging, etc) 28 | # 29 | # Example: 30 | # 31 | # app_name: 32 | # - Ajax Service 33 | # - All Services 34 | # 35 | app_name: <%= app_name %> 36 | 37 | # When "true", the agent collects performance data about your 38 | # application and reports this data to the New Relic service at 39 | # newrelic.com. This global switch is normally overridden for each 40 | # environment below. (formerly called 'enabled') 41 | monitor_mode: true 42 | 43 | # Developer mode should be off in every environment but 44 | # development as it has very high overhead in memory. 45 | developer_mode: false 46 | 47 | # The newrelic agent generates its own log file to keep its logging 48 | # information separate from that of your application. Specify its 49 | # log level here. 50 | log_level: info 51 | 52 | # Optionally set the path to the log file This is expanded from the 53 | # root directory (may be relative or absolute, e.g. 'log/' or 54 | # '/var/log/') The agent will attempt to create this directory if it 55 | # does not exist. 56 | # log_file_path: 'log' 57 | 58 | # Optionally set the name of the log file, defaults to 'newrelic_agent.log' 59 | # log_file_name: 'newrelic_agent.log' 60 | 61 | # The newrelic agent communicates with the service via http by 62 | # default. If you want to communicate via https to increase 63 | # security, then turn on SSL by setting this value to true. Note, 64 | # this will result in increased CPU overhead to perform the 65 | # encryption involved in SSL communication, but this work is done 66 | # asynchronously to the threads that process your application code, 67 | # so it should not impact response times. 68 | ssl: false 69 | 70 | # EXPERIMENTAL: enable verification of the SSL certificate sent by 71 | # the server. This setting has no effect unless SSL is enabled 72 | # above. This may block your application. Only enable it if the data 73 | # you send us needs end-to-end verified certificates. 74 | # 75 | # This means we cannot cache the DNS lookup, so each request to the 76 | # service will perform a lookup. It also means that we cannot 77 | # use a non-blocking lookup, so in a worst case, if you have DNS 78 | # problems, your app may block indefinitely. 79 | # verify_certificate: true 80 | 81 | # Set your application's Apdex threshold value with the 'apdex_t' 82 | # setting, in seconds. The apdex_t value determines the buckets used 83 | # to compute your overall Apdex score. 84 | # Requests that take less than apdex_t seconds to process will be 85 | # classified as Satisfying transactions; more than apdex_t seconds 86 | # as Tolerating transactions; and more than four times the apdex_t 87 | # value as Frustrating transactions. 88 | # For more about the Apdex standard, see 89 | # http://newrelic.com/docs/general/apdex 90 | 91 | apdex_t: 0.5 92 | 93 | #============================== Browser Monitoring =============================== 94 | # New Relic Real User Monitoring gives you insight into the performance real users are 95 | # experiencing with your website. This is accomplished by measuring the time it takes for 96 | # your users' browsers to download and render your web pages by injecting a small amount 97 | # of JavaScript code into the header and footer of each page. 98 | browser_monitoring: 99 | # By default the agent automatically injects the monitoring JavaScript 100 | # into web pages. Set this attribute to false to turn off this behavior. 101 | auto_instrument: true 102 | 103 | # Proxy settings for connecting to the service. 104 | # 105 | # If a proxy is used, the host setting is required. Other settings 106 | # are optional. Default port is 8080. 107 | # 108 | # proxy_host: hostname 109 | # proxy_port: 8080 110 | # proxy_user: 111 | # proxy_pass: 112 | 113 | 114 | # Tells transaction tracer and error collector (when enabled) 115 | # whether or not to capture HTTP params. When true, frameworks can 116 | # exclude HTTP parameters from being captured. 117 | # Rails: the RoR filter_parameter_logging excludes parameters 118 | # Java: create a config setting called "ignored_params" and set it to 119 | # a comma separated list of HTTP parameter names. 120 | # ex: ignored_params: credit_card, ssn, password 121 | capture_params: false 122 | 123 | 124 | # Transaction tracer captures deep information about slow 125 | # transactions and sends this to the service once a 126 | # minute. Included in the transaction is the exact call sequence of 127 | # the transactions including any SQL statements issued. 128 | transaction_tracer: 129 | 130 | # Transaction tracer is enabled by default. Set this to false to 131 | # turn it off. This feature is only available at the Professional 132 | # and above product levels. 133 | enabled: true 134 | 135 | # Threshold in seconds for when to collect a transaction 136 | # trace. When the response time of a controller action exceeds 137 | # this threshold, a transaction trace will be recorded and sent to 138 | # the service. Valid values are any float value, or (default) 139 | # "apdex_f", which will use the threshold for an dissatisfying 140 | # Apdex controller action - four times the Apdex T value. 141 | transaction_threshold: apdex_f 142 | 143 | # When transaction tracer is on, SQL statements can optionally be 144 | # recorded. The recorder has three modes, "off" which sends no 145 | # SQL, "raw" which sends the SQL statement in its original form, 146 | # and "obfuscated", which strips out numeric and string literals 147 | record_sql: obfuscated 148 | 149 | # Threshold in seconds for when to collect stack trace for a SQL 150 | # call. In other words, when SQL statements exceed this threshold, 151 | # then capture and send the current stack trace. This is 152 | # helpful for pinpointing where long SQL calls originate from 153 | stack_trace_threshold: 0.500 154 | 155 | # Determines whether the agent will capture query plans for slow 156 | # SQL queries. Only supported in mysql and postgres. Should be 157 | # set to false when using other adapters. 158 | # explain_enabled: true 159 | 160 | # Threshold for query execution time below which query plans will not 161 | # not be captured. Relevant only when `explain_enabled` is true. 162 | # explain_threshold: 0.5 163 | 164 | # Error collector captures information about uncaught exceptions and 165 | # sends them to the service for viewing 166 | error_collector: 167 | 168 | # Error collector is enabled by default. Set this to false to turn 169 | # it off. This feature is only available at the Professional and above 170 | # product levels 171 | enabled: true 172 | 173 | # Rails Only - tells error collector whether or not to capture a 174 | # source snippet around the place of the error when errors are View 175 | # related. 176 | capture_source: true 177 | 178 | # To stop specific errors from reporting to New Relic, set this property 179 | # to comma separated values. Default is to ignore routing errors 180 | # which are how 404's get triggered. 181 | # 182 | ignore_errors: ActionController::RoutingError 183 | 184 | # (Advanced) Uncomment this to ensure the cpu and memory samplers 185 | # won't run. Useful when you are using the agent to monitor an 186 | # external resource 187 | # disable_samplers: true 188 | 189 | # If you aren't interested in visibility in these areas, you can 190 | # disable the instrumentation to reduce overhead. 191 | # 192 | # disable_view_instrumentation: true 193 | # disable_activerecord_instrumentation: true 194 | # disable_memcache_instrumentation: true 195 | # disable_dj: true 196 | 197 | # If you're interested in capturing memcache keys as though they 198 | # were SQL uncomment this flag. Note that this does increase 199 | # overhead slightly on every memcached call, and can have security 200 | # implications if your memcached keys are sensitive 201 | # capture_memcache_keys: true 202 | 203 | # Certain types of instrumentation such as GC stats will not work if 204 | # you are running multi-threaded. Please let us know. 205 | # multi_threaded = false 206 | 207 | # Application Environments 208 | # ------------------------------------------ 209 | # Environment specific settings are in this section. 210 | # For Rails applications, RAILS_ENV is used to determine the environment 211 | # For Java applications, pass -Dnewrelic.environment to set 212 | # the environment 213 | 214 | # NOTE if your application has other named environments, you should 215 | # provide newrelic configuration settings for these environments here. 216 | 217 | development: 218 | <<: *default_settings 219 | # Turn off communication to New Relic service in development mode (also 220 | # 'enabled'). 221 | # NOTE: for initial evaluation purposes, you may want to temporarily 222 | # turn the agent on in development mode. 223 | monitor_mode: false 224 | 225 | # Rails Only - when running in Developer Mode, the New Relic Agent will 226 | # present performance information on the last 100 transactions you have 227 | # executed since starting the mongrel. 228 | # NOTE: There is substantial overhead when running in developer mode. 229 | # Do not use for production or load testing. 230 | developer_mode: true 231 | 232 | # Enable textmate links 233 | # textmate: true 234 | 235 | test: 236 | <<: *default_settings 237 | # It almost never makes sense to turn on the agent when running 238 | # unit, functional or integration tests or the like. 239 | monitor_mode: false 240 | 241 | # Turn on the agent in production for 24x7 monitoring. NewRelic 242 | # testing shows an average performance impact of < 5 ms per 243 | # transaction, you you can leave this on all the time without 244 | # incurring any user-visible performance degradation. 245 | production: 246 | <<: *default_settings 247 | monitor_mode: true 248 | 249 | # Many applications have a staging environment which behaves 250 | # identically to production. Support for that environment is provided 251 | # here. By default, the staging environment has the agent turned on. 252 | staging: 253 | <<: *default_settings 254 | monitor_mode: true 255 | app_name: <%= app_name %> (Staging) 256 | --------------------------------------------------------------------------------