16

I am using Capistrano 3 with a newly generated Rails 4 app. My deployment is working, but when I run bundle exec rails console on the production server, I get a warning from Rails:

Looks like your app's ./bin/rails is a stub that was generated by Bundler.

In Rails 4, your app's bin/ directory contains executables that are versioned like any other source code, rather than stubs that are generated on demand.

Indeed the binstubs generated during deployment overwrite the binstubs in the repository:

The original binstub:

$ cat bin/rails

#!/usr/bin/env ruby
begin
  load File.expand_path("../spring", __FILE__)
rescue LoadError
end
APP_PATH = File.expand_path('../../config/application',  __FILE__)
require_relative '../config/boot'
require 'rails/commands'

The binstub in production:

$ cat bin/rails

#!/usr/bin/env ruby
#
# This file was generated by Bundler.
#
# The application 'rails' is installed as part of a gem, and
# this file is here to facilitate running it.
#

require 'pathname'
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../../releases/20140930173754/Gemfile",
  Pathname.new(__FILE__).realpath)

require 'rubygems'
require 'bundler/setup'

load Gem.bin_path('railties', 'rails')

What needs to change in order to make Capistrano configuration compatible with Rails 4?

# Gemfile
group :development do
  gem 'capistrano', '~> 3.1'
  gem 'capistrano-rbenv', '~> 2.0'
  gem 'capistrano-bundler', '~> 1.1.2'
  gem 'capistrano-rails', '~> 1.1'
end

# config/deploy.rb
lock '3.2.1'
# ...
set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system}
set :rbenv_map_bins, %w{rake gem bundle ruby rails}
# ...

Everything else is using the default settings.

Community
  • 1
  • 1
Andrew
  • 227,796
  • 193
  • 515
  • 708

1 Answers1

34

Since the ./bin directory is version controlled in Rails 4, we need to prevent Capistrano from linking it on deployments by removing bin from set :linked_dirs. Now in order to prevent bundler from overwriting the version controlled binstubs, we can add the line set :bundle_binstubs, nil which will prevent capistrano-bundler from setting the --binstubs option when running bundle install.

Hope that helps!

Nicholas DeLuca
  • 633
  • 6
  • 7
  • 3
    This exact solution is implemented as a fix for this very issue here https://github.com/capistrano/bundler/issues/45 – s01ipsist Dec 08 '14 at 00:59