Heroku deploy fails to load custom .bundle file - ruby-on-rails

I'm having a lot of trouble googling this issue, as bundler keeps coming up. However, my issue is with a c library that I've bundled using mkmf and the ruby c api. I've compiled my c code into a file (e.g. my_library.bundle) and I've required it inside a helper with require_relative "my_library" without a problem.
The problem arrises when I deploy to heroku and I get the error:
2019-08-14T19:09:15.452530+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.4/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require': cannot load such file -- /app/app/helpers/my_library (LoadError)
I can run ls and cat on my heroku app to verify the file is there and the contents match. When I run the application locally with RAILS_ENV=production, I also don't run into any issues. Also, running heroku local web runs fine on my machine.
Does this have something to do with my configs autoload_paths? My main issue is that I can't seem to debug this locally.
EDIT:
I've noticed that this problem arrises in dockerized instances, as well. It seems that something about containerization seems to be the problem. I've even tried creating a gem to contain the bundle following this guide, which works locally, but again has the same issue finding the file, but this time the path is relative to the gem, not my project. I'm still stumped on what is causing this issue.

According to the error that you posted, it seems that Docker doesn't point to the correct path cannot load such file -- /app/app/helpers/my_library. If that is correct, you should explicitly specify the working directory in your Dockerfile.
WORKDIR /path/to/project
After that, just rebuild the image.
Now, if this doesn't work, you can check autoload_paths in your project or customize bootsnap to avoid error in autoloading paths.

What you can do is have the entire my_library as a local gem and point your Gemfile to it.
Roughly, the outline would be as follows:
Place the entire code for my_library in directory within your app, say fixtures (which is at the same level as your Gemfile.)
app/
...
fixtures/
my_library/
ext/
...
lib/
...
my_library.gemspec
Rakefile
Gemfile
Point your Gemfile to the my_library gem:
gem 'my_library', path: 'fixtures/my_library'
Then simply update your Gemfile.lock by running
bundle update

As #jay-dorsey mentioned, the bundle did need to be compiled on the server that was deploying the application in order to be used. Both of the guides that I followed to create the gem had some misinformation.
The gem should contain only the source files, no compiled source files
The rakefile should reference ext.lib_dir = "lib/my_library" instead of the ext directory
The gemspec should add the rake-compiler development dependency BEFORE the other dependencies
The version files should NOT try to load the extension, as it's being used in the gemspec, which is called before the gem has a chance to be compiled by rake / bundler
.bundle files can't be read on linux machines

Related

Webpacker binstubs not installing correctly

I have a perplexing issue here when trying to implement the Rails Webpacker gem into an existing application.
Unfortunately, I do not have much to offer in the way of debugging information, this is also an internal project, so I have limited options in terms of sharing the entire project source.
I am following the exact steps outlined here: https://github.com/rails/webpacker and have done it multiple times now, but during the bundle exec rails webpacker:install command (after running bundle), I see the message:
Skipped webpack and webpack-dev-server since they already exist.
If you want to overwrite skipped stubs, use --force.
This binstubs most-definitely do not exist in my bin/ directory. Either before or after the webpacker install.
I feel like I have tried everything at this point, and nothing seems to be working:
Reinstalling the gem (multiple versions, even via Git)
Manually creating the binstub from a different project (this "worked" until I tried to run the webpacker:install:react script).
Manually running Yarn, attempting to --force create the binstubs
Tried multiple different configuration tweaks in webpacker.yml
I am just out of ideas at this point. Anything else I should be checking, could try?
This is a fix that worked for me:
I copied these two files into the bin directory of my app and then bundle exec rails webpacker:check_binstubs stopped complaining.
As a side effect it made my app deployable on my Paas with the standard buildpack.

Bundler unable to find custom gem

I have a custom gem built as a .gem file that I am trying to reference from my Gemfile. I have placed the .gem file, along with the .gemspec, in the vendor/gems folder. My Gemfile has the following line:
gem 'umlgrader', '1.0.0', :path=>'vendor/gems'
When I run bundle install, it claims to have found the gem but it says it is "using" the gem, rather than "installing" it, even though the gem was not previously installed on my machine. When I try to run my app, I then get a NoMethodError when it tries to call any of the methods in the gem. Why isn't Bundler installing the gem?
I have gotten it to work by unpacking the gem in that directory and then editing the Gemfile as follows:
gem 'umlgrader', '1.0.0', :path=>'vendor/gems/umlgrader-1.0.0'
This solution is less than desirable. I would prefer to be able to install the gem using Bundler since I am trying to deploy the app to Heroku. I have already tried a lot of the solutions I have found online, but I am open to any suggestions.
EDIT:
Some of the other pages I have already gone through and tried:
Bundler: installing a specific .gem file
How to use Bundler with offline .gem file?
How do I specify local .gem files in my Gemfile?
I also noticed a lot of people suggest pointing to a Git repository containing the gem. I would rather not do this if I don't have to.
The Bundler documentation is somewhat cryptic on that topic, but that is the intended behaviour of Bundler. In order to use the path option you must unpack the gem at the desired location.
But that should be no problem for Heroku. After all, you are still using Bundler, even if the gem is already unpacked. It's just a step less in the gem installing process...
Without Docker
You need to clone the repository from github (or other source) to your custom folder. In example below the steps to reproduce how I use custom path to edit gems in a separeted folder:
In this case I use a custom_gems folder inside /bundle: mkdir /bundle/custom_gems.
cd /bundle/custom_gems.
git clone <gem-repository-source>. Is necessary to clone because if you copy from other folder in your computer probably some files are missed.
Set in your Gemfile: gem '<gem-name>', path: '/bundle/custom_gems/<gem-name>'.
Restart you application.
In docker-compose (or Docker)
With docker is little different, in this case I use a /gems folder inside my rails application folder: mkdir <my-app>/gems.
cd <my-app>/gems.
git clone <gem-repository-source>. Is necessary to clone because if you copy from other folder in your computer probably some files are missed.
Set in your Gemfile: gem '<gem-name>', path: '/bundle/custom_gems/<gem-name>'.
If you use docker-compose, you need to bind folders with volumes config, like below:
volumes:
- ./app/gems:/bundle/custom_gems
With this, your local folder (your machine) copy files inside ./app/gems to /bundle/custom_gems in Docker container.
Restart service.
If you NOT use docker-compose, you need add in Dockerfile some like:
ADD ./app/gems /bundle/custom_gems

Files added to my Ruby Project when using RBENV

After installing RBEnv and rebuilding my ROR project, I now seem to have added many, many files to my project. They are in /vendor/local, and appear to duplicate what you would normally find in /Library/Ruby/Gems.
My project will not run without these files present (I get the message Could not find rake-0.9.2.2 in any of the sources.
I had difficulties with my RBEnv installation. I have what I suspect are other issues (like I have to bundle exec rails instead of just running rails). I suspect that I have done something wrong and should not have these files in my project. What I'd like to know is:
1) Should these files be there?
2) How best to fix this (if this is not how it is supposed to work)?
3) If the best approach is to start over and reinstall rbenv, how do I clear it all out?
It is true that using RBENV will end up putting copies of your gems in the project's /vendor/local folder. This is to remove any dependencies on your base gem set. These files need not be part of your source repository, as long as your 'gemfile' and your '.rbenv-version' file are included in the repository.
Another price you pay for using rbenv is that you must bundle exec rails <command> and bundle exec rake <command> from here on in.

"could not locate gemfile" when doing bundle install on existing rails project

I've been given an existing rails project that I am trying to play around with. however, when I try to run bundle install or rake db:migrate, I run into problems so essentially, i can't really do anything with the code I've been given.
The biggest problem as I see it right now is the fact that it can't locate my gemfile when I bundle install?
How can I find my gemfile.. is there supposed to be one in the root folder of the application?
Is there another step I need to take to initialize an existing project that someone has just copied and pasted to me? Thanks!
Yes, you should have a Gemfile in the root directory of your app.
If you are developing in a Rails 2 app, you might want to check out the Bundler.io page about Rails 2.3:
http://bundler.io/v1.7/rails23.html
If you are using Rails 3+ you can take a learn from Bundler's page on Rails 3 use:
http://bundler.io/v1.7/rails3.html
If you just need to get started with a Gemfile, go to a different directory and generate a dummy app:
$ rails new temporary-app
Copy over the Gemfile to your directory. It will only have the default gems listed, but you may be able to "discover" your needed gems as you go. If you happen to have a Gemfile.lock file then you can see the gems that you need at the top of the dependency tree.

Bundler puts my gems in my project directory

I have a Rails 3rc app on Ruby 1.9.2 that works fine, but Bundler keeps making a folder named "bandsintown" (bandsintown is a gem I use) in my project directory. From what I can tell, the folder has all my gems in it. I'm pretty sure that this never happened before. Is it normal behavior?
I think this might be interfering with running tests. I get a "Command failed with status (1)" error and then it mentions the "bandsintown" folder a few times.
I find it odd that Bundler names the folder "bandsintown" even when I comment out that gem in the gemfile. There's a "ruby" folder in that one, and a "1.9.1" folder inside the "ruby" folder. I don't understand why it says 1.9.1 when I'm using 1.9.2. The 1.9.1 folder has a bin, bundler, cache, doc, gems and specification folder inside of it.
I made a testapp with all the same gems and did a bundle install. It doesn't make a new folder with all my gems in it.
Anyway, my app works fine, but I'd appreciate it if anyone could help me out here. If I left out any need-to-know information, let me know. Thanks.
You are probably running the following command: bundle install bandsintown. That command tells bundler to install gems into the bandsintown subdirectory of your application. In order to install gems, all you need to do is modify your Gemfile and run bundle install.
Bundler will remember the location that you last specified in the .bundle/config file. So, in order to "reset" bundler's memory. In your application's directory, run rm -r .bundle/config.
Then, after updating your Gemfile, simply run bundle install

Resources