電通総研 テックブログ

電通総研が運営する技術ブログ

「Git LFS × AWS S3」で大容量ファイルを構成管理する

こんにちは、ISID 金融ソリューション事業部の孫です。
皆さんはGitでソースコードの構成管理を行う中で、バイナリファイルのサイズが大きすぎてGitHubなどのホスティングサービスからブロックされたりした経験はないでしょうか。
実は、最近UnrealEngineを使ってゲームを開発しているところで、そうした大容量ファイルの管理問題に直面しました。
こういう問題を解決するために、Git LFS というアップローチがあります。
今回の記事では、Amazon S3(以下 S3)を用いて独自のGit LFSサーバを建てる方法を紹介します。
※構成イメージは以下の図をご参照ください。

Git LFSとは

GitHub でのサイズ制限によってGitHubでは100MBを超えるファイルをブロックします。
サイズ制限を解消するため、大容量ファイルを効率的に扱う「Git LFS」が利用されます。
Git LFSを利用することで、レポジトリではハッシュのみを管理し、データ自体は別のストレージ(上記図のAmazon S3)で管理することなどが可能になります。

GitHubでGit LFSを使う場合の選択肢

GitHubでは、公式サービスとしてGitHub LFSが提供されています。
しかし、GitHubが提供しているLFSサーバーは無料枠でアカウントごとに2GBまで使用することが可能であるものの、それを超えて使用する場合には「data pack」を購入する必要があります。
コストを削減したい為、GitHub LFSをS3に切り替えることにしました。
S3ベースのGit LFSサーバーの構築にあたり、いくつかOpenSourceがありますが、今回は構築の利便性および導入後の運用性を考慮した上でRudolfsを選定しました。
以下は当初検討になった各OpenSourceです。

  • lfs-test-server
    • S3と連携する仕組みがない為却下
  • LFS2S3Proxy
    • 個人の製品ですからセキュリティおよび今後のアップデートを考慮した上で却下
  • meltingice/Git LFS S3
    • Rubyで開発した製品ですが、チーム内にRubyに詳しいメンバーがいない為却下
  • Rudolfs
    • ★S3をバックエンドとして利用可能、かつDocker化されており運用もしやすい為採用★

実施手順

以下の流れで、Rudolfsを用いてGit LFSサーバーを構築します。

  1. 事前準備
  2. Rudolfsのセットアップ
  3. 検証リソースの準備
  4. 動作確認

1.事前準備

  • Dockerをセットアップします
    • 以下のドキュメントに沿ってDocker Desktopをインストールします
    • Docker Composeのインストールを確認します
      • コマンド docker compose version でバージョンが表示されればOKです
      • 一般的にDocker Desktopのインストールパッケージに含まれるはずですが、もし一部のlinuxパーケージになければ、こちらに沿ってDocker Composeプラグインをインストールします
    • その他、Dockerの使い方についての説明は割愛します
  • 「git lfs」コマンドプライグインをインストールします
  • AWSアカウントがない場合、作成する必要があります
    • 今なら1年間無料でAmazon EC2やS3を利用できるため、無料枠で大丈夫です
  • AWSコンソールからアクセスキーを作成します
  • AWSコンソールからS3バケットを作成します

2.Rudolfsのセットアップ

基本はRudolfsリポジトリReadmeを参考にしてセットアップを行います。

  • Rudolfsのソースコードをダウンロードします
    • 以下のコマンドでソースコードをクローンします
    • git clone https://github.com/jasonwhite/rudolfs.git
  • Rudolfsで利用する暗号化キーを生成します
    • openssl rand -hex 32 コマンドで生成します
  • ダウンロードしたRudolfsフォルダに移動して新規に .env ファイルを作成します
  • 事前準備で作成したAWSアクセスキー、暗号化キーとS3バケット名を埋め込んで .env ファイルに書きます
    AWS_ACCESS_KEY_ID=「AWSアクセスキーID」
    AWS_SECRET_ACCESS_KEY=「AWSアクセスキー」
    AWS_DEFAULT_REGION=「AWSリージョン名」
    LFS_ENCRYPTION_KEY=「Rudolfsの暗号化キー」
    LFS_S3_BUCKET=「作成したbucket名」
    LFS_MAX_CACHE_SIZE=10GB
  • 以下のコマンドを叩いてRudolfsコンテナを起動します
docker-compose --env-file .env up -d
  • コンテナの起動ステータスを確認します
    • docker compose ps を叩きます
    • 「STATUS」は running で表示することを確認します

3.検証リソースの準備

  • テストリポジトリをクローンします
    • git clone リポジトリのURL
  • test-lfsフォルダに移動し .lfsconfig ファイルを作成します
    • 以下の規則に沿ってLFSサーバのURLを定義します

  • git のglobal settingを設定します
    • Readmeでパフォーマンスに関するおすすめ設定です
    • 今回はこの設定によってどの程度の効果が発揮できるまでは検証していません
# Increase the number of worker threads
git config --global lfs.concurrenttransfers 64

# Use a global LFS cache to make re-cloning faster
git config --global lfs.storage ~/.cache/lfs
  • .gitattributes を作成し、該当のLFSファイルを定義します
    • 今回のテストファイルの拡張子は .test にしました
*.test filter=lfs diff=lfs merge=lfs -text
  • テストファイルを作成します
    • GitHubは100MBを超えるファイルをブロックします
    • 大容量ファイルを認識させるため、120MBのテストファイルを作成します
# MAC OSコマンド
$ mkfile -n 120m bigdata1.test

# Linux OSコマンド
$ dd if=/dev/zero of=bigdata1.test bs=1M count=120

# Window OSコマンド
$ fsutil file createnew "bigdata1.test" 125829120

4.動作確認

  • Push前にS3バケットを確認します

    • 何もオブジェクトがないことを確認します
  • Git LFSを使用しない場合のエラーを確認します

    • 先ほど作成した大容量テストファイルをPushします
    • Git LFSを使用しない場合、前述GitHubでのサイズ制限でエラーになることを確認します
# 大容量ファイルをgitに追加してコミットします
$ git add -A
$ git commit -m "test rudolfs s3 bigdata1"

# GitHubへのPushでファイルサイズの超過エラーが発生します
$ git push origin main

------エラー情報の抜粋--------
remote: error: Trace: 9256fd02811ab3b1e6f389b62f285e730ea5d39cbff2226baefcd80261028e5b
remote: error: See https://gh.io/lfs for more information.
★ remote: error: File bigdata1.test is 120.00 MB; this exceeds GitHub's file size limit of 100.00 MB ★
remote: error: GH001: Large files detected. You may want to try Git Large File Storage - https://git-lfs.github.com.
---------------------------
  • Git LFSを初期化します

    • git lfs install
  • 再度大容量テストファイルをPushします

    • Git LFSを使用する場合、Pushが問題なく完了することを確認します
$ git push origin main

ここまで、今回の構成に対する動作確認は完了しました!

おわりに

というわけで、今回はRudolfs+S3を導入することによって大容量ファイルの構成管理ができて、またリポジトリのサイズが抑えられました。
またチームで開発する場合は、Rudolfsの暗号キーさえチームメンバー内で一致していれば、各メンバーのS3権限を待たせる運用で進められます。
ただし、暗号キー自体は全てのメンバーに配布する都合で、セキュリティ観点で考慮する必要があります。
本記事ではセキュリティの側面について深掘りしないですが、もう少しセキュアな運用にしたい場合、一つの案として暗号キーの共有ではなくて安全なプライベートネットワーク内にRudolfsコンテナを一つ建て共有するアップローチがあります。
今回の構成は特にAWSプロジェクトにおいてコストを抑えたい方に向いています。LFSで大容量ファイルを管理した上で、リポジトリのCloneやPull、Pushなどの速度が早くなり開発の効率化を図ることができます!

現在ISIDはweb3領域のグループ横断組織を立ち上げ、Web3およびメタバース領域のR&Dを行っております(カテゴリー「3DCG」の記事はこちら)。
もし本領域にご興味のある方や、一緒にチャレンジしていきたい方は、ぜひお気軽にご連絡ください!
私たちと同じチームで働いてくれる仲間を、是非お待ちしております!
ISID採用ページ(Web3/メタバース/AI)

参考

執筆:@chen.sun@kase.teruyoshi、レビュー:@yamashita.yuki
Shodoで執筆されました