For my Rails 3.2/Capistrano 3 application I configured 2 deploy environments: staging and production.
I don't want to spend time on assets compilation when deploy to staging, since it should be the same as local development.
In my Capfile I have
require 'capistrano/rails/assets'
which is needed for production, but with this line Capistrano also compiles assets for all other environments.
How can I configure it to compile assets(or skip compilation) for specific environments?
Try adding this line to config/environments/staging.rb file
config.assets.compile = false
Related
what's the differences between these two tasks, why i need to add RAILS_ENV=production when cap deploy?
thanks!
You need to specify RAILS_ENV=production environment variable so that your config/environments/production.rb configuration file is used when precompiling assets. It usually contains production configuration for assets pipeline:
config.assets.js_compressor = :uglifier
config.assets.digest = true
If you omit RAILS_ENV=production then development configuration will be used (config/environments/development.rb).
The first one will precompile your assets on your local dev box (development environment) and the other will precompile your assets on your production environment. Your settings in your config files are most likely different and so it will go of what is configured off what is in the environment config for whatever you set RAILS_ENV to.
Was going to write as a comment but too long...
--
Production vs Local
Something you also need to consider with this, is if you're precompiling for the production environment, it essentially compiles & configures your files for that environment
Simply, this means if you have any special conditions / dependencies for production only, using RAILS_ENV=production will use these over your local setup. This is why you'll have this setup in your Gemfile:
#Gemfile
group :production do
gem 'xxxx'
end
--
SHELL VARIABLES
Something else you need to appreciate is RAILS_ENV is a SHELL VARIABLE. This means that whenever you run a shell session (I.E load cmd), these variables can be set to provide specific functionality.
In relation to RAILS_ENV, it means you'll be able to tell Rails to run in production mode for the time being; as opposed to running in development, testing or staging modes
I have rails 4.1 app and multistage (staging, production) deployment with capistrano3.
I want to deploy it to one stage server (which use rvm) and one production server (which use ruby env)
By default everything works nice on production server, but without rvm1-capistrnao3 gem installed and included in Capefile I cannot deploy to staging.
Is there a way to require 'rvm1/capistrano3' in Capefile, only if I deploy to staging like that
cap staging deploy
Here is what I've done to fix it
I made default capistrano multistage setup, like Doug Hall said!
The tricky part is the way to include rvm1-capistrano3 in Capefile
See deepak's workaround here https://github.com/capistrano/rvm/issues/49
So instead of just require 'rvm1/capistrano3' in Capefile, do it like that
task :use_rvm do
require 'rvm1/capistrano3'
end
task 'staging' => [:use_rvm]
When you run cap install, it creates a file called config/deploy.rb and two files in the config/deploy directory: production.rb and staging.rb. Use the config/deploy.rb file for all settings that both the production and staging servers have in common. Use the other two for the respective settings on those machines. I would require 'capistrano/rvm' in your Capfile, but only use it in the config/deploy/staging.rb file. Capistrano executes the common config/deploy.rb FIRST, then calls the proper staging.rb/production.rb file, so all set values from config/deploy.rb are available in the staging.rb/production.rb file.
what's the differences between these two tasks, why i need to add RAILS_ENV=production when cap deploy?
thanks!
You need to specify RAILS_ENV=production environment variable so that your config/environments/production.rb configuration file is used when precompiling assets. It usually contains production configuration for assets pipeline:
config.assets.js_compressor = :uglifier
config.assets.digest = true
If you omit RAILS_ENV=production then development configuration will be used (config/environments/development.rb).
The first one will precompile your assets on your local dev box (development environment) and the other will precompile your assets on your production environment. Your settings in your config files are most likely different and so it will go of what is configured off what is in the environment config for whatever you set RAILS_ENV to.
Was going to write as a comment but too long...
--
Production vs Local
Something you also need to consider with this, is if you're precompiling for the production environment, it essentially compiles & configures your files for that environment
Simply, this means if you have any special conditions / dependencies for production only, using RAILS_ENV=production will use these over your local setup. This is why you'll have this setup in your Gemfile:
#Gemfile
group :production do
gem 'xxxx'
end
--
SHELL VARIABLES
Something else you need to appreciate is RAILS_ENV is a SHELL VARIABLE. This means that whenever you run a shell session (I.E load cmd), these variables can be set to provide specific functionality.
In relation to RAILS_ENV, it means you'll be able to tell Rails to run in production mode for the time being; as opposed to running in development, testing or staging modes
Right now, every time I am changing something in the assets, I have to delete the assets folder from the public directory and then run rake assets:precompile to take effect.
Is this something right or wrong so I should put it in a capistrano task to do it automatically?
For some reason, it doesn't compile automatically the assets in production and it throws errors if I don't do the above (or it doesn't take effect the changes if there is the files already). Is there something I should put in the environments/production.rb?
Also I don't understand what the following code in the production.rb does:
# Don't fallback to assets pipeline if a precompiled asset is missed
config.assets.compile = true
I tried false and true but I didn't understand the difference.
I'm a bit confused as at how it should work the workflow in production, if what I am doing is right and about the settings for the assets in production.
Capistrano has built-in support for precompiling assets during deployment. Just add this line to your deploy.rb file:
load "deploy/assets"
I prefer not to concatenate JavaScript files in development mode, but serve them as individual files. So I configured:
development.rb:
config.assets.compress = false
config.assets.debug = true
config.assets.compile = true
In my /app/assets/javascript directory I have:
reviews.js
reviews/
foo.js
bar.js
reviews.js:
//= require jquery
//= require jquery_ujs
//= require_tree ./reviews
I include the JavaScript using <%= javascript_include_tag "reviews" %> in my layout. The generated page correctly references the three scripts individually and reviews.js is essentially empty. So far so good.
Now when I precompile my assets for production using rake assets:precompile the three JavaScript files are concatenated into reviews.js. This is all fine for production but now, in development mode, the concatenated reviews.js is served in addition to the two individual files.
Of course, this leads to all kinds of nasty bugs when developing because now, the content of foo.js and bar.js is served twice, one of them in a potentially older version in reviews.js.
How can I make sure Rails doesn't use the precompiled assets in development mode?
In config/environments/development.rb set:
config.assets.prefix = "/assets_dev"
so that in development mode Rails will look there (but it will not find anything, as you will not compile assets in development (this is indeed what you are trying to do -- not compile assets)).
When precompiling for production, use
RAILS_ENV=production rake assets:precompile
so it compiles into the default assets folder, public/assets.
It sounds like you are precompiling locally. Because the files exist in the expected location they are being served by your dev server, and the requests are not going to Sprockets.
The only way to stop this is delete the compiled files.
Normally you do not need to compile locally. It is expected that in almost all cases the precompile task will be run during deployment of the app. There is a Capistrano recipe for this on the asset pipeline guide page.
If you do need to have those files locally committed to your repo you could use a branch to avoid the problem. Reserve your master branch for production code, and make a second branch for dev. Only compile and commit assets on master. When you switch to dev, they will be gone. Merge dev into master as required.
Edit: Make sure you force your browser to update (control + F5) or you may find the old assets used from the browser cache!
in config/environments/development.rb set:
config.serve_static_assets = false
and no files from /public will be served
I tried this and it worked. rake assets:precompile RAILS_ENV=production
I observed that the new version of assets pipeline does this when you run rake assets:precompile does rake assets:precompile:all