Parity
Keeping development and
production environments in sync
for fun, profit, and sanity
Hi, I’m Geoff
I’m the CTO at Cortex
http://cortexintel.com
Developing in Ruby since 2008
Formerly operator of
Five Tool De...
What is parity?
Parity is consistency in the configuration of your
application’s environments (production, staging,
develo...
Why is this important?
• When your tests pass, you should be confident that
your code works.
• When you have parity, you'l...
Achieving parity
• Make the time gap small: a developer may write code
and have it deployed hours or even just minutes lat...
Setup for parity
• Use the same backing services and support
software in all environments
• At Cortex our bootstrap script...
Backing Services
• Database (Postgres, MySQL, Mongo, etc)
• Queues (Sidekiq, Resque, DelayedJob)
• Storage (local disk, AW...
The adapter fallacy:
ActiveRecord
• ActiveRecord promises portability, but most
applications will eventually implement beh...
Tools for parity
• Foreman - process manager
• Setup script
• pow - app/DNS/proxy with nice “.dev” domain
names
• Tunnelss...
Foreman
• Process manager that works well locally as a stand-
in for Heroku
• Runs web and background processes like Sidek...
Parity gem and Heroku
• Name your app folder big-red-machine
• Name your Heroku remotes big-red-machine-
staging and big-r...
Moving data with parity
• production backup - takes a snapshot on production
• staging restore production - copies the lat...
Rails environment setup
• Make differences between your environments
explicit
• Move universal configuration to applicatio...
Differences in development
For your own sanity, some items might be smart
candidates to break parity in your development
e...
Windows?
• If you deploy to a POSIX system (Linux, BSD, etc.),
you should be doing development or at least your
testing in...
Configure with ENV
Never store credentials or secrets in source control
Environment can be used for configuration beyond
c...
Local ENV
• Rails 4.1 introduced secrets.yml, a standard way to
store local credentials
• dotenv/dotenv-rails can load cre...
Careful what you mock
You should not need a network connection to run your
tests locally
In integration tests, don’t stub ...
Fog and Amazon
• Use Fog to abstract Amazon S3 so that local
development and test machines don’t need the
network
• Allows...
Strategies for parity
• Use the same backing services everywhere!
• Manage packages with a package manager such as
Homebre...
OSX protip: brew services
Can’t remember how to turn on PostgreSQL? How to
restart Redis? Use brew services
• brew service...
Strategies for parity
Avoid Rails.env.production? checks. Use tools like
custom_configuration
# config/environments/produc...
Make it easy on testers
• My app serves locally at http://cortex.dev
• My laptop is on the IP address 10.0.1.37
• My teste...
Strategies for deployment
• Keep your PRs as small as is reasonable
• Only merge to master code you’re ready to ship
• Dep...
Make deployment easy
• You should be able to do most deploys with
ONE (1) command
• Reduce the number of things you can fo...
Protect yourself
Automating deployment means:
• You don’t forget to run migrations
• You don’t forget to update reference ...
How we deploy
• Alias or script: push-to-staging, push-to-production,
push-to-demo
gp staging $(git symbolic-ref --short -...
Heroku Buildpacks
• Tim Pope’s Ruby buildpack tracks with Heroku’s
buildpack, but always runs migrations without
requiring...
Questions?
Further Reading
• Heroku's 12 Factor App site: http://12factor.net/
• parity gem: http://github.com/croaky/parity
• Forema...
Thanks!
I love talking about Ruby and Rails, so feel free to
reach out to me with questions!
email: geoff@cortexintel.com
...
Upcoming SlideShare
Loading in …5
×

DCRUG: Achieving Development-Production Parity

625 views
471 views

Published on

Thursday, June 12th 2014

Discussing strategies in Rails development for keeping multiple application environments as consistent as possible for the best development, testing, and deployment experience.

Published in: Software, Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
625
On SlideShare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
10
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide
  • At Cortex, we have production, staging (stakeholder QA), development (my laptop), test (my laptop), and CI (Travis, build verification)
  • You should strive to have your development and production environments as close to each other in configuration and behavior as possible so that your development (or testing) environment is an accurate representation of your deployed code in production.
  • Aaron Patterson from Rails Core has a joke that no app has ever successfully switched databases

    PG does not support strftime
  • DCRUG: Achieving Development-Production Parity

    1. 1. Parity Keeping development and production environments in sync for fun, profit, and sanity
    2. 2. Hi, I’m Geoff I’m the CTO at Cortex http://cortexintel.com Developing in Ruby since 2008 Formerly operator of Five Tool Development
    3. 3. What is parity? Parity is consistency in the configuration of your application’s environments (production, staging, development, test, etc.)
    4. 4. Why is this important? • When your tests pass, you should be confident that your code works. • When you have parity, you'll find many more bugs and configuration idiosyncrasies in development, before you get to a QA or (gasp) production phase.
    5. 5. Achieving parity • Make the time gap small: a developer may write code and have it deployed hours or even just minutes later. • Make the personnel gap small: developers who wrote code are closely involved in deploying it and watching its behavior in production. • Make the tools gap small: keep development and production as similar as possible. Source: http://12factor.net/dev-prod-parity
    6. 6. Setup for parity • Use the same backing services and support software in all environments • At Cortex our bootstrap script (modified from Thoughtbot’s suspenders-created script) installs PostgreSQL, Redis, node.js, and Bower if those packages are not already installed. It then sets up pow, foreman, tunnelss, so we can serve the app at http://cortex.dev and https://cortex.dev
    7. 7. Backing Services • Database (Postgres, MySQL, Mongo, etc) • Queues (Sidekiq, Resque, DelayedJob) • Storage (local disk, AWS, CloudDrive, SkyDrive) • Search (solr, Elasticsearch) • Caching (Rails In-memory, Memcached)
    8. 8. The adapter fallacy: ActiveRecord • ActiveRecord promises portability, but most applications will eventually implement behavior that isn’t consistent across different databases in the form of SQL literals or queries that return different results • Rails encourages the use of SQLite in development, but there’s no reason not to use the database you’re going to use in production
    9. 9. Tools for parity • Foreman - process manager • Setup script • pow - app/DNS/proxy with nice “.dev” domain names • Tunnelss (fork of tunnels) - route SSL to another port locally • Parity - easy management of Heroku environments
    10. 10. Foreman • Process manager that works well locally as a stand- in for Heroku • Runs web and background processes like Sidekiq, DelayedJob, or Resque • Easy to configure alongside pow
    11. 11. Parity gem and Heroku • Name your app folder big-red-machine • Name your Heroku remotes big-red-machine- staging and big-red-machine-production • Use parity aliases to execute commands easily on Heroku • migrate, rake, log, tail, log2viz, console, config, open
    12. 12. Moving data with parity • production backup - takes a snapshot on production • staging restore production - copies the latest production backup to staging • development restore production - copies the latest production backup to local dev
    13. 13. Rails environment setup • Make differences between your environments explicit • Move universal configuration to application.rb or initializers • Have environments inherit from a base environment (staging and demo from production), then override the few items that are different
    14. 14. Differences in development For your own sanity, some items might be smart candidates to break parity in your development environment: • Eager loading • Asset compilation • SSL
    15. 15. Windows? • If you deploy to a POSIX system (Linux, BSD, etc.), you should be doing development or at least your testing in a similar environment • Use Vagrant or other virtualization tools to run a facsimile environment locally
    16. 16. Configure with ENV Never store credentials or secrets in source control Environment can be used for configuration beyond credentials! • S3 configuration • CDN setup • DB connection pool size
    17. 17. Local ENV • Rails 4.1 introduced secrets.yml, a standard way to store local credentials • dotenv/dotenv-rails can load credentials from Heroku configs (downloaded with heroku config:pull) • Figaro performs similar functionality to Rails 4.1’s secrets.yml (YAML format, one file for all environments)
    18. 18. Careful what you mock You should not need a network connection to run your tests locally In integration tests, don’t stub or mock gems that interface with external services. Record a real response with the vcr gem, then replay that on later tests (make sure to strip out credentials after recording!)
    19. 19. Fog and Amazon • Use Fog to abstract Amazon S3 so that local development and test machines don’t need the network • Allows common interface for local and external storage • In our CI environment, we make a real connection to S3 to confirm that our local setup is not hiding a real problem
    20. 20. Strategies for parity • Use the same backing services everywhere! • Manage packages with a package manager such as Homebrew or apt-get • Use the same application server in development as production. If you’re using Unicorn in production, don’t use WEBrick in development
    21. 21. OSX protip: brew services Can’t remember how to turn on PostgreSQL? How to restart Redis? Use brew services • brew services list • brew services start postgresql • brew services restart redis
    22. 22. Strategies for parity Avoid Rails.env.production? checks. Use tools like custom_configuration # config/environments/production.rb BCX::Application.configure do config.x.resque.jobs_inline = true end # config/initializers/resque.rb if Rails.configuration.x.resque.jobs_inline Resque.inline = true end
    23. 23. Make it easy on testers • My app serves locally at http://cortex.dev • My laptop is on the IP address 10.0.1.37 • My tester can reach my machine at http://cortex.10.0.1.37.xip.io • When you’re not on the same subnet, use ngrok or Finch
    24. 24. Strategies for deployment • Keep your PRs as small as is reasonable • Only merge to master code you’re ready to ship • Deploy early and often (or… continuously!) • Automate your deployment process • Reduce the number of things you can forget
    25. 25. Make deployment easy • You should be able to do most deploys with ONE (1) command • Reduce the number of things you can forget through automation • Don’t trust that you or your teammates will follow a checklist every time
    26. 26. Protect yourself Automating deployment means: • You don’t forget to run migrations • You don’t forget to update reference data • You don’t forget to recompile or sync assets • You don’t forget to restart the server
    27. 27. How we deploy • Alias or script: push-to-staging, push-to-production, push-to-demo gp staging $(git symbolic-ref --short -q HEAD):master --force && staging migrate • Always rebuild assets with bower • Always run migrations • Always apply production data updates
    28. 28. Heroku Buildpacks • Tim Pope’s Ruby buildpack tracks with Heroku’s buildpack, but always runs migrations without requiring a second connection and app restart • We use qnyp/heroku-buildpack-ruby-bower to automatically build our assets from Bower whenever we deploy, which helps avoid issues where we forget to sync assets
    29. 29. Questions?
    30. 30. Further Reading • Heroku's 12 Factor App site: http://12factor.net/ • parity gem: http://github.com/croaky/parity • Foreman as process manager, Pow as DNS server: http://robots.thoughtbot.com/foreman-as-process- manager-pow-as-dns-server-and-http • Beyond the default Rails environments: http://signalvnoise.com/posts/3535-beyond-the- default-rails-environments
    31. 31. Thanks! I love talking about Ruby and Rails, so feel free to reach out to me with questions! email: geoff@cortexintel.com Github: geoffharcourt Twitter: @geoffharcourt

    ×