Bundle problems when deploying from Windows to Ubuntu using Capistrano

I’m in the final stages of upgrading my Rails 2.3 app to Rails 3.2. In this stage, I’ve also upgraded from Ruby 1.8.7 to 1.9.3. That’s meant a new version of the capistrano gem, and the inclusion of require ‘bundler/capistrano’ in deploy.rb.

cap deploy currently executes fine until it gets to a step where it’s trying to run bundle install on the production (ubuntu 12.04) server. There it gives the error message “Cannot write a changed lockfile while frozen.”

Googling this error leads to a few SO threads and some issue reports for bundler that point to a problem with Gemfile.lock being created on a Windows machine (with mingw-platform gems) and then being deployed on a unix machine. That would appear to apply to me. Some workarounds using the :platform option are mentioned, but they don’t seem to solve my issue. I have the latest version of bundler installed on both machines (1.3.5) and my Gemfile simply says gem ‘bundler’ with no version number specified.

Prior to this point, I haven’t had a capistrano recipe in place to run bundle install. Instead, I’ve simply manually installed new gems as needed on the production server when deploy error messages mentioned missing gems. Now that capistrano is trying to run bundle install, the problems have arisen.

Any help would be greatly appreciated. I basically can’t deploy any changes to my app as things stand.

Thanks very much,

Dean Richardson
Molex.com and Genlighten.com

Hi Dean,

This is a tricky problem. I’ve never used capistrano before, but I have had similar difficulties in the past when trying to deploy to a different OS. I believe that capistrano uses the --deployment flag when bundling. See the docs. You need the gems for both OS’s to be listed in the Gemfile.lock, but you don’t actually want them both required in all environments.

There is a long-standing bundler issue about this very thing. There’s some sample code in the bundler wiki that will put everything into Gemfile.lock but will only require those gems on the appropriate platform. This may do the trick for you, or it may not. If the gem in question is unable to install (or no-op) on all platforms then bundle install will fail. Either way, it’s not what I would call an optimal solution.

Which gems are giving you trouble? Do you absolutely have to have them in your production environment? Could you isolate them to your dev, test, or assets groups (precompiling assets and not requiring that group at runtime in production)? If so, I think you could use bundle package alsong with bundle install --deployment --without development test assets to successfully bundle in production.

Failing all of this, there’s always the option of using Vagrant to keep your local development environment in step with production. I know that several people here are happy Vagrant users.

Hope this helps,
Derek

1 Like

Derek:

This looks like hugely helpful advice. :slight_smile: I’ll work through the links you provided and see if I can live without the platform-specific gems. One thing I haven’t tried yet is seeing if cloning the repository on my mac and trying to deploy from there might solve the problem. I’ll see if that makes a difference and update the post.

Thanks!

Here is how I fixed my issue referring to the same error message:

“Cannot write a changed lockfile while frozen.”

Don’t know if it is the right way. It worked for me, so I’d like to share it.

I deploy from Win7 to Linux 2.6.32-37-server using Capistrano 2.15.5, Rails 3.2.14 and Bundler 1.3.4.

On my Win7 development machine:

  1. I deleted my Gemfile.lock and ran “bundle install” to have a clean new Gemfile.lock
  2. In Gemfile.lock platform block I added “ruby
  3. In Gemfile.lock spec block I added an Unix compatible version of all Windows specific gems
  4. bundle install

  5. git commit –am “adopted Gemfile.lock to Win and Unix by …”

  6. git push

  7. cap deploy

Relevant parts of my Gemfile.lock to give you an idea what it should look like:

GEM
  remote: https://rubygems.org/
  specs:
    bcrypt-ruby (3.1.2)
    bcrypt-ruby (3.1.2-x86-mingw32)
    […]
    mysql2 (0.3.11-x86-mingw32)
    mysql2 (0.3.13)
	
PLATFORMS
  ruby
  x86-mingw32

DEPENDENCIES
  mysql2
  rails (= 3.2.14) 
  […]

My Capistrano command and error message (before changes in Gemfile.lock):

  * executing "cd /home/user1234567/rails2/releases/20130830133630 && bundle install --gemfile /home/user1234567/rails2/releases/20130830133630/Gemfile --path /home/user1234567/rails2/shared/bundle --deployment --quiet --without development test"
    servers: ["ny.railshoster.de"]
    [ny.railshoster.de] executing command
 ** [out :: ny.railshoster.de] Cannot write a changed lockfile while frozen.
    command finished in 8994ms