Bundler 2.2.3+ and deployment of Ruby apps
Tags: bundler, deployment, rails
Published: 2021-04-20 13:51:30

---
title: Bundler 2.2.3+ and deployment of Ruby apps
published: true
date: 2021-04-18 14:06:49 UTC
tags: bundler,deployment,rails
canonical_url: https://prathamesh.tech/2021/04/18/bundler-2-2-3-and-deployment-of-ruby-apps/
---

While deploying a new Rails 6.1.3.1 application built with Bundler 2.2.16 on Heroku, I ran into this error in Heroku build log.

```sh
-----> Ruby app detected
-----> Installing bundler 2.2.15
-----> Removing BUNDLED WITH version in the Gemfile.lock
-----> Compiling Ruby/Rails
-----> Using Ruby version: ruby-3.0.1
-----> Installing dependencies using bundler 2.2.15
       Running: BUNDLE_WITHOUT='development:test' BUNDLE_PATH=vendor/bundle BUNDLE_BIN=vendor/bundle/bin BUNDLE_DEPLOYMENT=1 bundle install -j4
       Your bundle only supports platforms ["x86_64-darwin-20"] but your local platform
       is x86_64-linux. Add the current platform to the lockfile with `bundle lock
       --add-platform x86_64-linux` and try again.
       Bundler Output: Your bundle only supports platforms ["x86_64-darwin-20"] but your local platform
       is x86_64-linux. Add the current platform to the lockfile with `bundle lock
       --add-platform x86_64-linux` and try again.
 !
 ! Failed to install gems via Bundler.
 !
 ! Push rejected, failed to compile Ruby app.
 ! Push failed
```

> If you are using Bundler 1.x you will not run into this error. It only happens with Bundler 2.2.3 and above. My bundler version is 2.2.16.

The app was built on Mac OS X. The `Gemfile.lock ` contained following line.

```ruby
PLATFORMS
  x86_64-darwin-20
```

As per the warning it seems that my `Gemfile` was generated for Mac OS X but I am deploying to Linux and it was raising a flag. Kudos to Heroku buildpack to raise a user friendly error message!

A lot of gems such as `nokogiri` ship platform specific releases. In previous versions of Bundler, the approach for detecting the platform specific version was error-prone as per [this comment](https://github.com/rubygems/rubygems/issues/4269#issuecomment-758564690). To mitigate such errors, bundler now sets up `Gemfile.lock` for the platform on which it was generated.

When deploying to Heroku, the Heroku Ruby buildpack runs bundle install in [deployment mode](https://bundler.io/man/bundle-install.1.html#DEPLOYMENT-MODE). It expects that `Gemfile.lock` to be frozen and already compatible with the platform on which it is being run. In our case, the `Gemfile.lock` is not  compatible with the platform on which Heroku is deploying which is Linux and the platform on which it was generated which is Mac.

If we do not use the deployment mode, then bundler **will resolve the gems in real time with current platform** and this problem will not happen.

> Though you should not do this as dev-prod parity breaks down and in production, bundler may resolve to the gems which you have not tested in development or test mode.

To fix this, as the warning recommended, I added linux platform using following command.

```sh
bundle lock --add-platform x86_64-linux
```

This generated following diff in `Gemfile.lock`.

```sh
diff --git a/Gemfile.lock b/Gemfile.lock
index 9f4c3ad..ab20d37 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -102,6 +102,8 @@ GEM
     nio4r (2.5.7)
     nokogiri (1.11.3-x86_64-darwin)
       racc (~> 1.4)
+ nokogiri (1.11.3-x86_64-linux)
+ racc (~> 1.4)
     pg (1.2.3)
     public_suffix (4.0.6)
     puma (5.2.2)
@@ -198,6 +200,7 @@ GEM

 PLATFORMS
   x86_64-darwin-20
+ x86_64-linux
```

After pushing this change to Heroku, the deployment went through.

### Non-Heroku deployments

This is not specific to deployments on Heroku only. It can be seen in any other deployment platform as well where we are deploying to Linux and developing on Mac. The fix is same, add the platform to `Gemfile.lock` and redeploy.

* * *