Giter VIP home page Giter VIP logo

bundler's Introduction

Capistrano: A deployment automation tool built on Ruby, Rake, and SSH.

Gem Version Build Status Code Climate CodersClan

Capistrano is a framework for building automated deployment scripts. Although Capistrano itself is written in Ruby, it can easily be used to deploy projects of any language or framework, be it Rails, Java, or PHP.

Once installed, Capistrano gives you a cap tool to perform your deployments from the comfort of your command line.

$ cd my-capistrano-enabled-project
$ cap production deploy

When you run cap, Capistrano dutifully connects to your server(s) via SSH and executes the steps necessary to deploy your project. You can define those steps yourself by writing Rake tasks, or by using pre-built task libraries provided by the Capistrano community.

Tasks are simple to make. Here's an example:

task :restart_sidekiq do
  on roles(:worker) do
    execute :service, "sidekiq restart"
  end
end
after "deploy:published", "restart_sidekiq"

Note: This documentation is for the current version of Capistrano (3.x). If you are looking for Capistrano 2.x documentation, you can find it in this archive.


Contents

Features

There are many ways to automate deployments, from simple rsync bash scripts to complex containerized toolchains. Capistrano sits somewhere in the middle: it automates what you already know how to do manually with SSH, but in a repeatable, scalable fashion. There is no magic here!

Here's what makes Capistrano great:

Strong conventions

Capistrano defines a standard deployment process that all Capistrano-enabled projects follow by default. You don't have to decide how to structure your scripts, where deployed files should be placed on the server, or how to perform common tasks: Capistrano has done this work for you.

Multiple stages

Define your deployment once, and then easily parameterize it for multiple stages (environments), e.g. qa, staging, and production. No copy-and-paste necessary: you only need to specify what is different for each stage, like IP addresses.

Parallel execution

Deploying to a fleet of app servers? Capistrano can run each deployment task concurrently across those servers and uses connection pooling for speed.

Server roles

Your application may need many different types of servers: a database server, an app server, two web servers, and a job queue work server, for example. Capistrano lets you tag each server with one or more roles, so you can control what tasks are executed where.

Community driven

Capistrano is easily extensible using the rubygems package manager. Deploying a Rails app? Wordpress? Laravel? Chances are, someone has already written Capistrano tasks for your framework of choice and has distributed it as a gem. Many Ruby projects also come with Capistrano tasks built-in.

It's just SSH

Everything in Capistrano comes down to running SSH commands on remote servers. On the one hand, that makes Capistrano simple. On the other hand, if you aren't comfortable SSH-ing into a Linux box and doing stuff on the command-line, then Capistrano is probably not for you.

Gotchas

While Capistrano ships with a strong set of conventions that are common for all types of deployments, it needs help understanding the specifics of your project, and there are some things Capistrano is not suited to do.

Project specifics

Out of the box, Capistrano can deploy your code to server(s), but it does not know how to execute your code. Does foreman need to be run? Does Apache need to be restarted? You'll need to tell Capistrano how to do this part by writing these deployment steps yourself, or by finding a gem in the Capistrano community that does it for you.

Key-based SSH

Capistrano depends on connecting to your server(s) with SSH using key-based (i.e. password-less) authentication. You'll need this working before you can use Capistrano.

Provisioning

Likewise, your server(s) will likely need supporting software installed before you can perform a deployment. Capistrano itself has no requirements other than SSH, but your application probably needs database software, a web server like Apache or Nginx, and a language runtime like Java, Ruby, or PHP. These server provisioning steps are not done by Capistrano.

sudo, etc.

Capistrano is designed to deploy using a single, non-privileged SSH user, using a non-interactive SSH session. If your deployment requires sudo, interactive prompts, authenticating as one user but running commands as another, you can probably accomplish this with Capistrano, but it may be difficult. Your automated deployments will be much smoother if you can avoid such requirements.

Shells

Capistrano 3 expects a POSIX shell like Bash or Sh. Shells like tcsh, csh, and such may work, but probably will not.

Quick start

Requirements

  • Ruby version 2.0 or higher on your local machine (MRI or Rubinius)
  • A project that uses source control (Git, Mercurial, and Subversion support is built-in)
  • The SCM binaries (e.g. git, hg) needed to check out your project must be installed on the server(s) you are deploying to
  • Bundler, along with a Gemfile for your project, are recommended

Install the Capistrano gem

Add Capistrano to your project's Gemfile using require: false:

group :development do
  gem "capistrano", "~> 3.17", require: false
end

Then run Bundler to ensure Capistrano is downloaded and installed:

$ bundle install

"Capify" your project

Make sure your project doesn't already have a "Capfile" or "capfile" present. Then run:

$ bundle exec cap install

This creates all the necessary configuration files and directory structure for a Capistrano-enabled project with two stages, staging and production:

├── Capfile
├── config
│   ├── deploy
│   │   ├── production.rb
│   │   └── staging.rb
│   └── deploy.rb
└── lib
    └── capistrano
            └── tasks

To customize the stages that are created, use:

$ bundle exec cap install STAGES=local,sandbox,qa,production

Note that the files that Capistrano creates are simply templates to get you started. Make sure to edit the deploy.rb and stage files so that they contain values appropriate for your project and your target servers.

Command-line usage

# list all available tasks
$ bundle exec cap -T

# deploy to the staging environment
$ bundle exec cap staging deploy

# deploy to the production environment
$ bundle exec cap production deploy

# simulate deploying to the production environment
# does not actually do anything
$ bundle exec cap production deploy --dry-run

# list task dependencies
$ bundle exec cap production deploy --prereqs

# trace through task invocations
$ bundle exec cap production deploy --trace

# lists all config variable before deployment tasks
$ bundle exec cap production deploy --print-config-variables

Finding help and documentation

Capistrano is a large project encompassing multiple GitHub repositories and a community of plugins, and it can be overwhelming when you are just getting started. Here are resources that can help:

Related GitHub repositories:

  • capistrano/sshkit provides the SSH behavior that underlies Capistrano (when you use execute in a Capistrano task, you are using SSHKit)
  • capistrano/rails is a very popular gem that adds Ruby on Rails deployment tasks
  • mattbrictson/airbrussh provides Capistrano's default log formatting

GitHub issues are for bug reports and feature requests. Please refer to the CONTRIBUTING document for guidelines on submitting GitHub issues.

If you think you may have discovered a security vulnerability in Capistrano, do not open a GitHub issue. Instead, please send a report to [email protected].

How to contribute

Contributions to Capistrano, in the form of code, documentation or idea, are gladly accepted. Read the DEVELOPMENT document to learn how to hack on Capistrano's code, run the tests, and contribute your first pull request.

License

MIT License (MIT)

Copyright (c) 2012-2020 Tom Clements, Lee Hambley

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

bundler's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bundler's Issues

Ignoring bundle_dir setting?

i vendor gems in /current/vendor, but cap is trying to put them in /shared/bundle

Using:

gem 'capistrano-bundler', github: 'capistrano/bundler', ref: 'c6443d5'

Setting deploy.rb on line 1:

set :bundle_dir, -> { release_path.join('vendor') }

Seeing:

DEBUG [094e8d11] Command: cd /myapp/releases/20130907121236 && /usr/bin/env bundle \
  --gemfile /myapp/releases/20130907121236/Gemfile \
  --path /myapp/shared/bundle \
  --deployment --quiet --binstubs /myapp/shared/bin \
  --without development test

Capistrano symlink and default install path not in sync..

The command it runs to install the gems is:

cd /releases/20141003182225 && ~/.rvm/bin/rvm default do bundle install --binstubs /shared/bin --path /shared/bundle --without development test travis --deployment --quiet

However, the symlink created with linked_dirs is:

/shared/vendor/bundle/

This is what linked_dirs is set to:

set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets tmp/files vendor/bundle public/system}

Installed bins are not refreshed.

The bins that are places in shared/bin are not refreshed per-deploy.

As we, at our site, only keep 5 previous releases this means that after the fifth consecutive release the specified Gemfile is gone, when using the supplied defaults.

This is what my unicorn_rails file looks like:

#!/usr/bin/env ruby
#
# This file was generated by Bundler.
#
# The application 'unicorn_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/20131211121115/Gemfile",
  Pathname.new(__FILE__).realpath)

require 'rubygems'
require 'bundler/setup'

load Gem.bin_path('unicorn', 'unicorn_rails')

The 20131211121115 directory has been (long) reaped by Capistrano in order to keep things clean.

I see 3 solutions:

  • Rewrite files in shared/bin to point to ../../../current/Gemfile (rewriting files is a bad idea)
  • Remove the (appropriate) files in shared/bin before each bundle:install (removing all files might have unwanted side effects, so you need some sort of manifest)
  • Pack the files in release_path.join('bin') by default

Is there any speaking against the last option?

Defaults are not loaded

I'm using:

require 'capistrano/rails'
capistrano (3.0.1)
capistrano-bundler (1.1.0)
capistrano-rails (1.1.0)

For unknown reason the defaults are not loaded:

namespace :load do
  task :defaults do
    set :bundle_gemfile, -> { release_path.join('Gemfile') }
    set :bundle_dir, -> { shared_path.join('bundle') }
    set :bundle_flags, '--deployment --quiet'
    set :bundle_without, %w{development test}.join(' ')
    set :bundle_binstubs, -> { shared_path.join('bin') }
    set :bundle_roles, :all
    set :bundle_bins, %w{gem rake ruby}
  end
end

I understand this not much info. So can you please point me where to dig?

Automatically install correct bundler version – is this a desirable feature?

The bundler team advocates using the latest release of bundler to avoid bugs in older versions, and has even gone so far as adding a BUNDLED WITH entry to the Gemfile.lock. The idea is that the version of bundler you use in development should match the version of bundler you use in production.

I propose that capistrano-bundler should help do this.

Basically, just before bundle:install, we should:

  1. Parse the Gemfile.lock to check the BUNDLED WITH version
  2. If it specifies a newer version of bundler, use gem install bundler to install it

This would ensure that cap deploy would keep your server up to date with the version of bundler that your app requires.

Does this sound like a useful feature? I will contribute a PR if there is interest.

Shouldn't a .bundler be created?

I did a cap env deploy and I see this line:

DEBUG [799ade48] Command: cd /data/app/releases/20140313191241 && /usr/bin/env bundle install --binstubs /data/app/shared/bin --gemfile /data/app/current/Gemfile --path /data/app/shared/bundle --without development test --deployment --quiet

I'm using capistrano unicorn and it runs this line:

DEBUG [dfe649ed] Command: cd /data/app/current/ && ( RAILS_ENV=production BUNDLE_GEMFILE=/data/app/current/Gemfile /usr/bin/env bundle exec unicorn -c /data/app/current/config/unicorn.rb -E production -D  )

And I get this:

DEBUG [dfe649ed]    bundler: command not found: unicorn
DEBUG [dfe649ed]    Install missing gem executables with `bundle install`

Shouldn't a .bundle be created somewhere?

Please help, thanks in advance.

Explain that .bundle should be added to linked_dirs

As explained in #95, the bundle check behavior used by this gem depends on .bundle/config from previous deployments. If this directory is not linked, bundle check will be ineffective and a slower bundle install will be used. This unnecessarily slows down deployments.

We should add this explanation to the README.

bundle exec isn't used for rake tasks

Using only the official capistrano (3), capistrano/bundler and capistrano/rails gems, rake tasks doesn't get executed with bundle exec. This becomes a problem with for example the deploy:assets:precompile task of capistrano/rails where rake gets executed outside of the bundle.

What I'm left wanting is the equivalent of this from bundler/capistrano in Capistrano 2: set :rake, lambda { "#{fetch(:bundle_cmd, "bundle")} exec rake" }.

bash: bundle: command not found

I am not really sure this a bug or a misconfiguration,
here is the command that didn't find bundler:
cd /home/wideeyes/similifyserver/releases/20130901191319 && bundle --gemfile /home/wideeyes/similifyserver/releases/20130901191319/Gemfile --path /home/wideeyes/similifyserver/shared/bundle --deployment --quiet --binstubs /home/wideeyes/similifyserver/shared/bin --without development test

Manually going into that dir and doing a which bundler gives me:
/home/wideeyes/.rvm/gems/ruby-2.0.0-p247@similifyserver/bin/bundle

Specify bundler executable location

I'm using a shared hosting environment that has 3 version of Ruby installed: 2.0, 2.22, and 2.33. I'm using 2.33 in my application. Unfortunately, they don't use rvm or rbenv to manage this.

As a result, I need to use specific bundler settings to get my Gems installed in their environment:

app_dir$ /usr/local/bin/ruby233 /usr/local/bin/bundle233 --path vendor/bundle

When run manually (via ssh), this installs the Gems in the app_dir/shared/vendor/bundle directory.

How would I represent /usr/local/bin/ruby233 /usr/local/bin/bundle233 --path vendor/bundle in capistrano/bundler?

Make capistrano-bundler install bundler if it is missing

We use capistrano-rvm during deployment, and it will occasionally install a new Ruby version for running the application. In this case Bundler is not installed, and capistrano-bundler cannot do its magic.

Can you add a simple

gem query -i -n bundler || gem install bundler

to capistrano-bundler to make sure bundler is actually installed before running bundle install ?

Using current_path vs release_path

related: #31, tablexi/capistrano3-unicorn#10

i'm not sure if this is a problem, but i noticed, that when using capistrano/rbenv, capistrano/bundler and capistrano3-unicorn and trying to do zero downtime restarts, that unicorn's BUNDLE_GEMFILE path points to the old release (please see the related capistrano3-unicorn issue for my setup) when unicorn was actually started, and does not get refreshed upon deploys (when unicorn is gracefully restarted).

edit: same when using capistrano/rbenv master

Initial deploy uses current_path instead of release_path

When deploying the first time, the default bundle_gemfile path is using the current_path (which is not yet set), and not release_path. Therefore after it works as expected.

Initial deploy

** Invoke deploy:updated (first_time)
** Invoke bundler:install (first_time)
** Execute bundler:install
DEBUG [5ca3b8b7] Running /usr/bin/env if test ! -d /var/rails/app/releases/20140114175348; then echo "Directory does not exist '/var/rails/app/releases/20140114175348'" 1>&2; false; fi on 10.0.0.1
DEBUG [5ca3b8b7] Command: if test ! -d /var/rails/app/releases/20140114175348; then echo "Directory does not exist '/var/rails/app/releases/20140114175348'" 1>&2; false; fi
DEBUG [5ca3b8b7] Finished in 0.006 seconds with exit status 0 (successful).
 INFO [5f9d6754] Running /usr/bin/env bundle --gemfile /var/rails/app/current/Gemfile --path /var/rails/app/shared/bundle --deployment --quiet --binstubs /var/rails/app/shared/bin --without development test on 10.0.0.1
DEBUG [5f9d6754] Command: cd /var/rails/app/releases/20140114175348 && ( PATH=/opt/rbenv/bin:/opt/rbenv/shims:$PATH /usr/bin/env bundle --gemfile /var/rails/app/current/Gemfile --path /var/rails/app/shared/bundle --deployment --quiet --binstubs /var/rails/app/shared/bin --without development test )
DEBUG [5f9d6754]    The --deployment flag requires a Gemfile.lock. Please make sure you have checked
DEBUG [5f9d6754]    your Gemfile.lock into version control before deploying.

Every deploy therefore after

** Invoke deploy:updated (first_time)
** Invoke bundler:install (first_time)
** Execute bundler:install
DEBUG [8db7cc69] Running /usr/bin/env if test ! -d /var/rails/app/releases/20140114180714; then echo "Directory does not exist '/var/rails/app/releases/20140114180714'" 1>&2; false; fi on 10.0.0.1
DEBUG [8db7cc69] Command: if test ! -d /var/rails/app/releases/20140114180714; then echo "Directory does not exist '/var/rails/app/releases/20140114180714'" 1>&2; false; fi
DEBUG [8db7cc69] Finished in 0.004 seconds with exit status 0 (successful).
 INFO [4ab6547b] Running /usr/bin/env bundle --gemfile /var/rails/app/releases/20140114180714/Gemfile --path /var/rails/app/shared/bundle --deployment --quiet --binstubs /var/rails/app/shared/bin --without development test on 10.0.0.1
DEBUG [4ab6547b] Command: cd /var/rails/app/releases/20140114180714 && ( PATH=/opt/rbenv/bin:/opt/rbenv/shims:$PATH /usr/bin/env bundle --gemfile /var/rails/app/releases/20140114180714/Gemfile --path /var/rails/app/shared/bundle --deployment --quiet --binstubs /var/rails/app/shared/bin --without development test )
 INFO [4ab6547b] Finished in 97.585 seconds with exit status 0 (successful).

bundle command not found

Hi,

I am using capistrano for deploy my project and I run with this issue which is weird because I can run the command in the server without issues. The issue said that the command doesn't exist, but i can run "bundle install" in the server.

command:

cd /home/deployer/apps/perseus/releases/20150407001017 && ( PATH=/usr/bin:$PATH /usr/bin/env bundle install --path /home/deployer/apps/perseus/shared/bundle --without development test --deployment --quiet )

error log:

INFO [a06236ae] Running /usr/bin/env bundle install --path /home/deployer/apps/perseus/shared/bundle --without development test --deployment --quiet as deployer@server
DEBUG [a06236ae] Command: cd /home/deployer/apps/perseus/releases/20150407001017 && ( PATH=/usr/bin:$PATH /usr/bin/env bundle install --path /home/deployer/apps/perseus/shared/bundle --without development test --deployment --quiet )
DEBUG [a06236ae]    /usr/bin/env: 
DEBUG [a06236ae]    bundle
DEBUG [a06236ae]    : No such file or directory
DEBUG [a06236ae]    

I installed the bundle command using gem install bundle

Please tag version 1.1.3

The tag for version 1.1.3 is missing.

$ git tag
1.0.0
v1.1.0
v1.1.1
v1.1.2
v1.1.4

Could you please add it?

Resolve bundle bin location via SSHKit's command_map

In the :map_bins task, should we be resolving the path to bundle using SSHKit.config.command_map.prefix[:bundle]? For example, I think that:

SSHKit.config.command_map.prefix[command.to_sym].push("bundle exec")

should become:

bundle_exec = "#{SSHKit.config.command_map.prefix[command.to_sym] || :bundle} exec"
SSHKit.config.command_map.prefix[command.to_sym].push(bundle_exec)

I'm having trouble trying to get capistrano/bundler's bundle command to resolve to the bin set by capistrano/rbenv.

Cheers!

Question: How to execute a binary in the bundle in after:deploy stage

Hi!

I would like to execute a binary located in the bundle (/var/www/app/shared/bundle/ruby/2.3.0/bin) after finished a deploy. I am actually using a task after the deploy

after  :deploy, 'doc:generate_doc'

namespace :doc do
  desc 'Refresh API doc'
  task :generate_doc do
    on roles(:all) do
      execute "cd #{release_path}; sdoc app/controllers/api"
    end
  end
end

But this implies that the sdoc gem needs to be installed in the global gemset, instead of the bundle gemset, how to exec sdoc using the /var/www/app/shared/bundle/ruby/2.3.0/bin/sdoc binary?.

Sorry for my ignorance and thanks for the help.

Could not find arel-4.0.1 in any of the sources (Bundler::GemNotFound)

I'm using this gem along w/ capistrano, capistrano-rvm, and capistrano/rails. When I run cap production deploy I get a failure:

DEBUG [2e782c90] Command: cd /var/www/skateboxes/releases/20131024030833 && ( RVM_BIN_PATH=~/.rvm/bin RAILS_ENV=production /usr/local/rvm/bin/skateboxes_rake assets:precompile )
DEBUG [2e782c90]    /usr/local/rvm/gems/ruby-2.0.0-p247@global/gems/bundler-1.3.5/lib/bundler/spec_set.rb:92:in `block in materialize': Could not find arel-4.0.1 in any of the sources (Bundler::GemNotFound)

It doesn't appear that bundler is using 2.0@skateboxes but rather 2.0@global despite having set rvm_ruby_version

set :rvm_ruby_version, "2.0@skateboxes"

I'm not sure if the fault lies w/ capistrano/bundler, capistrano/rvm, or elsewhere. Any ideas?

bundler:install should hook into deploy:published

Hi,

maybe I am missing something, but I believe that the order of invocation of bundler:install is wrong. bundler:install fails, because the current symlink does not (yet) exist when bundler:install executes.

Currently, in framework.rake, deploy:updating gets invoked before deploy:publishing.

desc 'Deploy a new release.'
task :deploy do
  %w{ starting started
      updating updated
      publishing published
      finishing finished }.each do |task|
    invoke "deploy:#{task}"
  end
end

The deploy:publishing task is responsible for creating/updating the current symlink. bundler:install relies on the current symlink. However, capistrano-bundler, hooks into deploy:update, as can be seen in bundler.cap:

before 'deploy:updated', 'bundler:install'

And now to the point: since bundler:install hooks into deploy:updating, the current symlink does not exist when bundler:install executes.

From what I can see, bundler:install should hook into deploy:published, like so:

before `deploy:published`, `bundler:install`

Because at that point, the current symlink exists.

What do you think?

bundle install doesn't seem to run

I'm trying to add capistrano/bundler to my app. I have added the gem and the require to the Capfile. however, bundle install never seems to run during a deploy?

It clearly ran at some point, as there are some gems in the bundle, and bundle exec calls throughout the deploy work.

Empty :bundle_dir conflicts with --system

Empty :bundle_dir still creates a --path argument to bundle.

Gemfile

  # Easy multi-staging deployment
  gem 'capistrano', '~> 3.0.1'
    gem 'capistrano-bundler'
    gem 'capistrano-rails'
    gem 'capistrano-rvm', '~> 0.0.3'

production.rb

set :rvm_type, :auto
set :rvm_ruby_version, '1.9.3-p448@cmf'

# RVM <--> bundle integration
set :bundle_dir, ''
set :bundle_flags, '--system --quiet'

cap production deploy (log)

DEBUG [f6e5442b] Command: cd /srv/www/cmf/releases/20131114134217 && /usr/local/rvm/bin/rvm 1.9.3-p448@cmf do bundle --gemfile /srv/www/cmf/releases/20131114134217/Gemfile --path  --system --quiet --binstubs /srv/www/cmf/shared/bin --without development test
DEBUG [f6e5442b]    You have specified both a path to install your gems to, 
DEBUG [f6e5442b]    as well as --system. Please choose.

Expected bundle command

bundle --gemfile /srv/www/cmf/releases/20131114134217/Gemfile --system --quiet --binstubs /srv/www/cmf/shared/bin --without development test

Actual bundle command

bundle --gemfile /srv/www/cmf/releases/20131114134217/Gemfile --path  --system --quiet --binstubs /srv/www/cmf/shared/bin --without development test

No need to install asset group on DB hosts

I think I am correct in saying we don't need to install gems from the Gemfile's asset group on the DB hosts.

Would there be any problem with the following fix?

namespace :load do
  task :defaults do
    set :bundle_without, ->(host) { "development test #{:assets if (fetch(:asset_roles, []) & host.roles_array).empty?}" }
  end
end

Run `Bundler.setup` when `capistrano/bundler` is required in app Capfile

Currently when you run cap Capistrano will use system load path instead of those defined in your app Gemfile. If you use your Gemfile to select alternate versions of some Capistrano gems, say gem "capistrano-rails", path: "../capistrano-rails" you have to run bundle exec cap for your changes to have effect.

An alternative is to add these lines to your Capfile:

require "bundler"
Bundler.setup

I think one could expect require "capistrano/bundler" to make the cap command fully bundler-aware. Meaning: tasks should be loaded from sources specified in Gemfile. That's how rails and rake commands behave in Rails projects.

Since we don't want to reference bundler in the default Capfile template, I think those two lines should be ran in lib/capistrano/rails.rb. That way when user explicitly requires bundler support with his Capfile, the load path is automatically set for him.

Can't get `bundle install` step to print anything

Event if I replace the --quiet flag for --verbose, one is unable to see any output from bundle install, which can be useful for getting an idea of the installation progress (staring 2 minutes at a still screen isn't very cool).

Screenshot:

screen shot 2015-10-26 at 20 40 53

Generating binstubs on deployment seems destined to break when old releases are removed

We're seeing an issue that seems superficially similar to #22 -- in a nutshell, binstubs are generated with paths to the Gemfile for a specific Capistrano release, and once that release is reaped by Capistrano, the binstubs used by the current version of the application break.

Background

The relevant part of our Capistrano configuration:

set :bundle_binstubs, -> { shared_path.join('binstubs') }
set :bundle_gemfile, -> { release_path.join('Gemfile') }
set :bundle_flags, '--deployment'
append :linked_dirs, '.bundle'

On our servers, we have /app/shared/binstubs in the PATH, and this is the bundler config, symlinked into every release:

$ cat /app/shared/.bundle/config
---
BUNDLE_PATH: "/app/shared/bundle"
BUNDLE_DISABLE_SHARED_GEMS: "true"
BUNDLE_FROZEN: "true"
BUNDLE_BIN: "/app/binstubs"
BUNDLE_JOBS: "4"
BUNDLE_WITHOUT: "development:test"

We're using Bundler 1.17.3:

$ bundle -v
Bundler version 1.17.3

And these Capistrano versions:

$ bundle list | grep capistrano
  * capistrano (3.11.0)
  * capistrano-bundler (1.3.0)
  * capistrano-faster-assets (1.1.0)
  * capistrano-maintenance (1.2.0)
  * capistrano-rails (1.4.0)

(I realise capistrano-bundler is not at the latest release, but the changes between 1.3.0 and 1.5.0 don't seem like they would impact this at all)

The issue

When deploying, bundle install works as you'd expect, installing the gems and binstubs into the shared directory:

bundle install --gemfile /app/releases/20190425155236/Gemfile --path /app/shared/bundle --binstubs /app/shared/binstubs --jobs 4 --without development test --deployment

However, within the generated binstubs, they all include a reference to the specific release directory:

$ grep GEMFILE binstubs/rake
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../releases/20190425155236/Gemfile",

Since binstubs aren't automatically regenerated on every deploy, but we only retain a certain number of releases, so at some point, the release referenced in the binstubs is removed, and they all break.

Our current workaround is to explicitly set BUNDLE_GEMFILE to /app/current/Gemfile, but this causes other unrelated issues (e.g. new gems aren't visible to the application until after the symlink has been changed).

I think we're largely following the default approach for capistrano-bundler as described in the README, and I think this is the default behaviour of bundler.

#45 suggests that the right way to avoid this is by checking binstubs into the application repository. That would certainly work, since by definition the relative path of each binstubs and the Gemfile won't change.

So I suppose my question is: shouldn't everyone who is generating binstubs on deployment be seeing this issue? Maybe nobody else is either reaping old releases or generating binstubs? If this is the default behaviour, I wonder if the implementation should actually explicitly not support generating binstubs, and the documentation should propose the approach from #45?

Hopefully that's all clear; let me know if there's any other details that I can provide which might help

How to use bunder from other version of Ruby?

I tried to deploy to my Ubuntu 12.04 LTS which has ruby 1.8 installed as a default. However, the bundler seems to be fail reading my Gemfile which has 1.9 style code:

gem 'activeadmin', github: 'gregbell/active_admin'

Is there a way to specify the version of bundler that will execute the Gemfile? I want to use the one from my RVM rubies.

Many thanks!

Option to disable "--deployment" flag in bundle command

As I develop on Windows I cannot reuse the Gemfile.lock because the gemfiles are not the same on my deployment system (Linux).
The --deployment flag requires exactly that.
So I need an option to remove the --deployment from the command

~/.rvm/bin/app_bundle --gemfile /usr/share/nginx/www/staging/app/releases/20131017081800/Gemfile --path /usr/share/nginx/www/staging/app/shared/bundle --deployment --quiet --binstubs /usr/share/nginx/www/staging/app/shared/bin --without [:test, :development]

Error (if Gemfile.lock is not in scm)

                Cannot write a changed lockfile while frozen.
INFO [22519c68] Finished in 11.163 seconds command successful.

Side note: The command is actually NOT successful...

cannot run `bundler:install` without 'current' directory

I need to install capistrano/bundler so that my bundler-dependent commands can work properly, but since I haven't yet had a successful deploy (given the above) I get this error:

SSHKit::Runner::ExecuteError: Exception while executing as [email protected]: if  test ! -d /home/rails/project-name/current; then echo "Directory does not exist '/home/rails/project-name/current'" 1>&2; false; fi exit status: 1

Gem released ?

Hello,

I'm trying to migrate our deploy to capistrano 3, but the gem capistrano-bundler doesn't seams to be release ?

Thanks !

Don't generate binstubs by default when using Rails 4?

When using Rails 4, the default options result in this error being raised when running a command from bin in a deployed environment:

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.

Here's how to upgrade:

  bundle config --delete bin    # Turn off Bundler's stub generator
  rake rails:update:bin         # Use the new Rails 4 executables
  git add bin                   # Add bin/ to source control

You may need to remove bin/ from your .gitignore as well.

When you install a gem whose executable you want to use in your app,
generate it and add it to source control:

  bundle binstubs some-gem-name
  git add bin/new-executable

I have in fact checked in a bin with executables generated by Rails, but they are not used, because by default bin is symlinked to shared/bin, containing executables with bundler-generated executables. Of course it is trivial to configure bundler such that this doesn't happen, but since everyone using Rails 4 needs to do that, it would be better to just do 'the right thing' out of the box.

Do you agree and are you interested in a pull request for this?

Edit:
Also see rails/rails#8974 and specifically rails/rails#8974 (comment)

bundle install mysql2 with custom flags

A newbie question.
How can I specify custom flags for the bundle install command of mysql2 gem?
I need to pass --with-mysqlclientlib=/my/custom/lib/location.so

I'm getting this error while trying a deploy:

DEBUG[e6d2cffe]     An error occurred while installing mysql2 (0.3.16), and Bundler cannot continue.
DEBUG[e6d2cffe]     Make sure that `gem install mysql2 -v '0.3.16'` succeeds before bundling.

The bundler install time is too long every time.

When I run the `cap production deploy' and I will get stuck in this operation every time,

&& ~/.rvm/bin/rvm default do bundle install --binstubs /var/www/test-project/shared/bin --path /var/www/test-project/shared/bundle --without development test --deployment --quiet

Why?

Loading default values

capistrano_bundler doesn't seem to load defaults when creating a fresh project with caphub. I don't expect it to be any different when using just plain capistrano.

Does it rely on someone calling the load:defaults task?

Dependencies are fetched on every deploy

I am trying to understand why dependencies are installed on every deploy.

here is the relevant output:

7] Command: cd /home/deploy/app/test/releases/20131111101141 && /usr/bin/env bundle --gemfile /home/deploy/app/test/releases/20131111101141/Gemfile --path   --binstubs  --without development test

I do have this in the config for the test deployment

set :deploy_to, "/home/deploy/app/test"

The Gemfile exists, so why the dependencies are installed on every deploy?

Feature: rate limit for bundle:install task when using lots of servers

As mentioned by @gondalez in #93, the bundle:install task uses the default parallel SSHKit execution mode. This means if you have 100 servers you will potentially get 100 instances of bundle:install running concurrently. If a Gemfile uses a private gem server, this can overwhelm that server or run up against rate limits.

It would be nice to be able to configure the maximum parallelization of the bundle:install task.

However, I'd rather not introduce a bundle:install-specific configuration variable, because this sets a precedent for setting these sorts of variables for all kinds of Capistrano tasks (e.g. git:clone/update) that can run up against rate limits on shared resources. Ideally we could come up with a more generalizable solution.

Gemfile not found

Gemfile not found (Bundler::GemfileNotFound)

group :development do
gem 'capistrano', '> 3.10', require: false
gem 'capistrano-rails', '
> 1.3', require: false
gem 'capistrano-rvm', require: false
gem 'capistrano-bundler', '~> 1.3', require: false
gem 'capistrano3-puma', require: false
end

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.