ユーザ用ツール

サイト用ツール


freebsd:freebsd_に_redmine_を構築したらハマった話

FreeBSD に redmine を構築したらハマった話

要点

* Rubygem の管理が ports/pkg と絶望的なまでに相性が悪い。ports を利用し、かつ下記の改修を行なってからインストールする必要がある。

  • Makefile は以下の修正をする。
    • rubygem-bundler 以外の依存関係を全部削る。
      • ただし、web server と連携させる場合(つまり THIN オプションを設定しない場合)、rubygem-passenger への依存関係はむしろ足しておいた方がいい。
    • do-install」ターゲットで行なっている「bundler.d」ディレクトリの作成は、${STAGEDIR}${WWWDIR}/bundler.d${WWWDIR}/bundler.d の両方を作成するよう修正する。
      • 次項の注意書きも参照。
    • do-install-〜-on」ターゲットでのファイルコピーは、${STAGEDIR}${WWWDIR}/bundler.d${WWWDIR}/bundler.d に格納する。
      • ${STAGEDIR}${WWWDIR}/bundler.d にコピーしないと、build 中に ${STAGEDIR} 内で行なわれる操作で不都合が発生する。
        かといって、それだけだとインストール完了後に正常に動作しないため、${WWWDIR}/bundler.d にもコピーしておく必要がある。
        下で述べる「post-install」ターゲットが最終的なインストール先である ${WWWDIR} 以下にファイルをコピーしてから実行されればこんなことは起きないんだが、なぜか「${STAGEDIR}{$WWWDIR} へのインストール後」に実行されるので、こんな有様に。
        ターゲット名が実行タイミングと合ってないわけなんだが、どうしてこうなった……
        まあ、次の処理と併せて、pkg-post-install スクリプト書けばいい気もするんだよ? うん、嘘かもしれないけど? みたいな?
    • post-install」ターゲットでは、以下の処理を行なうようにする。
      (cd ${WWWDIR} && bundle config set --local path 'vendor/bundle')
      (cd ${WWWDIR} && bundle config set --local without 'development test')
      (cd ${WWWDIR} && ${CP} ${STAGEDIR}${WWWDIR}/Gemfile .)
      (cd ${WWWDIR} && ${RM} Gemfile.lock && bundle install)
  • files/patch-Gemfile は削除する。

* プラグインのインストール時は、プラグインを git clone したあと、/usr/local/www/redmine/ で以下のコマンドを実行する1)

bundle update
bundle exec rake redmine:plugins:migrate RAILS_ENV=production
  • ぐーぐる様にお伺いを立てると「bundle exec rake db:migrate RAILS_ENV=production を実行しろ」という記述も散見されるが、この情報は古い。これを実行すると、必要な処理が行われない場合がある。
    • 例えば、redmine_messenger をインストールする際にこれを使ってしまうと、DB に必要なテーブル(messenger_settings)が作られず、プロジェクトの設定画面を出そうとすると Internal Error が発生するようになる2)

なお、'24/3/6 現在、「Ruby はデフォルトが 3.2 へ移行したが、redmine の port は Ruby 3.2 非対応の 5.0 系のものしか存在しない(ため、BROKEN とマークされている)」という状態になっている。そこで、Ruby を 3.2 にした上で上記の方法を使って redmine 5.1.1 のインストールができないか試したが、「A formatter class is required (RuntimeError)」とかいうなぞのエラーが発生して起動しなかった。ぐぬぬ。

ports collection と ruby gems の相性が悪い理由

Ruby を使用したアプリケーションでは、必要な ruby gem を Gemfile に記述するようになっている。その際、当然それらは「あればいい」というものばかりではないので必要とするバージョンも指定されるようになっているのだが、「あるバージョンより新しければいい」というものばかりではなく、「新しすぎてはダメ」だったり「ドンピシャで同じでなければダメ」というものもある。これらの要求はアプリケーションごとに異なるので、システムに共通なものとは別に、「そのアプリケーションの動作に必要なもの(バージョン)」を手元にかき集めておく仕組みが用意されている。

一方、ports collection で管理されている rubygem は、基本的に時間経過とともに(通常は最新版を追う形で)バージョンが上がって行ってしまう。これは「そのシステムで共通のセット」を維持する上で特定のアプリケーションにのみ着目するわけにはいかないので当然ではあるのだが、ここで齟齬が発生する。

上記の通り、アプリケーションが使用する rubygem は「新しければいい」というものではない。それなのに ports collection で管理される rubygem は問答無用で更新されて行ってしまうので、上述の Gemfile も「あるバージョン以降であれば許容する」というように書き換えざるを得ない。その結果、インストールした時点(もっと言えば ports の Makefile が書かれた時点)では動作していたものが ports/pkg の更新によって動かなくなったり、Makefile が書かれてからある程度経ってしまうとアプリケーション側が更新されない限りインストールしても動作しなかったりする。増してや、Gemfile で本来行なわれていた「gem を新しくし過ぎないようにする」制限が取り払われてしまうので、「せっかく(たまたま)うまく動く環境が出来上がっていたのに、うっかり bundle update を叩くと、その瞬間にアプリがぶっ壊れる」という事態すら発生する。

まあ、結論としては、「ruby gems に関しては、元々 ruby が持っているパッケージ管理の仕組みにお任せしておくのがいいんじゃないかな……」ということ。

1)
FreeBSD の場合は root で。その代わり、 Apache を再起動する前に chmod -R www:www /usr/local/www/redmine を実行しておこう。
2)
DB のログを見てると「relation "messenger_settings" does not exist」というエラーが出てたりする。
freebsd/freebsd_に_redmine_を構築したらハマった話.txt ? 最終更新: 2024/04/01 18:39 by a-gota