From faffbb54e2fb31f2d153df2ed15ea961c6be285f Mon Sep 17 00:00:00 2001 From: Ed Morley <501702+edmorley@users.noreply.github.com> Date: Mon, 20 Jun 2022 22:50:13 +0100 Subject: [PATCH] Vendor Ruby if an installation is not found The ERB templating feature of this buildpack requires that the `erb` command (part of Ruby) be available at runtime, in order that the nginx config templates can be rendered into a valid nginx config. On Heroku-22 the stack image no longer includes a system Ruby installation, so in order for this buildpack to continue to work, a Ruby install must be vendored by this buildpack. If an app already uses the Ruby buildpack, and that buildpack is ordered prior to the nginx buildpack, then this buildpack will skip the Ruby vendoring step to save installing a redundant copy of Ruby. Fixes #101. GUS-W-11321729. --- bin/compile | 25 +++++++++++++++++++++++++ changelog.md | 4 ++++ readme.md | 4 ++-- 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/bin/compile b/bin/compile index b70de7f..2e1793a 100755 --- a/bin/compile +++ b/bin/compile @@ -19,6 +19,31 @@ cp "$BUILD_DIR/nginx/nginx-debug" "$BUILD_DIR/bin/nginx-debug" nginx_version=$($BUILD_DIR/bin/nginx -V 2>&1 | head -1 | awk '{ print $NF }') echo "-----> nginx-buildpack: Installed ${nginx_version} to app/bin" + +# The ERB templating feature requires a Ruby install at runtime, for the `erb` command. +# As of Heroku-22, there is no system Ruby installation in the stack image, so if the +# app doesn't already have the Ruby buildpack set before this one, we have to vendor +# our own copy of Ruby and ensure it's on PATH at runtime. +if ! command -v erb &> /dev/null; then + echo "-----> nginx-buildpack: An existing Ruby installation was not found (required for erb template support)" + ruby_version="3.1.2" + ruby_url="https://heroku-buildpack-ruby.s3.us-east-1.amazonaws.com/${STACK}/ruby-${ruby_version}.tgz" + vendored_ruby_dir=".heroku-buildpack-nginx/ruby" + mkdir -p "${BUILD_DIR}/${vendored_ruby_dir}" + + if ! curl --silent --show-error --fail --retry 3 --retry-connrefused --connect-timeout 5 "${ruby_url}" | tar -zxC "${BUILD_DIR}/${vendored_ruby_dir}"; then + echo " ! Failed to download Ruby from '${ruby_url}'" >&2 + exit 1 + fi + + mkdir -p "${BUILD_DIR}/.profile.d" + # Deliberately pick the same profile.d script filepath as the Ruby buildpack, + # so if the Ruby buildpack comes after this one, it will overwrite this script. + echo "export PATH=\"\${HOME}/${vendored_ruby_dir}/bin:\${PATH}\"" > "${BUILD_DIR}/.profile.d/ruby.sh" + + echo "-----> nginx-buildpack: Installed Ruby ${ruby_version}" +fi + cp bin/start-nginx "$BUILD_DIR/bin/" echo '-----> nginx-buildpack: Added start-nginx to app/bin' cp bin/start-nginx-debug "$BUILD_DIR/bin/" diff --git a/changelog.md b/changelog.md index 86168fc..022d83b 100644 --- a/changelog.md +++ b/changelog.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.9] - 2022-06-21 +### Changes +- If a Ruby installation is not found (required for the ERB templating feature), this buildpack will now install its own, to ensure it works on Heroku-22. + ## [1.8] - 2022-05-19 ### Changes - [heroku-18] updated nginx to 1.20.2, bump zlib to 1.2.12, updated PCRE to 8.45 diff --git a/readme.md b/readme.md index 0c4a98b..b24be14 100644 --- a/readme.md +++ b/readme.md @@ -150,7 +150,7 @@ The buildpack will not start NGINX until a file has been written to `/tmp/app-in ## Setup -Here are 2 setup examples. One example for a new app, another for an existing app. In both cases, we are working with ruby & unicorn. Keep in mind that this buildpack is not ruby specific. +Here are 2 setup examples. One example for a new app, another for an existing app. In both cases, we are working with ruby & unicorn. Keep in mind that this buildpack is not ruby specific. However if your app does happen to use Ruby, make sure to add the NGINX buildpack **after** the Ruby buildpack, so the NGINX buildpack doesn't have to install its own redundant copy of Ruby for the ERB templating feature. ### Existing App @@ -227,7 +227,7 @@ Create & Push Heroku App: ```bash $ heroku create $ heroku buildpacks:add heroku/ruby -$ heroku buildpacks:add https://github.com/heroku/heroku-buildpack-nginx +$ heroku buildpacks:add heroku-community/nginx $ git add . $ git commit -am "init" $ git push heroku main