⚠️

Ruby 3.1 から 3.2 へのアップグレード時のトラブルと対応策

に公開

Rubyバージョンアップ

# rbenvとruby-buildをアップグレードして、インストール可能なRubyのバージョン一覧を最新の状態に更新
$ brew upgrade rbenv ruby-build

# 利用可能なRubyのバージョンを確認
$ rbenv install --list

# rubyのインストール
$ rbenv install 3.2.6
.ruby-version
- ruby-3.1.0
+ ruby-3.2.6
Gemfile
- ruby '3.1.0'
+ ruby '3.2.6'
$ bundle install

動作確認

$ bin/webpack-dev-server
$ rails s
$ rails c
$ rubocop
$ brakeman
$ rspec

プロジェクトで Ruby 3.1.0 から 3.2.6 へアップデートした際に、Docker や CircleCI でいくつかの問題が発生しました。以下にそれらの問題と解決策についてまとめます。

環境

Ruby: 3.1.0 → 3.2.6
Docker: Alpine ベースのコンテナを使用
CI: CircleCI (cimg/ruby)
Node.js: Webpacker の互換性のために 16.x を利用

1.Dockerfile の修正

発生した問題

Dockerfile の FROM を以下のように変更しました。

Dockerfile
- FROM ruby:3.1.0-alpine3.15 as build_base
+ FROM ruby:3.2.6-alpine as build_base

この変更後、ビルド時に以下のエラーが発生しました。

1.884 ERROR: unable to select packages:
1.905   imagemagick6-dev (no such package):
1.905     required by: world[imagemagick6-dev]
------
failed to solve: process "/bin/sh -c apk update &&     apk --no-cache add         postgresql-client         tzdata         curl         make         gcc         g++         libxml2-dev         curl-dev         libc-dev         imagemagick6-dev         imagemagick         postgresql-dev         python3         yarn         shared-mime-info         build-base         libpq" did not complete successfully: exit code: 1
make: *** [build] Error 17

対応方法

原因は、Alpine Linux のリポジトリに imagemagick6-dev パッケージが存在しないためです。
そのため、利用可能な imagemagick-dev に変更しました。

Dockerfile
RUN apk --no-cache add \
  - imagemagick6-dev \
  + imagemagick-dev \
    imagemagick

2. Node.js のバージョン問題(Docker)

発生した問題

ruby:3.2.6-alpine をベースイメージにした場合、デフォルトで Node.js 18系 がインストールされます。しかし、プロジェクトでは Webpacker を使用しており、Node.js 16 系でないと動作しませんでした。

解決策

Alpine のリポジトリを明示的に指定し、Node.js 16 をインストールしました。

修正前(Node.js 18 が入ってしまう)

Dockerfile
RUN apk update && \
    apk --no-cache add nodejs

修正後(Node.js 16 を指定)

Dockerfile
RUN apk add --no-cache --repository \
    http://dl-cdn.alpinelinux.org/alpine/v3.16/main nodejs~=16

参考:Alpine Linuxのapkで旧バージョンパッケージをインストール

3. CircleCI の Webpacker エラー

発生した問題

CircleCI で cimg/ruby:3.2.6-browsers を使用したところ、デフォルトで Node.js 18 がインストールされてしまい、Webpacker のビルドが失敗しました。

# Webpacker::Manifest::MissingEntryError:
#   Webpacker can't find application.js in /home/circleci/workspace/public/packs-test/manifest.json. Possible causes:
#   1. You want to set webpacker.yml value of compile to true for your environment
#      unless you are using the `webpack -w` or the webpack-dev-server.
#   2. webpack has not yet re-run to reflect updates.
#   3. You have misconfigured Webpacker's config/webpacker.yml file.
#   4. Your webpack configuration is not creating a manifest.
#   Your manifest contains:

このエラーは、Node.js のバージョンが 18 になってしまったことで、Webpacker のビルドが正常に行われなかったためです。

解決策

CircleCI のジョブ内で、Node.js 16 をインストールし、バージョンを切り替えました。

修正前

.circleci/config.yml
executors:
  default:
    working_directory: ~/workspace
    docker:
      - image: cimg/ruby:3.2.6-browsers

修正後(任意のnode versionを指定してインストールしnvmを各ジョブで使用)

.circleci/config.yml
  set-node-version:
    steps:
      - run:
          name: Swap node versions to 16
          command: |
            set +e
            wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
            export NVM_DIR="$HOME/.nvm"
            [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
            [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"
            nvm install 16
            nvm alias default 16
            echo 'export NVM_DIR="$HOME/.nvm"' >> $BASH_ENV
            echo '[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"' >> $BASH_ENV

参考:CircleCIのruby imageで任意のnode versionを指定したい

まとめ

Ruby 3.1.0 -> 3.2.6へのアップデート時には、以下の問題が発生しました。

  1. ruby:3.1.0-alpine3.15 -> ruby:3.2.6-alpine でAlpineのimagemagick6-dev パッケージが存在しなくなり、imagemagick-dev に変更。

  2. ruby:3.2.6-alpine ではデフォルトで Node.js 18 がインストールされるため、Node.js 16 を明示的にインストール。

  3. CircleCIの cimg/ruby:3.2.6-browsers でも Node.js 18 がデフォルトになるため、ジョブ内で Node.js 16 をインストールし、バージョンを切り替え。

Discussion