Hello i'm starting to deploy my rails application in Digital Ocean host, before that i was developing locally and using webrick in Development mode, now that i'm deploy i'm using Unicorn in Production Env.
So if i change something on my sourcecode both envs will be affected. So why the exist? which the correct way to use it?
thanks
Rails environments allow developers to maintain common elements (code, certain gems) and custom elements (other gems, environment settings, etc) for development, test and production.
For instance, you may want to use a simple DB like SQLite for development and just capture any emails generated in your log, but in production you want to use Postgres and (obviously) you need to send emails to users. The Rails environment structure makes it very easy to maintain these separate configurations without duplication.
In your example, you want to use Unicorn in production as your application server. This is easily accomplished by adding the Unicorn gem in a production group in your Gemfile like so:
group :production do
gem 'unicorn', '4.8.3'
end
Of course you will also need a Unicorn configuration file but hopefully this helps you appreciate the power and utility of Rails environments.
I would recommend taking some time to read the documentation here.
Related
I am developing a gem for my application and want to see if my gem is working on a real application or not, but the problem is if I want to see the changes in the application I have to restart the server.
I have googled the issue but all the solutions were either not working or relatively old (backing to rails 3 or so); is there any way to see the changes without restarting the server in rails 5?
I don't think you can because Gems are initialized when you start the server. Any change to the gemfile or gems themselves will require a server restart. The same is true about Routes, Config, etc.
We're writing a Rails app that we want to be able to talk to any of several external data repositories via a uniform adapter interface, and we'd like to be able to add more later just by writing new implementations of that adapter interface (cf. ActiveRecord adapters).
Any one installation of the app will only need one adapter running, and we don't want to have to rev the code or even the Gemfile whenever we introduce a new adapter. Assuming we write each adapter as a standalone gem, what's the proper way to incorporate just one adapter gem at runtime, based on configuration?
Normally in Rails, you can only access gems that are listed in the Gemfile; Bundler enforces this. However that doesn't stop you from loading gems manually.
If your adapter gems are installed in a well-known location, then loading an adapter gem could be as simple as this:
$LOAD_PATH << "/path/to/adapters/my_adapter/lib"
require "my_adapter"
Where "my_adapter" is something you discover at runtime via configuration.
Put your configuration in the environment, as you're probably already doing.
For example, I use the dotenv gem.
Set an environment variable to your adapter gem name.
The result is an ENV var that Rails can access, such as:
ENV["adapter"] #=> "my_custom_gem_name"
Use the environment to pick the adapter, e.g. in your Rails config:
require ENV['adapter']
This presumes your gem name is the same as the require name. If your gem name is different, use the require name.
When you deploy a new adapter, you can put it anywhere on the Rails load path. Or you can adjust the Rails load path as you like e.g. adding a path to $LOAD_PATH.
An example of how to adjust the load path:
# /config/application.rb
module MyApp
class Application < Rails::Application
$LOAD_PATH << "/path/to/custom/gem"
require("my_custom_gem_name")
…
For example, put the gem code in ./lib, or install the gem into ./vendor or systemwide, using any tool you like such as scp or rsync or ansible, thus bypassing the typical bundle command.
You won't need to update the Gemfile.
I don't think there's a good way to do quite exactly what you ask. Part of the bundler system (that's what uses Gemfiles) is that only gems mentioned in your gemfile (and their dependencies) are available to your app, it is isolated to only them. If this sounds like a bad thing, we could have a long conversation about the pre-bundler dependency management problems that this system has successfully solved.
Option 1 -- what are you worried about anyway? There is probably no downside to including all the possible gems in your Gemfile, even if a given installation will only use one. If using Rails, you will want to make sure these gems are not require'd on launch. (If not using Rails, this might not be neccesary, as other environments don't necessarily ask bundler to require all gems on boot (which is wise), but won't hurt).
So all the gems will get installed in every installation, yes, but only the one you want to use will be loaded, when you issue the require at runtime -- you'll still want to do this on application load, perhaps in response to an ENV variable, to avoid any concurrency or load time weirdness. Anyway, the unused gems will just be sitting there on disk un-loaded. How big a downside is having them installed but not used? How much are you willing to increase the confusingness of your setup to get rid of this downside?
Option 1 is what I'd do.
Option 2 -- separate Gemfiles. Another option is preparing a separate Gemfile for each type of setup. Gemfiles are just ruby code, so you could have one 'base' gemfile including common gems, and then a separate Gemfile for each type of setup, which uses ruby to load/include the base gemfile and then adds the setup-specific gems. You'd give each Gemfile a separate name, Gemfile_adapter1 or whatever.
You're going to have to commit something to your source when you add support for a new adapter type, aren't you? Where does this adapter come from? I don't understand how you could do it without revising any code. Anyway, adding a new Gemfile for that adapter type when you add a new adapter doesn't seem like a huge barrier, but I dunno.
You can launch Rails specifying which of these gemfiles to use with the BUNDLE_GEMFILE env variable: BUNDLE_GEMFILE=./Gemfile_one rails server. And in every other command you do that will use the Gemfile. BUNDLE_GEMFILE=./SOME_GEMFILE bundle install. BUNDLE_GEMFILE=./SOME_GEMFILE RAILS_ENV=production bundle exec rake assets:precompile. If you use capistrano that's doing some of these things for you, figure out how to make sure cap uses the right BUNDLE_GEMFILE when it executes it. Figure out how to make your app server do that when it launches your app. Etc.
This will work out fine -- but is going to end up being a pain to keep track of and make sure it's working right in your entire devops stack.
I suppose you could even generate the Gemfiles at install time, instead of having them in your source repo, for even more confusing situation and another thing that can go wrong and be confusing to debug! (I wouldn't).
I'd consider this Option 2, but would prefer option 1 unless there were really good reasons it wasn't going to work.
Option 3 -- Don't use Bundler. You could abandon bundler and gemfiles entirely. Maybe, if you can convince Rails to do this somehow. It might be hard to convince Rails to do this.
If you could, you are in a situation where you have to install all your gems on your deploy system by hand, making sure they are the right versions and figuring out what versions are compatible with what other versions, and that no more recent versions you don't want are installed.
Then, at runtime, you just need to require all the gems you want, and the app will get the most recent version of that gem installed on the system.
I would never, ever, ever, do this. I don't know if you can get Rails to do it, but even if you could, I remember the dependency hell from before Bundler existed, and would never want to go back.
I want to implement capistrano in my ruby on rails project. I am using MongoDB as database .
I install capistrano gem.
capify .
[add] writing './Capfile'
[add] writing './config/deploy.rb'
[done] capified!
It gives me file deploy.rb inside the Config. What should i do inside. so where do i have to put mongoid.yml ? Working code is helpful for me to do or some hints is appreciable.
You should first be clear about why you want to implement capistrano :-)
Capistrano is a tool for making deployments easier - it allows for executing commands in multiple remote machines, via ssh.
For a default installation of a Rails App with mongodb, you don't need to have anything related to mongodb in the capistrano deploy.rb file.
You would add some mongodb stuff in this file if there is some mongodb related task that you want to accomplish every time the code is deployed to the remote servers.
Example: Here is a capistrano recipe example to synchronize local mongodb with production
I would recommend that you familiarize yourself with the basics of capistrano by watching the railscast episode on capistrano tasks.
Put mongoid.yml in /config, and type cap deploy in /.
Windows 7, Rails 3 here. I local/development mode, rails server does not handle multiple request at the same time. The process crash and the cmd prompt comes in front.
I've noticed this behaviour when :
having too much ajax request, too close from one another
loading a simple page on 2 browsers
Is there a way workaround that ? Change the local server (default is webrick) ? How is that done ?
Thanks.
I don't know if this still needs an answer but I did this by adding gem 'puma' to the Gemfile then you'll need to add config.threadsafe! to either your config/application.rb or the environment file you're running on (like config/environments/development.rb.
Sometimes you might not want threadsafe on so I so did this in my development.rb:
if ENV["THREADS"]
config.threadsafe!
end
Now (with what I did in my development.rb) I can do rails s Puma and it will run with a max of 16 threads and can handle multiple requests. You can also up the thread pool and configure more with Puma, docs are here
Update
Note that the use of config.threadsafe! is not needed in Rails 4+ and is deprecated I believe.
You need to install the mongrel gem and this specify which server you want to use when you rails s
I don't know how you guys do it on win systems. Why not run a virtual Unix box? isn't rails just much easier with it? So with Unix it would be something like:
Install mongrel gem:
gem install mongrel
Then specify which server you want to run:
rails server mongrel
I've inherited a rails site that I need to deploy (quickly!) to our webhost, which is a standard *nix shared server that uses FastCGI for rails apps. I've worked with rails sites on multiple occasions in the past but wouldn't consider myself an expert by any stretch.
This particular app was developed using capistrano, with which I've got no experience, and everything I've read leads me to believe that to deploy the app "properly" would require my setting up an external svn account, among other things, which aren't feasible given our time frame and hosting situation.
My question is: what is the best way to quickly get this application up and running without using capistrano? I received, along with the site files, a .sql dump that I've already imported, and I've configured config/database.yml to reflect the correct production db settings. Right now, running ruby script/console production yields the following error message:
/home/user1/ruby/gems/gems/activesupport-2.3.3/lib/active_support/dependencies.rb:443:in `load_missing_constant':NameError: uninitialized constant ApplicationController
Thanks for your consideration!
As the others already stated, you are probably using the incorrect version.
Rails switched from app_controller to application_controller (or something like that) in version 2.1 or 2.2.
There is a rake task that you should be able to run in that case:
rake rails:update:application_controller
It might help you.
As for the capistrano. In your deploy.rb you can add the parameter :deploy_via :
set :deploy_via, :copy
set :scm, :none
And it should use the copy you are having in your working directory to deploy with (no need for subversion or any other version control)
Copy usually fetches the code from a repository locally and then uploads it to the server, but also setting the :scm to none it should ignore that and just (hopefully) use your working copy instead.
All capistrano requires is a deploy.rb and a Capfile, this is not what is causing your error. From the looks of it it seems that the problem is that you're using a gem rails version which is incompatible with your app, do you know which version it was developed with? If so you should try vendoring your rails directory to the right version.
For deployment, if you're using FastCGI you can just upload the files to the host and set the appropriate permissions and you should be good to go. Going forward you might want to look at upgrading to a newer version of rails, using capistrano and changing your environment to use apache passenger.
I hope this helps.
The problem you're running into appears to be a mismatch of your installed version and the version that the app is expecting. Look in config/environment.rb, Toward the top you'll see something that looks like:
RAILS_GEM_VERSION = '2.3.4'
You need to make sure that the version of rails installed on your machine matches whatever version is declared in that file. You can do that by running:
sudo gem install -v=X.X.X rails
where X.X.X matches what was in your environment.rb.
Jonnii is suggesting you "freeze" your rails by including all the rails code into your project directly, (which can be done by running rake rails:freeze:gems AFTER you have followed the above steps and gotten the correct gems installed in the first place.) Once you've frozen rails, then you no longer need to have the rails gems installed on your webserver machine.
Good luck!