Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Updated HEROKU.md squashed
I've added an extra step to explicitly add the production.rb file.

Added S3 CDN instructions with asset sync gem. Users assets will auto sync with S3 on deploy, using Gziped files where available. This should significantly help with Heroku stability under load.

Added add-on instructions for some load testing services available through Heroku. Hopefully help us hack on performance and stability issues.

Some general houskeeping, fixed h1 h2 muddle and removed bundle exec from foreman commands, as it uses bundler by default, and added some commands for running tests.
  • Loading branch information
nverba committed Jul 16, 2013
1 parent 7c9bd8e commit f43dc13
Showing 1 changed file with 113 additions and 28 deletions.
141 changes: 113 additions & 28 deletions docs/HEROKU.md
Expand Up @@ -12,20 +12,27 @@ For details on how to reduce the monthly cost of your application, see [Advanced
cd discourse
git checkout -b heroku

2. Create a redis.yml file.
2. Create a redis.yml file from the sample.

cp config/redis.yml.sample config/redis.yml

3. Comment out or delete `config/redis.yml` from .gitignore. We want to include redis.yml when we push to Heroku.
3. Create a production.rb file from the sample.

cp config/environments/production.rb.sample config/environments/production.rb

4. Comment out or delete the created files from .gitignore. We want to include them when we push to Heroku.

*.gitignore*

```diff
- config/redis.yml
+ # config/redis.yml
...
- config/environments/production.rb
+ # config/environments/production.rb
```

4. Commit your changes.
5. Commit your changes.

git add .
git commit -m "ready for Heroku"
Expand Down Expand Up @@ -167,35 +174,41 @@ For details on how to reduce the monthly cost of your application, see [Advanced

Using Foreman to start the application allows you to mimic the way the application is started on Heroku. It loads environment variables via the .env file and instantiates the application using the Procfile. In the .env sample file, we have set `RAILS_ENV='development'`, this makes the Rails environment variable available globally, and is required when starting this application using Foreman.

**First**, save the file `.env.sample` as `.env`

*.env*
Create a .env file from the sample.

RAILS_ENV='development'
cp .env.sample .env

### Foreman commands:


##### Create the database

bundle exec foreman run rake db:create
foreman run rake db:create

##### Migrate and seed the database

bundle exec foreman run rake db:migrate db:seed_fu
foreman run rake db:migrate db:seed_fu

##### Start the application using Foreman

bundle exec foreman start
foreman run rails server

##### Use Rails console, with pry

bundle exec foreman run rails console
foreman run rails console

##### Prepare the test database

foreman run rake db:test:prepare

##### Run tests

foreman run rake autospec


## Heroku add-on examples
# Heroku add-on examples

# Email
## Email

##### Mandrill example

Expand All @@ -221,10 +234,40 @@ Using Foreman to start the application allows you to mimic the way the applicati
+ :authentication => :plain
+ }
```

## Advanced Heroku deployment

# Autoscaler
## Load Testing

##### Blitz example

1. Add the [Blitz](https://addons.heroku.com/blitz) add-on from the [Heroku add-ons](https://addons.heroku.com/) page, or install from the command line using:

heroku addons:add blitz:250

You can now run basic load tests against your instalation. Heres an example query with the rush of users scaling from 1 to 250 over 60 seconds. The timeout (-T) is set to 30 seconds, as after this Heroku will kill a process and return an error anyway.

-p 1-250:60 -T 30000 http://YOUR-APP-NAME.herokuapp.com/

##### loader.io example

1. Add the [loader.io](https://addons.heroku.com/loaderio) add-on from the [Heroku add-ons](https://addons.heroku.com/) page, or install from the command line using:

heroku addons:add loaderio:test

loader.io is still in beta, so you mileage may vary, but the tests are free for now.
They currently require you verify your domain. A simple way to do this is to add a hard coded static route to `config.routes.rb` using the loaderio verification key. You'll see the key the first time you try to run a load test.

*config/routes.rb*

```diff
Discourse::Application.routes.draw do
+ match "/loaderio-xxxxxxxxxxxxxxxxxxxx", :to => proc {|env| [200, {}, ["/loaderio-xxxxxxxxxxxxxxxxxxxx"]] }
...
end
```

# Advanced Heroku deployment

## Autoscaler

Adding the [Autoscaler Gem](https://github.com/JustinLove/autoscaler) can help you better manage the running cost of your application by scaling down the Sidekiq worker process when not in use. This could save up to $34 per month depending on your usage levels.

Expand Down Expand Up @@ -254,20 +297,20 @@ Adding the [Autoscaler Gem](https://github.com/JustinLove/autoscaler) can help y
require 'autoscaler/sidekiq'
require 'autoscaler/heroku_scaler'

Sidekiq.configure_server do |config|
config.redis = sidekiq_redis
config.server_middleware do |chain|
chain.add(Autoscaler::Sidekiq::Server, Autoscaler::HerokuScaler.new('sidekiq'), 60)
end
end
Sidekiq.configure_server do |config|
config.redis = sidekiq_redis
config.server_middleware do |chain|
chain.add(Autoscaler::Sidekiq::Server, Autoscaler::HerokuScaler.new('sidekiq'), 60)
end
end


Sidekiq.configure_client do |config|
config.redis = sidekiq_redis
config.client_middleware do |chain|
chain.add Autoscaler::Sidekiq::Client, 'default' => Autoscaler::HerokuScaler.new('sidekiq')
end
end
Sidekiq.configure_client do |config|
config.redis = sidekiq_redis
config.client_middleware do |chain|
chain.add Autoscaler::Sidekiq::Client, 'default' => Autoscaler::HerokuScaler.new('sidekiq')
end
end

else

Expand All @@ -277,3 +320,45 @@ Adding the [Autoscaler Gem](https://github.com/JustinLove/autoscaler) can help y
end

```

## S3 CDN

Heroku Cedar stack does not support Nginx as a caching layer, so you may want to host your static assets in a CDN so you're not hitting your rails app for every asset request.

This can be done simply using the [Asset Sync](https://github.com/rumblelabs/asset_sync) gem.

You'll need an Amazon S3 account set up with a bucket configured with your app name (appname-assets), and a seperate user with write access to that bucket. You can create the new user in Account > Security Credentials. See [AWS best practices](http://docs.aws.amazon.com/IAM/latest/UserGuide/IAMBestPractices.html) for more details.

**Caveat:** This example relies on the app being deployed using the `heroku labs:enable user-env-compile` method detailed above. For instructions on manual compilation, plese refer to the [Asset Sync](https://github.com/rumblelabs/asset_sync) gem readme.

1. Add the Asset Sync Gem to the Gemfile under assets.

*Gemfile*

```diff
group :assets do
...
+ gem 'asset_sync'
end
```

2. Update production.rb to use the asset host.

*config/environments/production.rb*

```diff
- # config.action_controller.asset_host = "http://YOUR_CDN_HERE"
+ config.action_controller.asset_host = "//#{ENV['FOG_DIRECTORY']}.s3.amazonaws.com"
```

3. Get the access keys that were created for the new user and push the S3 configs to Heroku.

heroku config:set FOG_PROVIDER=AWS AWS_ACCESS_KEY_ID=xxx AWS_SECRET_ACCESS_KEY=yyy FOG_DIRECTORY=appname-assets
4. Push the Gzip config setting to Heroku. This tells asset sync to upload Gziped files where available.

heroku config:add ASSET_SYNC_GZIP_COMPRESSION=true

Now commit your changes to Git and push to Heroku.

If you open Chrome's Inspector, click on Network and refresh the page, your assets should now be showing an amazonaws.com url. Please refer to the [Asset Sync](https://github.com/rumblelabs/asset_sync) gem readme for more configuration options, or to use anothe CDN such as AWS CloudFront for better performance.

0 comments on commit f43dc13

Please sign in to comment.