Build a Ruby on Rails application image in 5 minutes, no Dockerfile required.
At the end of this tutorial, you'll have a working OCI image of a Ruby on Rails application that can run locally. You will learn about the Cloud Native Buildpack (CNB) ecosystem, and how to utilize the pack CLI to build images without the need to write or maintain a Dockerfile.
You can now also use the
heroku/rubyCNB on Heroku Fir generation via the pilot program. See the Getting started on Heroku Fir Dev Center tutorial.
We assume you have docker installed and a working copy of git. Next, you will need to install the CLI tool for building CNBs, pack CLI. If you're on a Mac you can install it via Homebrew:
$ brew install buildpacks/tap/pack
Ensure that pack is installed correctly:
$ pack --version
0.40.0+git-06c9593.build-6752
Once pack is installed, the only configuration you'll need for this tutorial is to set a default builder:
$ pack config default-builder heroku/builder:24
Builder 'heroku/builder:24' is now the default builder
You can view your default builder at any time:
$ pack config default-builder
The current default builder is 'heroku/builder:24'
Note: The
heroku/builder:24supports both amd64 (also known as x86) and arm64 (such as aarch64 used with newer Mac machines) architectures. If needed, you can configure the architecture fordockerandpackCLIs using the--platformargument if needed. For example--platform linux/amd64.
Note
Skip ahead if you want to build the application first and get into the details later. You won't need to know about builders for the rest of this tutorial.
In short, a builder is a delivery mechanism for buildpacks. A builder contains references to base images and individual buildpacks. A base image contains the operating system and system dependencies. Buildpacks are the components that will configure an image to run your application, that’s where the bulk of the logic lives and why the project is called “Cloud Native Buildpacks” and not “Cloud Native Builders.”
You can view the contents of a builder via the command pack builder inspect. For example:
$ pack builder inspect heroku/builder:24 | awk '/^Buildpacks:/ {flag=1} /^Detection Order:/ {exit} flag'
Buildpacks:
ID NAME VERSION HOMEPAGE
heroku/deb-packages Heroku .deb Packages 0.3.0 https://github.com/heroku/buildpacks-deb-packages
heroku/dotnet Heroku .NET 1.0.5 https://github.com/heroku/buildpacks-dotnet
heroku/go Heroku Go 2.2.1 https://github.com/heroku/buildpacks-go
heroku/gradle Heroku Gradle 7.0.10 https://github.com/heroku/buildpacks-jvm
heroku/java Heroku Java 7.0.10 https://github.com/heroku/buildpacks-jvm
heroku/jvm Heroku OpenJDK 7.0.10 https://github.com/heroku/buildpacks-jvm
heroku/maven Heroku Maven 7.0.10 https://github.com/heroku/buildpacks-jvm
heroku/nodejs Heroku Node.js 5.5.4 https://github.com/heroku/buildpacks-nodejs
heroku/php Heroku PHP 1.5.1 https://github.com/heroku/buildpacks-php
heroku/procfile Heroku Procfile 4.2.1 https://github.com/heroku/buildpacks-procfile
heroku/python Heroku Python 6.1.0 https://github.com/heroku/buildpacks-python
heroku/ruby Heroku Ruby 12.3.0 https://github.com/heroku/buildpacks-ruby
heroku/sbt Heroku sbt 7.0.10 https://github.com/heroku/buildpacks-jvm
heroku/scala Heroku Scala 7.0.10 https://github.com/heroku/buildpacks-jvm
Note
Your output version numbers may differ.
This output shows the various buildpacks that represent the different languages that are supported by this builder such as heroku/go and heroku/nodejs.
How do you configure a CNB? Give them an application. While Dockerfile is procedural, buildpacks, are declarative. A buildpack will determine what your application needs to function by inspecting the code on disk.
For this example, we're using a pre-built Ruby on Rails application. Download it now:
$ git clone https://github.com/heroku/ruby-getting-started
$ cd ruby-getting-started
Verify you're in the correct directory:
$ ls -A
.env
.git
.github
.gitignore
Gemfile
Gemfile.lock
Procfile
README.md
Rakefile
app
app.json
bin
config
config.ru
db
lib
log
public
test
vendor
This tutorial was built using the following commit SHA:
$ git log --oneline | head -n1
b903ad4 Fix migrate status output (#215)
Now build an image named my-image-name by executing the heroku builder against the application by running the
pack build command:
$ pack build my-image-name --path .
===> ANALYZING
Image with name "my-image-name" not found
===> DETECTING
2 of 5 buildpacks participating
heroku/ruby 12.3.0
heroku/procfile 4.2.1
===> RESTORING
Skipping buildpack layer analysis
===> BUILDING
## Heroku Ruby Buildpack
- Ruby version `3.4.8` from `Gemfile.lock`
- Installing ..... (2.0s)
- Bundler version `4.0.5` from `Gemfile.lock`
- Running `gem install bundler --version 4.0.5 --install-dir /layers/heroku_ruby/bundler --bindir /layers/heroku_ruby/bundler/bin --force --no-document --env-shebang` ..... (2.2s)
- Bundle install gems
- Running `BUNDLE_FROZEN="1" BUNDLE_GEMFILE="/workspace/Gemfile" BUNDLE_WITHOUT="development:test" bundle install`
Fetching gem metadata from https://rubygems.org/.........
Fetching rake 13.3.1
Installing rake 13.3.1
Fetching base64 0.3.0
Fetching bigdecimal 4.0.1
Fetching concurrent-ruby 1.3.6
Fetching connection_pool 3.0.2
Installing base64 0.3.0
Fetching drb 2.2.3
Installing bigdecimal 4.0.1 with native extensions
Installing connection_pool 3.0.2
Installing drb 2.2.3
Fetching json 2.19.1
Fetching logger 1.7.0
Installing concurrent-ruby 1.3.6
Installing logger 1.7.0
Installing json 2.19.1 with native extensions
Fetching prism 1.9.0
Installing prism 1.9.0 with native extensions
Fetching securerandom 0.4.1
Installing securerandom 0.4.1
Fetching uri 1.1.1
Installing uri 1.1.1
Fetching builder 3.3.0
Installing builder 3.3.0
Fetching erubi 1.13.1
Installing erubi 1.13.1
Fetching racc 1.8.1
Installing racc 1.8.1 with native extensions
Fetching crass 1.0.6
Installing crass 1.0.6
Fetching rack 3.2.5
Installing rack 3.2.5
Fetching useragent 0.16.11
Installing useragent 0.16.11
Fetching prettyprint 0.2.0
Installing prettyprint 0.2.0
Fetching erb 6.0.2
Installing erb 6.0.2 with native extensions
Fetching date 3.5.1
Installing date 3.5.1 with native extensions
Fetching stringio 3.2.0
Installing stringio 3.2.0 with native extensions
Fetching tsort 0.2.0
Installing tsort 0.2.0
Fetching io-console 0.8.2
Installing io-console 0.8.2 with native extensions
Fetching thor 1.5.0
Installing thor 1.5.0
Fetching zeitwerk 2.7.5
Installing zeitwerk 2.7.5
Fetching nio4r 2.7.5
Installing nio4r 2.7.5 with native extensions
Fetching websocket-extensions 0.1.5
Installing websocket-extensions 0.1.5
Fetching timeout 0.6.0
Installing timeout 0.6.0
Fetching marcel 1.1.0
Installing marcel 1.1.0
Fetching mini_mime 1.1.5
Installing mini_mime 1.1.5
Fetching msgpack 1.8.0
Installing msgpack 1.8.0 with native extensions
Fetching ffi 1.17.3 (x86_64-linux-gnu)
Installing ffi 1.17.3 (x86_64-linux-gnu)
Fetching rb-fsevent 0.11.2
Installing rb-fsevent 0.11.2
Fetching pg 1.6.3 (x86_64-linux)
Installing pg 1.6.3 (x86_64-linux)
Fetching rack-timeout 0.7.0
Installing rack-timeout 0.7.0
Fetching i18n 1.14.8
Installing i18n 1.14.8
Fetching tzinfo 2.0.6
Installing tzinfo 2.0.6
Fetching nokogiri 1.19.1 (x86_64-linux-gnu)
Installing nokogiri 1.19.1 (x86_64-linux-gnu)
Fetching rack-session 2.1.1
Installing rack-session 2.1.1
Fetching rack-test 2.2.0
Installing rack-test 2.2.0
Fetching rackup 2.3.1
Installing rackup 2.3.1
Fetching pp 0.6.3
Installing pp 0.6.3
Fetching psych 5.3.1
Installing psych 5.3.1 with native extensions
Fetching websocket-driver 0.8.0
Installing websocket-driver 0.8.0 with native extensions
Fetching net-protocol 0.2.2
Installing net-protocol 0.2.2
Fetching reline 0.6.3
Installing reline 0.6.3
Fetching rb-inotify 0.11.1
Installing rb-inotify 0.11.1
Fetching loofah 2.25.0
Installing loofah 2.25.0
Fetching puma 7.2.0
Installing puma 7.2.0 with native extensions
Fetching net-imap 0.6.2
Installing net-imap 0.6.2
Fetching net-pop 0.1.2
Installing net-pop 0.1.2
Fetching net-smtp 0.5.1
Installing net-smtp 0.5.1
Fetching listen 3.10.0
Installing listen 3.10.0
Fetching rails-html-sanitizer 1.7.0
Installing rails-html-sanitizer 1.7.0
Fetching rdoc 7.2.0
Installing rdoc 7.2.0
Fetching mail 2.9.0
Installing mail 2.9.0
Fetching sdoc 2.6.5
Installing sdoc 2.6.5
Fetching bootsnap 1.23.0
Installing bootsnap 1.23.0 with native extensions
Fetching minitest 6.0.2
Fetching irb 1.17.0
Installing minitest 6.0.2
Installing irb 1.17.0
Fetching activesupport 8.1.2
Installing activesupport 8.1.2
Fetching rails-dom-testing 2.3.0
Fetching globalid 1.3.0
Fetching activemodel 8.1.2
Installing rails-dom-testing 2.3.0
Installing globalid 1.3.0
Fetching actionview 8.1.2
Installing activemodel 8.1.2
Fetching activejob 8.1.2
Installing actionview 8.1.2
Installing activejob 8.1.2
Fetching activerecord 8.1.2
Fetching actionpack 8.1.2
Installing activerecord 8.1.2
Installing actionpack 8.1.2
Fetching railties 8.1.2
Fetching actioncable 8.1.2
Fetching actionmailer 8.1.2
Installing actioncable 8.1.2
Installing actionmailer 8.1.2
Installing railties 8.1.2
Fetching propshaft 1.3.1
Installing propshaft 1.3.1
Fetching activestorage 8.1.2
Installing activestorage 8.1.2
Fetching actionmailbox 8.1.2
Installing actionmailbox 8.1.2
Fetching action_text-trix 2.1.17
Fetching importmap-rails 2.2.3
Installing action_text-trix 2.1.17
Installing importmap-rails 2.2.3
Fetching actiontext 8.1.2
Installing actiontext 8.1.2
Fetching rails 8.1.2
Installing rails 8.1.2
Bundle complete! 10 Gemfile dependencies, 78 gems now installed.
Gems in the groups 'development' and 'test' were not installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
- Done (30.2s)
- Running `bundle clean --force` ... (0.2s)
- Default process detection
- Running `bundle list` ... (0.1s)
- Detected rails app (`rails` gem found)
- Rake assets install
- Detected rake (`rake` gem found, `Rakefile` found at `/workspace/Rakefile`)
- Running `rake -P --trace` .... (1.8s)
- Compiling assets with cache (detected `rake assets:precompile` and `rake assets:clean` via `rake -P`)
- Creating cache for /workspace/public/assets
- Creating cache for /workspace/tmp/cache/assets
- Running `rake assets:precompile assets:clean --trace`
** Invoke assets:precompile (first_time)
** Invoke environment (first_time)
** Execute environment
** Execute assets:precompile
** Invoke assets:clean (first_time)
** Invoke environment
** Execute assets:clean
Generating image variants require the image_processing gem. Please add `gem "image_processing", "~> 1.2"` to your Gemfile or set `config.active_storage.variant_processor = :disabled`.
Writing lang-logo-27c62977.png
Writing application-f5e7b2f6.css
Writing actiontext-c9c6c481.js
Writing actiontext.esm-c376325e.js
Writing trix-2e4b1469.js
Writing trix-65afdb1d.css
Writing actioncable.esm-e0ec9819.js
Writing action_cable-5212cfee.js
Writing actioncable-ac25813f.js
Writing activestorage-f9e46063.js
Writing activestorage.esm-81bb34bc.js
Writing rails-ujs.esm-e925103b.js
Writing rails-ujs-20eaf715.js
- Done (0.7s)
- Storing cache for /workspace/public/assets
- Storing cache for (empty) /workspace/tmp/cache/assets
- Done (finished in 37.6s)
## Procfile Buildpack
- Processes from `Procfile`
- web: `bundle exec puma -C config/puma.rb`
- Done (finished in < 0.1s)
===> EXPORTING
Adding layer 'heroku/ruby:binruby'
Adding layer 'heroku/ruby:bundler'
Adding layer 'heroku/ruby:cache_public_assets'
Adding layer 'heroku/ruby:cache_tmp_cache_assets'
Adding layer 'heroku/ruby:env_defaults'
Adding layer 'heroku/ruby:gems'
Adding layer 'heroku/ruby:user_binstubs'
Adding layer 'buildpacksio/lifecycle:launch.sbom'
Added 1/1 app layer(s)
Adding layer 'buildpacksio/lifecycle:launcher'
Adding layer 'buildpacksio/lifecycle:config'
Adding layer 'buildpacksio/lifecycle:process-types'
Adding label 'io.buildpacks.lifecycle.metadata'
Adding label 'io.buildpacks.build.metadata'
Adding label 'io.buildpacks.project.metadata'
Adding label 'io.buildpacks.exec-env'
Setting default process type 'web'
Saving my-image-name...
*** Images (1b346fa21f3b):
my-image-name
Adding cache layer 'heroku/ruby:binruby'
Adding cache layer 'heroku/ruby:bundler'
Adding cache layer 'heroku/ruby:cache_public_assets'
Adding cache layer 'heroku/ruby:cache_tmp_cache_assets'
Adding cache layer 'heroku/ruby:gems'
Successfully built image 'my-image-name'
Note
Your output may differ.
Verify that you see “Successfully built image my-image-name” at the end of the output. And verify that the image is present locally:
$ docker image ls --format "table {{.ID}}\t{{.Repository}}\t{{.Tag}}" | grep my-image-name
1b346fa21f3b my-image-name latest
Note
Skip ahead if you want to run the application first and get into the details later.
When you run pack build with a builder, each buildpack runs a detection script to determine if it should be eligible to build the application. In our case the heroku/ruby buildpack found a Gemfile file. As a result, the buildpack has enough information to install Ruby dependencies. You can view a list of the buildpacks used in the build output:
===> DETECTING
2 of 5 buildpacks participating
heroku/ruby 12.3.0
heroku/procfile 4.2.1
===> RESTORING
Skipping buildpack layer analysis
After the detect phase, each buildpack will execute. Buildpacks can inspect your project, install files to disk, run commands, write environment variables, and more. You can see some examples of that in the output above. For example, the Ruby buildpack installs dependencies from the Gemfile automatically:
- Running `BUNDLE_FROZEN="1" BUNDLE_GEMFILE="/workspace/Gemfile" BUNDLE_WITHOUT="development:test" bundle install`
If you’re familiar with Dockerfile you might know that many commands in a Dockerfile will create a layer. Buildpacks also use layers, but the CNB buildpack API provides for fine grained control over what exactly is in these layers and how they’re composed. Unlike Dockerfile, all images produced by CNBs can be rebased. The CNB api also improves on many of the pitfalls outlined in the satirical article Write a Good Dockerfile in 19 'Easy' Steps.
Even though we used pack and CNBs to build our image, it can be run with your favorite tools like any other OCI image. We will be using the docker command line to run our image.
By default, images will be booted into a web server configuration. You can launch the app we just built by running:
$ docker run -it --rm --env PORT=5006 -p 5006:5006 my-image-name
[1] Puma starting in cluster mode...
[1] * Puma version: 7.2.0 ("On The Corner")
[1] * Ruby version: ruby 3.4.8 (2025-12-17 revision 995b59f666) +PRISM [x86_64-linux]
[1] * Min threads: 3
[1] * Max threads: 3
[1] * Environment: production
[1] * Master PID: 1
[1] * Workers: 2
[1] * Restarts: (✔) hot (✖) phased (✖) refork
[1] * Preloading application
Generating image variants require the image_processing gem. Please add `gem "image_processing", "~> 1.2"` to your Gemfile or set `config.active_storage.variant_processor = :disabled`.
[1] * Listening on http://[::]:5006
[1] Use Ctrl-C to stop
[1] - Worker 0 (PID: 15) booted in 0.01s, phase: 0
[1] - Worker 1 (PID: 19) booted in 0.08s, phase: 0
Now when you visit http://localhost:5006 you should see a working web application:
Don't forget to stop the docker container when you're done.
Here's a quick breakdown of that command we just ran:
docker runCreate and run a new container from an image.-itMakes the container interactive and allocates a TTY.--rmAutomatically remove the container when it exits.--env PORT=5006Creates an environment variable namedPORTand sets it to5006this is needed so the application inside the container knows what port to bind the web server.-p 5006:5006Publishes a container's port(s) to the host. This is what allows requests from your machine to be received by the container.my-image-nameThe name of the image you want to use for the application.
So far, we've downloaded an application via git and run a single command pack build to generate an image, and then we can use that image as if it was generated via a Dockerfile via the docker run command.
In addition to running the image as a web server, you can access the container's terminal interactively. In a new terminal window try running this command:
$ docker run -it --rm my-image-name bash
Now you can inspect the container interactively. For example, you can see the files on disk with ls:
$ ls -A
.env
.git
.github
.gitignore
Gemfile
Gemfile.lock
Procfile
README.md
Rakefile
app
app.json
bin
build_output.txt
config
config.ru
db
lib
log
public
test
tmp
vendor
And anything else you would typically do via an interactive container session.
Note
Skip this section if you want to try building your application with CNBs and learn about container structure later.
If you’re an advanced Dockerfile user you might be interested in learning more about the internal structure of the image on disk. You can access the image disk interactively by using the bash docker command above.
If you view the root directory / you’ll see there is a layers folder. Every buildpack that executes gets a unique folder:
$ docker run --rm my-image-name "ls /layers"
config
heroku_ruby
sbom
Individual buildpacks can compose multiple layers from their buildpack directory. For example you can see that ruby binary is present within that buildpack layer directory:
$ docker run --rm my-image-name "which ruby"
/layers/heroku_ruby/binruby/bin/ruby
OCI images are represented as sequential modifications to disk. By scoping buildpack disk modifications to their own directory, the CNB API guarantees that changes to a layer in one buildpack will not affect the contents of disk to another layer. This means that OCI images produced by CNBs are rebaseable by default, while those produced by Dockerfile are not.
We saw before how the image booted a web server by default. This is accomplished using an entrypoint. In another terminal outside of the running container you can view that entrypoint:
$ docker inspect my-image-name | grep '"Entrypoint": \[' -A2
"Entrypoint": [
"/cnb/process/web"
],
From within the image, you can see that file on disk:
$ docker run --rm my-image-name "ls /cnb/process/"
web
While you might not need this level of detail to build and run an application with Cloud Native Buildpacks, it is useful to understand how they’re structured if you ever want to write your own buildpack.
So far we've learned that CNBs are a declarative interface for producing OCI images (like docker). They aim to be no to low configuration and once built, you can interact with them like any other image.
For the next step, we encourage you to try running pack with the Heroku builder against your application and let us know how it went. We encourage you to share your experience by opening a discussion and walking us through what happened:
- What went well?
- What could be better?
- Do you have any questions?
We are actively working on our Cloud Native Buildpacks and want to hear about your experience. The documentation below covers some intermediate-level topics that you might find helpful.
Language support is provided by individual buildpacks that are shipped with the builder. The above example uses the heroku/ruby buildpack which is visible on GitHub. When you execute pack build with a builder, every buildpack has the opportunity to "detect" if it should execute against that project. The heroku/ruby buildpack looks for a Gemfile file in the root of the project and if found, knows how to detect a ruby version and install dependencies.
In addition to this auto-detection behavior, you can specify buildpacks through the --buildpack flag with the pack CLI or through a project.toml file at the root of your application.
For example, if you wanted to install both Ruby and Node.js you could create a project.toml file in the root of your application and specify those buildpacks.
In file project.toml write:
[_]
schema-version = "0.2"
id = "sample.ruby+nodejs.app"
name = "Sample Ruby & NodeJS App"
version = "1.0.0"
[[io.buildpacks.group]]
uri = "heroku/nodejs"
[[io.buildpacks.group]]
uri = "heroku/ruby"
[[io.buildpacks.group]]
uri = "heroku/procfile"Ensure that a Node.js dependency file, such as package.json is in the root directory, and then build your application:
$ pack build my-image-name --path .
===> ANALYZING
Image with name "my-image-name" not found
===> DETECTING
heroku/nodejs 5.5.4
heroku/ruby 12.3.0
heroku/procfile 4.2.1
===> RESTORING
Skipping buildpack layer analysis
===> BUILDING
## Heroku Node.js
- Checking Node.js version
- Node.js version not specified, using `24.x`
- Resolved Node.js version: `24.14.0`
- Installing Node.js distribution
- GET https://nodejs.org/download/release/v24.14.0/node-v24.14.0-linux-x64.tar.gz ... (0.3s)
- Validating ... (< 0.1s)
- Extracting .... (1.0s)
- Verifying checksum
- Extracting Node.js `24.14.0 (linux-amd64)`
- Installing Node.js `24.14.0 (linux-amd64)` ... (< 0.1s)
- Done (finished in 1.5s)
## Heroku Ruby Buildpack
- Ruby version `3.4.8` from `Gemfile.lock`
- Installing .... (1.8s)
- Bundler version `4.0.5` from `Gemfile.lock`
- Running `gem install bundler --version 4.0.5 --install-dir /layers/heroku_ruby/bundler --bindir /layers/heroku_ruby/bundler/bin --force --no-document --env-shebang` ... (0.3s)
- Bundle install gems
- Running `BUNDLE_FROZEN="1" BUNDLE_GEMFILE="/workspace/Gemfile" BUNDLE_WITHOUT="development:test" bundle install`
Fetching gem metadata from https://rubygems.org/.........
Fetching rake 13.3.1
Installing rake 13.3.1
Fetching base64 0.3.0
Fetching bigdecimal 4.0.1
Fetching concurrent-ruby 1.3.6
Fetching connection_pool 3.0.2
Installing base64 0.3.0
Fetching drb 2.2.3
Installing bigdecimal 4.0.1 with native extensions
Installing connection_pool 3.0.2
Installing drb 2.2.3
Fetching json 2.19.1
Fetching logger 1.7.0
Installing concurrent-ruby 1.3.6
Installing logger 1.7.0
Installing json 2.19.1 with native extensions
Fetching prism 1.9.0
Installing prism 1.9.0 with native extensions
Fetching securerandom 0.4.1
Installing securerandom 0.4.1
Fetching uri 1.1.1
Installing uri 1.1.1
Fetching builder 3.3.0
Installing builder 3.3.0
Fetching erubi 1.13.1
Installing erubi 1.13.1
Fetching racc 1.8.1
Installing racc 1.8.1 with native extensions
Fetching crass 1.0.6
Installing crass 1.0.6
Fetching rack 3.2.5
Installing rack 3.2.5
Fetching useragent 0.16.11
Installing useragent 0.16.11
Fetching prettyprint 0.2.0
Installing prettyprint 0.2.0
Fetching erb 6.0.2
Installing erb 6.0.2 with native extensions
Fetching date 3.5.1
Installing date 3.5.1 with native extensions
Fetching stringio 3.2.0
Installing stringio 3.2.0 with native extensions
Fetching tsort 0.2.0
Installing tsort 0.2.0
Fetching io-console 0.8.2
Installing io-console 0.8.2 with native extensions
Fetching thor 1.5.0
Installing thor 1.5.0
Fetching zeitwerk 2.7.5
Installing zeitwerk 2.7.5
Fetching nio4r 2.7.5
Installing nio4r 2.7.5 with native extensions
Fetching websocket-extensions 0.1.5
Installing websocket-extensions 0.1.5
Fetching timeout 0.6.0
Installing timeout 0.6.0
Fetching marcel 1.1.0
Installing marcel 1.1.0
Fetching mini_mime 1.1.5
Installing mini_mime 1.1.5
Fetching msgpack 1.8.0
Installing msgpack 1.8.0 with native extensions
Fetching ffi 1.17.3 (x86_64-linux-gnu)
Installing ffi 1.17.3 (x86_64-linux-gnu)
Fetching rb-fsevent 0.11.2
Installing rb-fsevent 0.11.2
Fetching pg 1.6.3 (x86_64-linux)
Installing pg 1.6.3 (x86_64-linux)
Fetching rack-timeout 0.7.0
Installing rack-timeout 0.7.0
Fetching i18n 1.14.8
Installing i18n 1.14.8
Fetching tzinfo 2.0.6
Installing tzinfo 2.0.6
Fetching nokogiri 1.19.1 (x86_64-linux-gnu)
Installing nokogiri 1.19.1 (x86_64-linux-gnu)
Fetching rack-session 2.1.1
Installing rack-session 2.1.1
Fetching rack-test 2.2.0
Installing rack-test 2.2.0
Fetching rackup 2.3.1
Installing rackup 2.3.1
Fetching pp 0.6.3
Installing pp 0.6.3
Fetching psych 5.3.1
Installing psych 5.3.1 with native extensions
Fetching websocket-driver 0.8.0
Installing websocket-driver 0.8.0 with native extensions
Fetching net-protocol 0.2.2
Installing net-protocol 0.2.2
Fetching reline 0.6.3
Installing reline 0.6.3
Fetching rb-inotify 0.11.1
Installing rb-inotify 0.11.1
Fetching loofah 2.25.0
Installing loofah 2.25.0
Fetching puma 7.2.0
Installing puma 7.2.0 with native extensions
Fetching net-imap 0.6.2
Installing net-imap 0.6.2
Fetching net-pop 0.1.2
Installing net-pop 0.1.2
Fetching net-smtp 0.5.1
Installing net-smtp 0.5.1
Fetching listen 3.10.0
Installing listen 3.10.0
Fetching rails-html-sanitizer 1.7.0
Installing rails-html-sanitizer 1.7.0
Fetching rdoc 7.2.0
Installing rdoc 7.2.0
Fetching mail 2.9.0
Installing mail 2.9.0
Fetching sdoc 2.6.5
Installing sdoc 2.6.5
Fetching bootsnap 1.23.0
Installing bootsnap 1.23.0 with native extensions
Fetching minitest 6.0.2
Fetching irb 1.17.0
Installing minitest 6.0.2
Installing irb 1.17.0
Fetching activesupport 8.1.2
Installing activesupport 8.1.2
Fetching rails-dom-testing 2.3.0
Fetching globalid 1.3.0
Fetching activemodel 8.1.2
Installing rails-dom-testing 2.3.0
Installing globalid 1.3.0
Fetching actionview 8.1.2
Installing activemodel 8.1.2
Fetching activejob 8.1.2
Installing activejob 8.1.2
Installing actionview 8.1.2
Fetching activerecord 8.1.2
Fetching actionpack 8.1.2
Installing activerecord 8.1.2
Installing actionpack 8.1.2
Fetching railties 8.1.2
Fetching actioncable 8.1.2
Fetching actionmailer 8.1.2
Installing actioncable 8.1.2
Installing actionmailer 8.1.2
Installing railties 8.1.2
Fetching propshaft 1.3.1
Installing propshaft 1.3.1
Fetching activestorage 8.1.2
Installing activestorage 8.1.2
Fetching actionmailbox 8.1.2
Installing actionmailbox 8.1.2
Fetching action_text-trix 2.1.17
Fetching importmap-rails 2.2.3
Installing action_text-trix 2.1.17
Installing importmap-rails 2.2.3
Fetching actiontext 8.1.2
Installing actiontext 8.1.2
Fetching rails 8.1.2
Installing rails 8.1.2
Bundle complete! 10 Gemfile dependencies, 78 gems now installed.
Gems in the groups 'development' and 'test' were not installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
- Done (30.1s)
- Running `bundle clean --force` ... (0.2s)
- Default process detection
- Running `bundle list` ... (0.1s)
- Detected rails app (`rails` gem found)
- Rake assets install
- Detected rake (`rake` gem found, `Rakefile` found at `/workspace/Rakefile`)
- Running `rake -P --trace` .... (1.5s)
- Compiling assets with cache (detected `rake assets:precompile` and `rake assets:clean` via `rake -P`)
- Creating cache for /workspace/public/assets
- Creating cache for /workspace/tmp/cache/assets
- Running `rake assets:precompile assets:clean --trace`
** Invoke assets:precompile (first_time)
** Invoke environment (first_time)
** Execute environment
** Execute assets:precompile
** Invoke assets:clean (first_time)
** Invoke environment
** Execute assets:clean
Generating image variants require the image_processing gem. Please add `gem "image_processing", "~> 1.2"` to your Gemfile or set `config.active_storage.variant_processor = :disabled`.
Writing lang-logo-27c62977.png
Writing application-f5e7b2f6.css
Writing actiontext-c9c6c481.js
Writing actiontext.esm-c376325e.js
Writing trix-2e4b1469.js
Writing trix-65afdb1d.css
Writing actioncable.esm-e0ec9819.js
Writing action_cable-5212cfee.js
Writing actioncable-ac25813f.js
Writing activestorage-f9e46063.js
Writing activestorage.esm-81bb34bc.js
Writing rails-ujs.esm-e925103b.js
Writing rails-ujs-20eaf715.js
- Done (0.8s)
- Storing cache for /workspace/public/assets
- Storing cache for (empty) /workspace/tmp/cache/assets
- Done (finished in 35.2s)
## Procfile Buildpack
- Processes from `Procfile`
- web: `bundle exec puma -C config/puma.rb`
- Done (finished in < 0.1s)
===> EXPORTING
Adding layer 'heroku/nodejs:available_parallelism'
Adding layer 'heroku/nodejs:dist'
Adding layer 'heroku/nodejs:web_env'
Adding layer 'heroku/nodejs:z_node_module_bins'
Adding layer 'heroku/ruby:binruby'
Adding layer 'heroku/ruby:bundler'
Adding layer 'heroku/ruby:cache_public_assets'
Adding layer 'heroku/ruby:cache_tmp_cache_assets'
Adding layer 'heroku/ruby:env_defaults'
Adding layer 'heroku/ruby:gems'
Adding layer 'heroku/ruby:user_binstubs'
Adding layer 'buildpacksio/lifecycle:launch.sbom'
Added 1/1 app layer(s)
Adding layer 'buildpacksio/lifecycle:launcher'
Adding layer 'buildpacksio/lifecycle:config'
Adding layer 'buildpacksio/lifecycle:process-types'
Adding label 'io.buildpacks.lifecycle.metadata'
Adding label 'io.buildpacks.build.metadata'
Adding label 'io.buildpacks.project.metadata'
Adding label 'io.buildpacks.exec-env'
Setting default process type 'web'
Saving my-image-name...
*** Images (ab6163880886):
my-image-name
Adding cache layer 'heroku/nodejs:dist'
Adding cache layer 'heroku/ruby:binruby'
Adding cache layer 'heroku/ruby:bundler'
Adding cache layer 'heroku/ruby:cache_public_assets'
Adding cache layer 'heroku/ruby:cache_tmp_cache_assets'
Adding cache layer 'heroku/ruby:gems'
Successfully built image 'my-image-name'
You can run the image and inspect everything is installed as expected:
$ docker run -it --rm my-image-name bash
$ which node
/layers/heroku_nodejs/dist/bin/node
Most buildpacks rely on existing community standards to allow you to configure your application declaratively. They can also implement custom logic based on file contents on disk or environment variables present at build time.
The Procfile is a configuration file format that was introduced by Heroku in 2011, you can now use this behavior on your CNB-powered application via the heroku/procfile, which like the rest of the buildpacks in our builder is open source. The heroku/procfile buildpack allows you to configure your web startup process.
This is the web entry in the getting started guide's Procfile:
web: bundle exec puma -C config/puma.rb
By including this file and using heroku/procfile buildpack, your application will receive a default web process. You can configure this behavior by changing the contents of that file.
