Not all versions of Node.js are compatible with each other. Also npm packages may require a minimum or maximum version of Node.js. We use nvm on our development PCs so we can operate multiple versions of Node.js in parallel.
To make sure that all developers use a compatible version of Node.js, your Rails project should declare the required Node.js in a file called .nvmrc
.
When a .nvmrc
exists, developers can cd
in your project directory and activate...
When deploying with capistrano it's possible you get this "error" message:
*** [err :: example.com] There are no Phusion Passenger-served applications running whose paths begin with '/var/www/example.com'.
*** [err :: example.com]
This is just because there were no running passenger process for this application on the server which could be restarted. It's not a real error. The application process will start if the first request for this app hits the appserver.
The output appears as err
because it's printed to stderr
.
This is a short overview of things that are required to upgrade a project from the Asset Pipeline to Webpacker. Expect this upgrade to take a few days even the diff is quite small afterwards.
1. Find all libraries that are bundled with the asset pipeline. You can check the application.js
and the application.css
for require
and import
statements. The source of a library is most often a gem or a vendor directory.
2. Find an working example for each library in the application and write it down.
3. Find out the ver...
While deploying an Ruby update to an old application these days, we encountered the following misleading error:
*** [err :: some-host.makandra.de] You are trying to install in deployment mode after changing
*** [err :: some-host.makandra.de] your Gemfile. Run `bundle install` elsewhere and add the
*** [err :: some-host.makandra.de] updated Gemfile.lock to version control.
*** [err :: some-host.makandra.de]
*** [err :: some-host.makandra.de] You have deleted from the Gemfile:
*** [err :: some-host.makandra.de] *
We found out a newe...
Remember How to skip Sprockets asset compile during Capistrano deployment and Automatically skipping asset compilation when assets have not changed? Turns out there is an even better way to speed up Capistrano deployments with asset compilation – and it's even simpler.
Popular asset managers for Rails are Sprockets and Webpacker. Both keep a cache of already compiled files that we're going to leverage for deployments now.
Font Awesome 5 is a comprehensive solution for vector icons on your website.
Originally, Font Awesome came as an icon font (plus stylesheets), but recently it can also be used as a pure JavaScript solution (which will render icons as inline <svg>
tags), or even as SVG sprites.
All solutions have their pros and cons:
Icon font:
Javascript + inline SVG:
Phusion Passenger changed the way how it gets restarted several times. Through the project's history, these all were valid:
touch tmp/restart.txt
sudo passenger-config restart-app /path/to/app
passenger-config restart-app /path/to/app
You should not need to know which one to use. Instead, the capistrano-passenger gem will choose the appropriate restart mechanism automatically based on your installed the passenger version.
Add to your Gemfile
:
gem 'capistr...
In this example we assume that not only the storage gem changes but also the file structure on disc.
Part A: Create a commit which includes a script that allows you to copy the existing file to the new file structure.
Part B: Create a commit which removes all paperclip logic and replace it with the same code you used in the first commit
Here are some implementation details you might want to reuse:
Just like Ruby Gems tag their version releases to the corresponding Git commit, it can be helpful to track production deploys within the commit history. This task does the tagging for you.
# lib/capistrano/tasks/deploy.rb
namespace :deploy do
...
desc 'Tag the deployed revision'
task :tag_revision do
date = Date.today.to_s
puts `git tag deploy-#{date} #{fetch :current_revision}`
puts `git push --tags origin`
end
end
# config/deploy/production.rb
after 'deploy:finished', 'deploy:tag_revi...
In medium-sized to large Rails applications, asset compilation can take several minutes. In order to speed up deployment, asset precompilation can be skipped. This card automates the process.
namespace :deploy do
desc 'Automatically skip asset compile if possible'
task :auto_skip_assets do
asset_locations = %r(^(Gemfile\.lock|app/assets|lib/assets|vendor/asset))
revisions = []
on roles :app do
within current_path do
revisions << capture(:cat, 'REVISION').strip
...
When your application is running on a multi-server setup, application logs are stored per server (unless you choose a centralized logging solution).
Here is a Capistrano task that connects to all servers and prints logs to your terminal like this:
$ cap production app:logs
00:00 app:logs
01 tail -n0 -F /var/www/your-application/shared/log/production.log | while read line; do echo "$(hostname): $line"; done
01 app01-prod: Started GET "/sign_in" for 1.2.3.4 at 2018-04-26 11:28:19 +0200
01 app01-prod: Proc...
By default, Capistrano truncates server responses and places an ellipsis at the end of lines that are longer than your terminal. Error messages are never truncated.
While this can be helpful to make deployment output appear less noisy, it also hides information that could be helpful.
I believe you should prefer knowing what is going on, even if causes a few extra lines of output.
Capistrano by default uses Airbrussh which is where truncation happens. To disable truncation globally, place this into your deploy.rb
:
set :format_options...
For applications coming with lots of stylesheets and scripts, asset compilation might take quite long. This can be annoying when deploying a release that does not actually change assets.
When your app uses Sprockets, you can simply skip asset compilation and re-use the previous release's assets. [1]
That is especially easy via Capistrano. Capistrano will automatically symlink your release's public/assets
to a shared directory, so all you need to do is skip the deploy:assets:precompile
task.
Put the following code where you'd put other ...
Some cronjobs must only run on a single server. E.g. when you run nightly batch operations on the database, it should probably run on a single server. Running it on multiple servers would likely result in deadlocks or corrupt data.
Some cronjobs must always run on all servers. E.g. starting a sidekiq process on reboot.
If not configured otherwise, cronjobs defined in whenever's `s...
Capistrano has the concept of a "rollback" that comes in really handy in case of errors. When you notice that your recent deploy was faulty, run cap deploy:rollback
and you're back with the previous release. In case of an error during a deployment, Capistrano will rollback itself.
But, you may ask, how can it know how to revert all the custom stuff I'm doing during deployment? It can't. But you can tell it how to.
Deploy and rollback are nearly identi...
When you have a multi-server setup, you'll be adding a new server from time to time. Before doing a full deploy, you might want to test that server in an isolated deploy. There is a single way to do this: the HOSTFILTER
env variable.
Commenting out "server" lines in the Capistrano deploy config will raise a Capistrano::NoMatchingServersError
with <task> is only run for servers matching {:roles=> <role>}, but no servers matched
. Instead, specify the server-under-test like this:
HOSTFILTER=separate-sidekiq.makandra.de cap productio...
By default Middleman generates files with a .html
extension. Because of this all your URLs end in /foo.html
instead of /foo
, which looks a bit old school.
To get prettier URLs, Middleman lets you activate :directory_indexes
in config.rb
. This makes a directory for each of your pages and puts a single file index.html
into it, e.g. /foo/index.html
. This lets you access pages with http://domain/foo
.
Unfortunately you are now forcing every br...
Middleman is a static page generator that brings many of the goodies that Rails developers are used to.
Out of the box, Middleman brings Haml, Sass, helpers etc. However, it can be configured to do even better. This card is a list of improvement hints for a Rails developer.
Remove tzinfo-data
and wdm
unless you're on Windows. Add these gems:
gem 'middleman-livereload'
gem 'middleman-sprockets' # Asset pipeline!
gem 'bootstrap-sass' # If you want to use Bootstrap
gem 'byebug'
gem 'capistrano'
gem 'capistrano-mid...
Sometimes, through some firewall or proxy misconfiguration, you might have to deploy to a server that cannot access the git repository.
SSH can be tunneled over an HTTP Proxy. For example, when the repo is on github
, use this:
Install socat
Add a ~/.ssh/config
on the target server(s) with permission 0600 and this content:
Host github.com ssh.github.com
User git
Hostname ssh.github.com
Port 443
ProxyCommand socat - PROXY:<your proxyhost>:%h:%p,...
Looks like ActiveState is trying to market a new Ruby distribution for Enterprises:
ActiveRuby Enterprise Edition is designed for businesses with large Ruby deployments in essential, mission-critical applications that, when down, could cost your business in lost revenue and a damaged reputation. Deploy Ruby with confidence knowing you're using the most secure, enterprise-grade builds for the platforms that power your business. You'll get priority access to our Ruby experts for technical support and best prac...
We generally use multiple application servers (at least two) and you have to search on all of them if you don't know which one handled the request you are looking for.
Rails application logs usually live in /var/www/<project-environment-name>/shared/log
.
Web server logs usually live in /var/www/<project-environment-name>/log
.
grep
/ zgrep
You can use grep
in this directory to only search the latest logs or zgrep
to also search older (already zipped) logs. zgrep
is used just like grep
...
On application servers, gems are usually bundled into the project directory, at a location shared across deployments.
This is usually shared/bundle
inside your project's root directory, e.g. /var/www/your-project/shared/bundle/
.
If you can't find that, take a look at current/.bundle/config
and look for BUNDLE_PATH
.
When you are changing the version of RubyGems or Bundler on a system where gems are installed this way, you must wipe that bundle directory in addition to the user and system gems or gems that are already ins...
Reminder of what you can do with Geordi.
Note: If you alias Geordi to something short like g
, running commands gets much faster!
Note: You only need to type the first letters of a command to run it, e.g. geordi dep
will run the deploy
command.
Guided deployment, including push, merge, switch branches. Does nothing without confirmation.
Run something for all Capistrano environments, e.g. geordi cap deploy
When you just clon...
Sometimes huge refactorings or refactoring of core concepts of your application are necessary for being able to meet new requirements or to keep your application maintainable on the long run. Here are some thoughts about how to approach such challenges.
Try to break your refactoring down in different parts. Try to make tests green for each part of your refactoring as soon as possible and only move to the next big part if your tests are fixed. It's not a good idea to work for weeks or months and wait for all puzzle pieces ...