Cloud Native Buildpacks Tutorial - 5.4. ┗ heroku/buildpacks:18 BuilderでRubyアプリのOCIイメージを作成

heroku/buildpacks:18でRubyのアプリケーションのOCIイメージを作成します。

BuilderとStackを予めpullしておいてください。

docker pull heroku/buildpacks:18
docker pull heroku/pack:18

次のコマンドで"Hello World"アプリケーションを作成します。

mkdir hello-sinatra
cd hello-sinatra
cat <<'EOF' > app.rb
require 'sinatra'

get '/' do
  'Hello World!'
end
EOF

cat <<'EOF' > Gemfile
source 'https://rubygems.org'

gem 'sinatra'
EOF

cat <<'EOF' > Gemfile.lock
GEM
  remote: https://rubygems.org/
  specs:
    mustermann (1.1.1)
      ruby2_keywords (~> 0.0.1)
    rack (2.2.2)
    rack-protection (2.0.8.1)
      rack
    ruby2_keywords (0.0.2)
    sinatra (2.0.8.1)
      mustermann (~> 1.0)
      rack (~> 2.0)
      rack-protection (= 2.0.8.1)
      tilt (~> 2.0)
    tilt (2.0.10)

PLATFORMS
  ruby

DEPENDENCIES
  sinatra

BUNDLED WITH
   1.17.2
EOF

cat <<'EOF' > Procfile
web: ruby app.rb
EOF

pack buildコマンドでイメージを作成します。

pack build making/pack-sinatra --no-pull --builder heroku/buildpacks:18

BuilderとStackを事前にpullしていない場合は--no-pullを外せば、ビルド時にBuilderとStackもpullしますが、ビルドが遅くなります。

次のようなログが出力されます。

===> DETECTING
[detector] heroku/ruby     0.0.1
[detector] heroku/procfile 0.5
===> ANALYZING
[analyzer] Warning: Image "index.docker.io/making/pack-sinatra:latest" not found
===> RESTORING
===> BUILDING
[builder] -----> Installing bundler 1.17.3
[builder] -----> Removing BUNDLED WITH version in the Gemfile.lock
[builder] -----> Compiling Ruby/Rack
[builder] -----> Using Ruby version: ruby-2.6.5
[builder] -----> Loading Bundler Cache
[builder] -----> Installing dependencies using bundler 1.17.3
[builder]        Running: bundle install --without development:test --path /layers/heroku_ruby/gems/vendor/bundle --binstubs vendor/bundle/bin -j4 --deployment
[builder]        Fetching gem metadata from https://rubygems.org/.........
[builder]        Using bundler 1.17.3
[builder]        Fetching rack 2.2.2
[builder]        Fetching ruby2_keywords 0.0.2
[builder]        Fetching tilt 2.0.10
[builder]        Installing tilt 2.0.10
[builder]        Installing ruby2_keywords 0.0.2
[builder]        Fetching mustermann 1.1.1
[builder]        Installing rack 2.2.2
[builder]        Installing mustermann 1.1.1
[builder]        Fetching rack-protection 2.0.8.1
[builder]        Installing rack-protection 2.0.8.1
[builder]        Fetching sinatra 2.0.8.1
[builder]        Installing sinatra 2.0.8.1
[builder]        Bundle complete! 1 Gemfile dependency, 7 gems now installed.
[builder]        Gems in the groups development and test were not installed.
[builder]        Bundled gems are installed into `/layers/heroku_ruby/gems/vendor/bundle`
[builder]        Bundle completed (3.45s)
[builder]        Cleaning up the bundler cache.
[builder] -----> Detecting rake tasks
[builder] 
[builder] ###### WARNING:
[builder] 
[builder]        You have not declared a Ruby version in your Gemfile.
[builder]        To set your Ruby version add this line to your Gemfile:
[builder]        ruby '2.6.5'
[builder]        # See https://devcenter.heroku.com/articles/ruby-versions for more information.
[builder] 
[builder] 
[builder] 
[builder] -----> Discovering process types
[builder]        Procfile declares types     -> web
===> EXPORTING
[exporter] Adding layer 'launcher'
[exporter] Adding layer 'heroku/ruby:env'
[exporter] Adding layer 'heroku/ruby:gems'
[exporter] Adding layer 'heroku/ruby:ruby'
[exporter] Adding 1/1 app layer(s)
[exporter] Adding layer 'config'
[exporter] *** Images (45d722376422):
[exporter]       index.docker.io/making/pack-sinatra:latest
[exporter] Adding cache layer 'heroku/ruby:gems'
Successfully built image making/pack-sinatra

pack build時に--publishオプションをつけると、Docker Registryでのpushを行います。事前にdocker loginが必要です。

作成したイメージをdocker runで起動します。

docker run --rm -e PORT=8080 -p 8080:8080 making/pack-sinatra

アプリケーションにアクセスします。

$ curl localhost:8080 -w '\n'
Hello World!

Docker Imageのサイズを確認します。

$ docker images | grep making/pack-sinatra
making/pack-sinatra                  latest              45d722376422        40 years ago        533MB

pack inspect-imageでイメージを解析します。

$ pack inspect-image making/pack-sinatra
Inspecting image: making/pack-sinatra

REMOTE:
(not present)

LOCAL:

Stack: heroku-18

Base Image:
  Reference: 60f9e03398de7d6a5268be95224246f05eed9f1eecb1fe7605753261f2bd871a
  Top Layer: sha256:ceefbd5b67bc32a9d87867c8c8d375675246e9db9b470cb95133b4e93429b113

Run Images:
  heroku/pack:18

Buildpacks:
  ID                     VERSION
  heroku/ruby            0.0.1
  heroku/procfile        0.5

Processes:
  TYPE                 SHELL        COMMAND                 ARGS
  web (default)        bash         ruby app.rb             
  console              bash         bundle exec irb         
  rake                 bash         bundle exec rake  

おわったらDocker Imageを削除します。

docker rmi making/pack-sinatra