dev and prod systems in rails - ruby-on-rails

What exactly is the difference in rails between dev and prod environments.
When I develop an application in dev mode, do I have peformance problems, or others if I clone my dev environment on prod?

Environments are similar to rails initializers, here's a short list of common differences:
Dev mode loads the development environment, production loads the production environment. You can find the files/settings for each in /config/environments/*.rb.
The development environment is usually set to display rendering information, system information, and RJS errors.
The development environment will usually have caching disabled.
I'm not sure if this still holds true, but the rails development environment has been known to have issues with memory leaks and should never be used on applications running on machines with production software.
Documentation on settings that can be used within the environment configurations can be found here: http://guides.rubyonrails.org/configuring.html

Dev mode won't cache your code, won't cache SQL, it will show you exceptions including your code, no optimizations, etc. Not recommended to distribute it like that, even though you can configure all those under config/environments/development.rb

Related

Deploying Rails on Staging and Production using Capistrano 3

i have a rails app developed with 4.2.6 and ruby 2.2.4. Its my application so I am the only one responsible for the development, testing and deployment.Now I have few questions related to deployment and would appreciate if someone can help me.
I have two separate servers on digital ocean for staging and production.So how can i deploy my application or what should be the order of deployment when i am done with the development and testing.So..
i should be deploying the code on Staging(quite obvious) and then after testing successfully, in the staging server, deploy it to the production.Is this the way to go ahead.
Or deploy the code on staging and after testing, just deploy the changes only to the production and restart the production server.
Moreover, having separate git repository for both pro and staging good or how should i proceed with code maintenance.
What is the best approach.Is there something which i really need to understand or missing.Kindly help me the goodies with deployment and what suits the best?
Thanks in advance.
First, Yes your first assumption is correct you run you app in development on your local machine then when you are satisfied you test in in a production like environment which is staging then if you test everything an its fine then do a final deploy to production where its ready to be accessed by your users.
Second you dont need to have different git repos for both you should have a main branch where everything goes when its ready for production most of the times this is called master....then for the feature you are working create a separate branch where the changes goes and this is the branch where you add new features to your application usually known as develop or the name of the feature or name bug you are fixing...capistrano will allow you to choose what branch to deploy
Third afer you install capistrano it generates 2 file a staging and production file in the directory config/deploy customize this individually place the ip or endpoin/url of staging server in staging.rb and for production server inproduction.rb

Should development server's configuration be the same with the production server?

I have been learning about AWS to deploy my rails application. It seems AWS Beanstalk is the easiest one I can use for my deployment. It even provides CLI tool so that I may be able to deploy easily as I do in Heroku.
But what I haven't still figured out is whether my development server's configuration should be the same with the production server which is a AWS Beanstalk stack.
For example, is it possible to use a different OS between the development server and production server? Ruby, MySQL, Web server and all other stuffs should be the same?
Using identical configuration (especially operating systems and software) isn't a hard requirement, it is a recommendation.
It might often happen that some code doesn't run on your production environment but works perfectly on your development machine because of some underlying incompatibility in your code or your libraries with your production stack. This could be avoided if you used the same software on your dev machine.
As for your question, it is possible to use different OSes or software versions on your dev/prod servers, but this is highly unrecommended.

How to manage application configurations/environment variables in production

I read some articles stating that application configs/parameters should be kept out of version control and be set as environment variables in the production environment.
My question is: How do you manage these environment variables?
Using a configuration management tool like Puppet? What if you are deploying a new version of your app and need to add some new configuration variables?
Your deploy scripts will probably also be in version control so if you set any production variable in there everyone with deploy access can see it. (and tools like Capistrano stores the deploy scripts together with application source code.)
What are the common practice for this?
Thank you for your help.

Ruby development environment (OS X vs. Ubuntu)

I'm a developer who uses RoR-CoffeeScript-Sass-Passenger-Apache. We use EC2 for our deployment and we have Macbook Airs for development. While the rails community is very much Mac-friendly, because of the whole deployment stack difference in dev vs. prod, I'm using a virtualbox+ubuntu while my peers are developing on OS X native.
Having on OS X Native adds more problem as we have more dependencies in the stack (Solr, Beanstalk, Mongodb and more which works well in Ubuntu)
I'm looking for suggestions on how Rails developers using Mac and Amazon EC2 can have their dev and prod environment setup.
Would also like feedback on use of vagrant for distribution of development environments for this use case.
A common practice would be to replicate your stack as a "staging" environment. With EC2, you can just create AMI's of your existing machines and duplicate them, turning them on only to test deploys, and run your tests to make sure everything is running properly before deploying it to production. Or often you may wish to leave it on permanently so developers can quickly deploy updates or patches to test as need be.
Doing it this way ensures that you have an exact replica of your production system to test before rolling out, thereby eliminating any (catastrophic) issues pertaining to the deploy sneaking out into production.
Our team has been been developing on Macs and deploying to Ubuntu on EC2 for three years now with very few issues. Several things have helped make this a smooth process:
We can run the entire app stack** on a Mac. Between macports, homebrew, and building from source when necessary, we have managed to get every piece of technology that we run in prod working on our dev boxes. The way the pieces are configured and fit together is different locally (in prod, for example, we auto-discover our memcached instance, whereas locally it's hard coded) but every integration can be tested on Macs first before going to prod.
Our continuous build system is on the same setup as our prod boxes. This means if you check in some code that depends on some piece of local magic it's discovered quickly.
We run a soak (some people call this staging or integ) stack that is configured identically to production. This sometimes causes some development overhead but has so many benefits that it's well worth it. All code goes through this stack before being pushed to prod.
This setup has worked well enough that over time we've allowed more parts of the setup to drift apart. We used to run passenger locally (like we do in prod) but now use Pow. We regularly experiment with new ruby versions in development for some time before upgrading the rest of the stack.
I've had to develop using a virtualized environment for other projects (OSX + CentOS in VirtualBox) and definitely found it more painful that all-native. For one, it felt like managing two machines instead of one. Everything also felt sloooooowww.
If there's a piece of the stack that is painful to run on the Mac, I would definitely prefer to take the hit of either a) spending the time of getting it working locally or b) abstracting that piece away, rather than pay the tax of dealing with a virtual environment.
** I'm only including the Rails app and direct dependencies in this discussion. For example, we use puppet to configure our EC2 fleet, but don't run it on our dev boxes.

Why is it supposedly "hard" to deploy Ruby on Rails to production?

I admit that I don't follow much of anything "right" on deploying test versus production code. I have been using ASP.NET, and I typically run it locally in Visual Studio, it works, I upload it, I test it again on the production server.
I have read several people say that deploying Rails apps is harder and there are special programs/ways on the ruby site about deploying RoR. I've only toyed with RoR. What is special about deployment? You don't just copy and paste the code and run it (from development machine to the production)? Is it because one is in Apache and the other running on the built in server?
This will be on a Mac Server if it matters.
Deploying RoR is not difficult anymore, especially with Phusion Passenger.
What is somewhat difficult, is getting a automated production environment setup with capistrano, vlad, etc. If you don't mind simply copying your code to the server, you can do that just fine. Most people choose not to do it that way because you lose out on a lot of the benefits that the automated deployment tools give you.
I guess people consider a Rails app harder to deploy than say some PHP apps or such where you just plop the code somewhere and point Apache or whatever at it. But, as mentioned above, you could do that now with Phusion Passenger.
We use Nginx+Passenger, but not for simplicity of deployment. Capistrano is our deploy tool of choice, and really, unless you have a very simple app, you're going to want something like Capistrano anyway. For example, with our deploy, we do a slew of things:
run any database migrations
generate release notes automatically, based on all the commits to Git between the last deploy and this one
notify various people via email (with differing lists depending on whether the deploy is to our staging environment or production) - we do this via cap_gun which integrates with Capistrano.
Notify New Relic RPM of the deploy so it can mark it in our RPM analysis
Notify Hoptoad of the deploy, so it too can have that data when reporting any exceptions
produce our sitemap.xml file, and ping Google to tell them there's a new one
update crontab files (I store our crontab files for each server in our git repo, and then on deploy it sees if there is a new version and updates accordingly, etc.).
flush/restart memcached
There are other ways aside from Capistrano, but it's a proven tool, with a lot of flexibility, yet pretty simple to setup a vanilla configuration.
So, my take is that once you get into any app that is beyond just the very simplest of apps, you're going to need/want to be doing things other than just simply updating the code. In the beginning though, if you just need the code updates, and maybe Rails migrations, then you can do simpler things like Passenger and code sync, or look at tools like Heroku or Engine Yard's stuff where they do a deploy by doing a Git clone (and then offer some additional abilities).
Another super easy way to deploy is with http://heroku.com/
Some of the issues you face with deploying rails to production:
Database connection.
You need to be sure that the database connector is set up for the production environment.
Database migrations.
You have to run database migrations against the production database even though you may have already run them in production/testing/staging
Ruby version. The version or sub-version or Ruby can trip you up, e.g. An error occurred while installing debugger-linecache (1.1.1), and Bundler cannot continue
Gem dependency.
Your production environment may have different packages and gems from development. Bundler will figure this out for the most part and install the dependencies but occasionally there are still issues that you have to resolve manually.
Dependencies.
Some gems on some machine have particular dependencies. I have seen frequent problems with using gems on my unix box that work on OSX and vice-versa.
Note the last 3 shouldn't affect you if on the same machine but I included them based on the title and to be comprehensive.
It's not especially hard. If you stick to conventions then with a little bit of configuration it boils down to this:
cap deploy
...however there is sometimes a bit of effort needed up front to get the workflow in place.
The good news is that lots of people have packaged up solutions and stacks for RoR that you can just plug and play. For example, google ec2onrails - this is a packaged Ubuntu image and set of capistrano tasks for running rails apps in Amazon's EC2 cloud, with lots of common stuff set up already out of the box.
Choose a good hosting provider and you should be able to find something similar for that also.
An easy way to deploy Rails apps is to use Phusion Passenger. Deployment doesn't get much easier than that for any programming language or framework. You can do that on a Mac server.
Another really easy way to deploy rails is with jruby and the glassfish gem.

Resources