はじめに
Railsアプリを書いているのですが、Dockerfileをちまちま書くのが面倒だったので、Cloud Native Buildpacksを使ってみることにしました。
参考
@satococoaさんがすでに検証記事を書かれていたのでそれを参考に進めていきます。
対象アプリとして、以下で作成しているRailsアプリを利用します。
Rails 7にwebpackを使っています。
また、公式サイトも参考にします。
環境準備
pack
コマンドをインストールします。公式サイトにやり方が書かれているのでそれをそのまま実行します。
また、Procfile
というものが必要ということで作成します。中身は以下のようなものにしました。
web: bundle exec puma -t 5:5 -p ${PORT:-8080} -e ${RACK_ENV:-production} release: bin/rails db:migrate
Procfileの説明は以下のものを参照。
Railsアプリの起動に関する記述については以下のものを参考にしました。
作成する
以下のコマンドを実行します。
$ pack build イメージ名 --builder heroku/buildpacks:20
以下のようなログが流れてイメージが作成されます。
20: Pulling from heroku/buildpacks Digest: sha256:2b638e111bb446d298e463442258da052884f9c64b2347f5cb4fc1c5af334d98 Status: Image is up to date for heroku/buildpacks:20 20-cnb: Pulling from heroku/heroku Digest: sha256:e12a18dc1ea56391d5c178a6ae32485b01f2474c9b72db2d56197bb575fb40ec Status: Image is up to date for heroku/heroku:20-cnb ===> ANALYZING Previous image with name "イメージ名" not found ===> DETECTING Warning: Buildpack 'heroku/ruby@0.0.0' requests deprecated API '0.4' Warning: Buildpack 'heroku/python@0.0.0' requests deprecated API '0.4' Warning: Buildpack 'heroku/scala@0.0.0' requests deprecated API '0.4' Warning: Buildpack 'heroku/php@0.0.0' requests deprecated API '0.4' Warning: Buildpack 'heroku/go@0.0.0' requests deprecated API '0.4' Warning: Buildpack 'heroku/nodejs-function@0.9.18' requests deprecated API '0.2' Warning: Buildpack 'heroku/nodejs@0.5.14' requests deprecated API '0.2' Warning: Buildpack 'heroku/gradle@0.0.0' requests deprecated API '0.4' heroku/ruby 0.0.0 heroku/procfile 2.0.0 ===> RESTORING ===> BUILDING -----> Installing bundler 2.3.25 -----> Removing BUNDLED WITH version in the Gemfile.lock -----> Compiling Ruby/Rails -----> Using Ruby version: ruby-3.2.1 -----> Installing dependencies using bundler 2.3.25 Running: BUNDLE_WITHOUT='development:test' BUNDLE_PATH=vendor/bundle BUNDLE_BIN=vendor/bundle/bin BUNDLE_DEPLOYMENT=1 bundle install -j4 Fetching gem metadata from https://rubygems.org/......... Fetching rake 13.0.6 (省略) Bundle completed (13.31s) Cleaning up the bundler cache. Removing bundler (2.3.25) -----> Installing node-v16.18.1-linux-x64 -----> Installing yarn-v1.22.19 -----> Detecting rake tasks -----> Preparing app for Rails asset pipeline Running: rake assets:precompile yarn install v1.22.19 [1/4] Resolving packages... [2/4] Fetching packages... [3/4] Linking dependencies... [4/4] Building fresh packages... Done in 20.31s. yarn run v1.22.19 $ webpack --config webpack.config.js asset application.js 203 KiB [emitted] [minimized] (name: application) 2 related assets orphan modules 449 KiB [orphan] 80 modules runtime modules 670 bytes 3 modules cacheable modules 446 KiB ./app/javascript/application.js + 68 modules 427 KiB [built] [code generated] ./node_modules/@rails/actioncable/src/index.js + 9 modules 19.1 KiB [built] [code generated] webpack 5.75.0 compiled successfully in 5486 ms Done in 6.28s. yarn install v1.22.19 [1/4] Resolving packages... success Already up-to-date. Done in 0.22s. yarn run v1.22.19 $ sass ./app/assets/stylesheets/application.bootstrap.scss:./app/assets/builds/application.css --no-source-map --load-path=node_modules Done in 3.45s. (省略) Asset precompilation completed (32.99s) Cleaning assets Running: rake assets:clean -----> Detecting rails configuration [Discovering process types] Procfile declares types -> web, release ===> EXPORTING Adding layer 'heroku/ruby:profile' Adding layer 'buildpacksio/lifecycle:launch.sbom' Adding 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' Setting default process type 'web' Saving イメージ名... *** Images (26cf6771ef02): イメージ名 Adding cache layer 'heroku/ruby:shim' Successfully built image イメージ名
builderで指定するのは以下で公開されているものからheroku/buildpacks:20
を指定しました。
ドキュメントによると、pack builder suggest
で候補を得られるようです。
起動
これでイメージが作成されたので、起動します。
$ $ docker run --rm -p 8080:8080 my_rails_app:1.0.0 Puma starting in single mode... * Puma version: 5.6.5 (ruby 3.2.1-p31) ("Birdie's Version") * Min threads: 5 * Max threads: 5 * Environment: production * PID: 1
無事起動しました。
docker ps
で見てみます。無事起動していることが確認できます。
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES コンテナID イメージ名 "/cnb/process/web" 26 seconds ago Up 25 seconds 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp goofy_matsumoto
db:migrate
db:migrate
をどうやって実行しようかと思いましたが、こんな感じで起動しているコンテナ内でrelease
を実行させることで実現しました。今回、データベースはSQLite3にしているので、コンテナ内でコマンドを実行する必要がありました。
$ docker exec -it コンテナID /cnb/process/release
SQLite3以外の場合は、docker run
でentrypoint
オプションを指定してあげるとよさそうです。
具体的には、docker run --entrypoint release イメージ名
としてあげると良いようです。