discourse_docker における shallow git fetch のリグレッション

こんにちは、

docker_discourse の最近のコミットにより、app.ymlversion: 値にタグ(例:v2.6.0)を指定する機能が壊れています。これは、テスト目的などで Discourse の古いバージョンをインストールする際に役立ちます。

e2eb085714dfcf2aa0117b0f2fdf39b762b0e18d を使用して version: v2.6.0 を指定すると、以下のような問題が発生します。

I, [2020-12-05T10:59:38.848743 #1]  INFO -- : > cd /var/www/discourse && git remote set-branches origin v2.6.0
I, [2020-12-05T10:59:38.852600 #1]  INFO -- : 
I, [2020-12-05T10:59:38.852639 #1]  INFO -- : > cd /var/www/discourse && git fetch --depth 1 origin v2.6.0
From https://github.com/discourse/discourse
 * tag                 v2.6.0     -> FETCH_HEAD
I, [2020-12-05T10:59:41.405163 #1]  INFO -- : 
I, [2020-12-05T10:59:41.405307 #1]  INFO -- : > cd /var/www/discourse && git checkout v2.6.0
error: pathspec 'v2.6.0' did not match any file(s) known to git
I, [2020-12-05T10:59:41.411796 #1]  INFO -- : 

その直前のコミットを使用した場合の期待される出力の代わりに、上記のようなエラーが表示されます。

I, [2020-12-05T11:22:14.717910 #1]  INFO -- : > cd /var/www/discourse && git fetch origin v2.6.0
From https://github.com/discourse/discourse
 * tag                     v2.6.0     -> FETCH_HEAD
I, [2020-12-05T11:22:15.672616 #1]  INFO -- : 
I, [2020-12-05T11:22:15.672683 #1]  INFO -- : > cd /var/www/discourse && git checkout v2.6.0
Note: checking out 'v2.6.0'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b <new-branch-name>

HEAD is now at d6121249d3 Version bump to v2.6.0
「いいね!」 7

これは厳密にはバグとは言えませんが、Discourse の古いバージョンをインストールする方法について、より複雑なテンプレートを使用する場合でも、何らかの手順を提供したいと考えています。

@Falco が調査中です。

「いいね!」 7

depth を設定可能にするには賛成です。おそらく環境変数を通じて、「shallow」をデフォルト値としつつ、単純な環境変数で設定できるようにするのがよいでしょう。

「いいね!」 1

ここでの問題は、チェックアウト時にタグがローカルに存在しないことだと思います。以下(Discourse 関連ではない)の issue と同様です:

git fetch --all を実行すれば問題は解決するはずですが、画像サイズがどの程度増えるかはわかりません(後で未使用の参照を削除する別の指示がある場合を除きます)。

とはいえ、git clone --depth 1 https://github.com/discourse/discourse.git --branch=$version で解決できると思います。--branch オプションはブランチとタグの両方を指定できるためです。ただし、私はテストしていないため、現在 master ブランチを使用している理由があるかどうかはわかりません。

git clone --depth 1 https://github.com/discourse/discourse.git --branch=v2.6.0 を実行すると、フォルダ全体のサイズは 212MB、その中の .git フォルダは 46MB でした。したがって、問題ないと思います。

リポジトリサイズが倍になりますね :slightly_frowning_face:

問題は、イメージビルド時に将来どのブランチを使用したいかがわからないことです。

現在の設定はイメージサイズを小さくするために変更されました。その結果、圧縮後のイメージサイズが 250MB(25%)削減され、これは大きな成果です。stable や beta、tests-passed などの通常のブランチを使用する場合は問題なく動作します。

回避策として、タグに切り替えたい場合は、app.yml ファイルに以下を適用してください。

hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone https://github.com/discourse/docker_manager.git
+    - exec:
+        cd: $home
+        cmd:
+          - git fetch --depth=1 origin tag v2.5.0 --no-tags
+          - git checkout v2.5.0

もう一つの回避策は、app.yml の最上位に base_image キーを追加し、古いベースイメージの値を設定することです。新しいイメージが古い Discourse バージョンを実行できるかどうかの互換性を維持しようとしていないため、かなり古いバージョンに戻す必要がある場合はこれが必須になる可能性があります。

「いいね!」 9

その通りですね。その時点ではバージョンが不明です。ベースイメージは「current version + tests-passed ブランチ」を使用しているようですが、そのブランチにはイメージがビルドされた時点のコミットが含まれます。

現在のやり方では、tests-passed ブランチを使用していたとしても、再ビルドが遅くなることはないでしょうか?

以下の手順を考慮してみてください:

ベースイメージ内:

git clone --depth 1 https://github.com/discourse/discourse.git
cd discourse/
git remote set-branches --add origin tests-passed

web.template.yml 内:

git reset --hard
git clean -f
git remote set-branches --add origin master
git pull
...

git pull が実行されると、リポジトリ全体がプルされ、数分かかる可能性があります。これは以前に浅いクローン(shallow clone)しか行っていなかったためです。実際に上記の手順だけをローカルで実行して確認してみてください。

ベースイメージにリポジトリ全体を含めることが良いとは言っていませんが、web.template.yml のコードは、app.yml でプラグインが追加されただけや設定が変更されただけであっても、すべての再ビルドで実行されます。私が(Discourse 以外の)プロジェクトで行っているのは、新しいバージョンごとに新しいイメージを作成することですが、現在の運用方法から考えると、それが現実的ではないかもしれません。

再ビルド時間の増加に気づいていませんか?(あるいは、総再ビルド時間と比較してそれほど大きくないのかもしれません)

更新

上記の手順を再度テストしましたが、高速でした。おそらく 1 回目に別のコマンドを実行して git ツリーが変更され、その結果 git pull を実行した際にすべてをプルしようとしていたのでしょう。

「いいね!」 2

本当にそうでしょうか?

➜  discoursesmall git:(6a42acbf) docker run --rm -it discourse/base:2.0.20201125-2246
root@b481d11669ba:/# cd /var/www/discourse/
root@b481d11669ba:/var/www/discourse# du -sh .                                                     
774M    . 
root@b481d11669ba:/var/www/discourse# git pull
...
root@b481d11669ba:/var/www/discourse# du -sh .                                                               
778M    . 
「いいね!」 5

@lucasbasquerotto ご指摘の通り、git pull は厳密には不要でしたので、こちら で削除しました。

これにより、今後他のブランチ(またはフォーク)が discourse_docker とよりスムーズに連携できるようになります :slight_smile:

「いいね!」 5

はい、プル後に正しいブランチでフェッチとチェックアウトが行われているようですので、git pull は不要だと考えられます(まだテストはしていませんが)。

タグについては、個別にフェッチする必要があるようですが、それも可能そうです。さらに、ブランチの方が一般的に使用されるため、タグは特殊なケースに該当するでしょう。

「いいね!」 1

構成ファイル standalone.yml の version オプションが効果を持たない、と仮定しても安全でしょうか?

依然として効果がありますが、現在はブランチに対してのみ設定できます。

「いいね!」 3

同じエラーが発生しています。私はバージョン 2.5.1 を使用していました。

これにより、以下のエラーが表示されます。

I, [2020-12-31T11:50:24.701475 #1]  INFO -- : > cd /var/www/discourse && find /var/www/discourse ! -user discourse -exec chown discourse {} \+
chown: cannot dereference '/var/www/discourse/public/plugins/styleguide': No such file or directory

ビルドが実行されません。何か助言はありますか?

上記のキーを追加し、discourse/base - Docker Image から古いイメージを使用してみてください。

「いいね!」 2

これは機能しません。なぜなら、これはバージョンを取得できないために失敗するコードに実行されるからです。機能したのは、web.template.yml の隣に以下の内容を持つ version.template.yml を作成することでした。

params:
  home: /var/www/discourse

run:
  - exec:
      cd: $home
      hook: code
      cmd:
        - git fetch --tags

その後、このファイルを containers/app.ymlweb.template.yml の前に含めます。

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/version.template.yml"
  - "templates/web.template.yml"

それを機能させるには、app.yml の version 上位キーを使用せず、その新しいコードのみを使用してください。そうすれば失敗しません。

「いいね!」 3

ありがとうございます、明確にしてくれて助かりました。私が以前混乱していたのと同じように迷っている方のために、Discourse のリリースタグを取得する方法は以下の通りです。

  • app.yml 内の version パラメータが設定されていないことを確認してください。例えば:
    params:
      db_default_text_search_config: "pg_catalog.english"
      #  version: stable
    
  • app.yml の末尾に、目的のバージョンをチェックアウトするコードを追加してください。例えば:
    hooks:
      after_code:
        - exec:
            cd: $home/plugins
            cmd:
              - git clone https://github.com/discourse/docker_manager.git
    +    - exec:
    +        cd: $home
    +        cmd:
    +          - git fetch --depth=1 origin tag v2.5.0 --no-tags
    +          - git checkout v2.5.0
    

./launcher rebuild app を実行すると、以下のように動作します。

  • デフォルトの version(つまり test_passed ブランチ)がチェックアウトされます。
  • v2.5.0 タグがフェッチされ、チェックアウトされることで、以前のバージョンが実質的に置き換えられます。
「いいね!」 1

This topic was automatically closed 0 minutes after the last reply. New replies are no longer allowed.