Running both Bundler and NPM on Heroku - ruby

I have a Node.js app that uses Compass, a Ruby gem.
When I push to Heroku it will detect a Node.js app and run npm install. Now, it detects the Gemfile first which it a ruby project and no longer runs npm install. Is it possible to tell Heroku this is a Node.js app which requires the Gemfile for running bundle exec install compass?

You need to use a custom buildpack that supports both Ruby and Node. Take a look at third-party buildpacks and multi buildpacks.

Related

Minimal `Gemfile/Gemfile.lock` for Heroku environment

I’m updating the environment on Heroku and one of the buildpack we use is based on Ruby, which is no longer available by default in the new heroku-22 environment/stack (nor required by our PHP app).
From the docs:
[...] end users should add the Ruby buildpack prior to the buildpack in question (they will also need to ensure minimal Gemfile / Gemfile.lock files exist, so that the Ruby buildpack passes detection).
However I have no clue what those files should include as I have zero experience with Ruby. What would be a valid set of minimal Gemfiles to trigger Ruby installation on Heroku?
I suggest you don't use that buildpack at all. It's ancient, and third-party buildpacks are always a bit questionable, even if it's just because they often stop getting updated.
Here's what it claims to do:
This is a Heroku buildpack for vendoring just the mysql binary from the mysql-client-core deb package.
If you just need a mysql binary, you can use the apt buildpack to install it without worrying about Ruby or anything like that.
Add it as your first buildpack:
heroku buildpacks:add --index 1 heroku-community/apt
Create an Aptfile in the root directory of your project that lists the Ubuntu packages you wish to install, e.g.
mysql-client-core-8.0
Note that the buildpack does not do dependency resolution. If any packages you list have their own dependencies you may have to list them explicitly.
Commit, and redeploy.
You should see the Ubuntu packages you listed get installed before your main buildpack runs.
In any case, if you really want to make your application compatible with the Ruby buildpack you should be able to simply include an empty Gemfile in the root of your project:
The Heroku Ruby Support will be applied to applications only when the application has a Gemfile in the root directory. Even if an application has no gem dependencies it should include an empty Gemfile to document that your app has no gem dependencies.
A Gemfile.lock is not required.
Note that you'll need to manually add the buildpacks you require. I believe you'll want Ruby first, then the MySQL buildpack in your question, then whatever language your application is written in, which appears to be PHP:
heroku buildpacks:set heroku/php # Main buildpack; we insert others before it below
heroku buildpacks:add --index 1 heroku/ruby
heroku buildpacks:add --index 2 https://github.com/thoughtbot/heroku-buildpack-mysql.git
heroku buildpacks
# => Should print the buildpacks in the expected order
Edited
It turns out an empty Gemfile is not enough and a Gemfile.lock is actually required as well.
-----> Building on the Heroku-22 stack
-----> Using buildpacks:
1. heroku/python
2. heroku/ruby
3. https://github.com/thoughtbot/heroku-buildpack-mysql
4. heroku/php
5. heroku/nodejs
-----> Python app detected
-----> Using Python version specified in runtime.txt
-----> Stack has changed from heroku-20 to heroku-22, clearing cache
-----> No change in requirements detected, installing from cache
-----> Installing python-3.10.8
-----> Installing pip 22.2.2, setuptools 63.4.3 and wheel 0.37.1
-----> Installing SQLite3
-----> Installing requirements with pip
Collecting supervisor
Downloading supervisor-4.2.4-py2.py3-none-any.whl (749 kB)
Installing collected packages: supervisor
Successfully installed supervisor-4.2.4
-----> Ruby app detected
grep: /tmp/build_bebc9aa2/Gemfile.lock: No such file or directory
-----> Compiling Ruby/NoLockfile
!
! Gemfile.lock required. Please check it in.
!
! Push rejected, failed to compile Ruby app.
! Push failed
An empty Gemfile will trigger the Ruby installation, however the heroku/ruby package itself does require a lock file.
The buildpack will detect your app as Ruby if it has a Gemfile and Gemfile.lock files in the root directory.
After some trial and error I figure out the following files work:
# Gemfile
source 'https://rubygems.org'
# Gemfile.lock
GEM
remote: https://rubygems.org/
specs:
PLATFORMS
ruby
DEPENDENCIES
BUNDLED WITH
1.17.3

Installing a python package in a ruby application

I have a ruby sinatra app, and in one place I need to call out to a python script -- using ruby's system() -- and that python script depends on a python package.
Python3 is pre-installed on heroku (I checked by looking at one of my existing ruby apps), but my question is: How can I install both ruby gems for my main app and the python package needed for the python script?
Obviously installing the gems is just done using the Gemfile, and if I was writing a pure python application I would use requirements.txt, but I'm unclear how to proceed in this case where I need both.
You can use multiple buildpacks in your application. Briefly:
Add a requirements.txt file (or Pipfile and Pipfile.lock) to your root directory containing your Python dependencies
Set your Ruby buildpack explicitly:
heroku buildpacks:set heroku/ruby
Add the official Python buildpack before the Ruby buildpack (your main buildpack should be last):
heroku buildpacks:add --index 1 heroku/python
Now, redeploy your application.

How can I compile sass and bower install on heroku with a PHP app?

How can I compile sass and run bower install on heroku with a PHP (Laravel) app?
For Sass, everything seems to point to using Sass with rails. I have tried adding a script in my composer.json file and that doesnt work because Sass is not detected on heroku.
For bower, I tried adding a package.json, installing bower locally, and using that to run bower install but when I put a package.json file in my directory, it thinks my app is a node app so I cant get my Laravel app to even start.
https://github.com/dzuelke/heroku-multipack-nodejs-php-example is one way of doing that - the example runs both the Node and the PHP buildpack, so you'd have to add the Ruby buildpack to the beginning of the list as well and have a Gemfile that requires Sass.

Heroku is ignoring bundle configuration

I'm trying to install the gem 'taglib-ruby' on Heroku. This gem compiles as a native extension which requires a system dependency called taglib, so after compiling and uploading it through heroku vulcan, I achieved to compile the gem via command line on heroku bash:
bundle exec gem install taglib-ruby -- --with-opt-dir=/app/vendor/taglib
And in order to this parameter would be used by bundler later, I added it as a bundler configuration through the command:
bundle config build.taglib-ruby '--with-opt-dir=/app/vendor/taglib'
I've already verified this config was applied, inspecting the file /.bundle/config and looking for the line BUNDLE_BUILD__TAGLIB-RUBY.
However after pushing out my project to heroku and while it is executing the bundle install command, heroku complains that the above gem (taglib-ruby) cannot be installed due the taglib library isn't present, although it's what I was trying to solve with the option '--with-opt-dir=/app/vendor/taglib' mentioned above.
So it appears that Heroku is ignoring the bundler configuration.
What could be happening? Do you know another way the achieve the same intention (install a gem with custom build options) on Heroku?

Installing heroku client only, and not the other things

I am using RVM for my Ruby installations.
I recently encountered a problem installing the heroku toolbelt with it installing Ruby 1.9.1 on my actual system, which then rewriting environment variables, and breaking my ruby cli. I had to delete everything, reinstall RVM, reinstall gems, ect ect..
The point is, I wish to be able to use the heroku client, and possibly foreman, but I don't want the toolbelt trying to install git, and ruby 1.9.1 on my system.
I tried to do the gem install version, but it states that the gem is depreciated, and for me to install the toolbelt.
Any help will be greatly appreciated.
Thank you for all thoughtful answers.
Go to the Heroku CLI on github and download the tarball from the other setup. Extract the Tarball and move the resulting files under /usr/local/heroku. Add /usr/local/heroku/bin to your PATH. Ensure that Heroku gem is removed from any project gem files. Reload your terminal and the Heroku CLI should be working.
You can run which heroku from your project directory and you should get /usr/local/heroku/bin/heroku.
As it is self updating you should only need to do this once.
If you want Foreman just use the Gem version.
Git and Ruby will not be installed using this process.
Update: Heroku now have an install script for a standalone install of the Heroku Client without Foreman and Git.
On Windows, the Heroku Toolbelt installer offers a choice between Full Installation and Custom Installation. If you choose Custom, you can select which components you want to install.

Resources