Seriously, you should have a staging environment

 Having a good staging environment for a production app is vital. Ideally, it is almost identical to production, with the exception being test credentials if using a service like Stripe. When I came in, we had a staging environment. Ok, great! Except that we had no data in it, so we couldn’t actually test anything but the most basic interactions. It was somewhere between very difficult to impossible to test if bugs had been fixed. It was also using the production environment variable, so it was actually indistinguishable from production… but luckily, we were using test Stripe keys!

How we fixed it (in our Rails app):

  1. Copied production.rb to staging.rb and replaced   config.action_mailer.smtp_settings with the settings from Mailtrap. If you aren’t up for Mailtrap (it’s pretty rad, I would definitely recommend it), you can also use just plain old gmail.
  2. 2) If you are using the rails_12factor gem, don’t forget to add it to the staging environment in the Gemfile, like so:
    group :staging, :production do
      gem 'rails_12factor'
    end
    If you don’t do this, you will (like me) end up with your staging server being unable to find any of your assets and getting a ton of 404s in your console. Whomp whomp.
  3. Set a cron job to regularly grab data from production. Here’s an example of how we are doing it:
    heroku maintenance:on --app STAGING_APP_NAME
    heroku pg:backups capture --app PROD_APP_NAME
    heroku pg:backups restore `heroku pg:backups public-url --app PROD_APP_NAME | cat` DB_NAME --app STAGING_APP_NAME --confirm STAGING_APP_NAME
    heroku run rake db:sanitize_passwords --app STAGING_APPNAME
    heroku run rake db:migrate --app STAGING_APP_NAME
    heroku maintenance:off --app STAGING_APP_NAME 
    
    where DB_NAME is something like HEROKU_POSTGRESQL_JADE. This type of script is only relevant if using heroku and postgres, but you can do something similar if using other providers/databases. This post goes over a different way to do it if you are using mysql. ‘rake db:sanitize_passwords’ would be a task of your own creation to sanitize all the passwords of the users (very important) and also (less important, but still good for privacy) remove identifying data.
  4. Add staging to your database.yml. This should basically be a copy of production, but the database name should be something like #{product}_staging.

I’ve probably missed a few small things, but after that, basically just look for 'production’ in your app and add matching bits for 'staging’.

UPDATE: I did miss something after all. One of my former coworkers brought this to my attention: '3a) Rake task to sanitize/de-identify data, reset passwords?’. In the script I’m actually running, I am updating the credit card information so each customer just has a Stripe test account with a atest card instead of linked to their actual account, but I definitely did forget to reset passwords. Another reason this is useful is that, if you reset all your staging passwords to the same thing, you can login as any user on your test environment to debug any issues they may be having.