GitLabのファイルストレージ
ファイルのアップロード、保存、取得にはCarrierWavegemを使っています。
ファイルのアップロードはWorkhorseによって高速化されるはずです。詳細はアップロードの開発ドキュメントを参照してください。
ファイルアップロードが使用される場所は、コンテキストによって様々です:
- システム
- インスタンスロゴ (サインイン/サインアップ ページで表示されるロゴ)
- ヘッダーロゴ(ナビゲーションバーに表示されるロゴ)
 
- グループ
- グループアバター
 
- ユーザー
- ユーザーアバター
- ユーザースニペット添付ファイル
 
- プロジェクト
- プロジェクトアバター
- イシュー/MR/ノート Markdown添付ファイル
- イシュー/MR/ノート レガシー Markdown添付ファイル
- CIアーティファクト(アーカイブ、メタデータ、トレース)
- LFS オブジェクト
- マージリクエストの差分
- デザイン管理デザインのサムネイル
 
- トピック
- トピックアバター
 
ディスクストレージ
GitLabはすべてをローカルディスクに保存するようになりました。ディレクトリの場所は以前のバージョンと変わりましたが、まだ100%標準化されているわけではありません。下記をご覧ください:
| 説明 | DBで? | 相対パス(CarrierWave.rootから) | アップローダクラス | モデルタイプ | 
|---|---|---|---|---|
| インスタンスロゴ | yes | uploads/-/system/appearance/logo/:id/:filename | AttachmentUploader | 外観 | 
| ヘッダーロゴ | yes | uploads/-/system/appearance/header_logo/:id/:filename | AttachmentUploader | 外観 | 
| グループアバター | yes | uploads/-/system/group/avatar/:id/:filename | AvatarUploader | グループ | 
| ユーザーアバター | yes | uploads/-/system/user/avatar/:id/:filename | AvatarUploader | ユーザー | 
| ユーザースニペット添付ファイル | yes | uploads/-/system/personal_snippet/:id/:random_hex/:filename | PersonalFileUploader | スニペット | 
| プロジェクトアバター | yes | uploads/-/system/project/avatar/:id/:filename | AvatarUploader | プロジェクト | 
| トピックアバター | yes | uploads/-/system/projects/topic/avatar/:id/:filename | AvatarUploader | トピック | 
| イシュー/MR/ノート Markdown添付ファイル | yes | uploads/:project_path_with_namespace/:random_hex/:filename | FileUploader | プロジェクト | 
| イシュー/MR/ノート レガシー Markdown添付ファイル | いいえ | uploads/-/system/note/attachment/:id/:filename | AttachmentUploader | ノート | 
| デザイン管理デザインのサムネイル | yes | uploads/-/system/design_management/action/image_v432x230/:id/:filename | DesignManagement::DesignV432x230Uploader | デザインマネジメント::アクション | 
| CIアーティファクト(CE) | yes | shared/artifacts/:disk_hash[0..1]/:disk_hash[2..3]/:disk_hash/:year_:month_:date/:job_id/:job_artifact_id(:disk_hashはproject_idの SHA256 ダイジェスト ) | JobArtifactUploader | Ci::JobArtifact | 
| LFS オブジェクト(CE) | yes | shared/lfs-objects/:hex/:hex/:object_hash | LfsObjectUploader | LfsObject | 
| 外部マージリクエスト差分 | yes | shared/external-diffs/merge_request_diffs/mr-:parent_id/diff-:id | ExternalDiffUploader | マージ要求差分 | 
| 発行可能なメトリクスイメージ | yes | uploads/-/system/issuable_metric_image/file/:id/:filename | IssuableMetricImageUploader | 発行可能メトリック画像 | 
CIアーティファクトとLFSオブジェクトは、CEとEEで動作が異なります。CEではGitlabUploader 、EEではObjectStorage を継承し、S3 API互換のオブジェクトストアにファイルを格納します。
イシュー/MR/ノートのMarkdown添付ファイルの場合、ハッシュストレージレイアウトを使用する異なるアプローチがあります。プロジェクトが新しいアプローチ(10.2で導入)にマイグレーションする場合、パスを変更可能な変数:project_path_with_namespace 、代わりにプロジェクトIDのハッシュを使用することができます。
すべてのアップロードを一度にオブジェクトストレージにマイグレーションするオールインワンのRakeタスクを提供します。新しいUploaderクラスまたはモデルタイプが導入された場合、それに対応するRakeタスクの呼び出しをカテゴリリストに追加してください。
パスセグメント
ファイルは複数の場所に保存され、異なるパススキームを使用します。すべてのGitlabUploader 派生クラスは、このパスセグメントスキーマに従う必要があります:
|   GitlabUploader
| ----------------------- + ------------------------- + --------------------------------- + -------------------------------- |
| `<gitlab_root>/public/` | `uploads/-/system/`       | `user/avatar/:id/`                | `:filename`                      |
| ----------------------- + ------------------------- + --------------------------------- + -------------------------------- |
| `CarrierWave.root`      | `GitlabUploader.base_dir` | `GitlabUploader#dynamic_segment`  | `CarrierWave::Uploader#filename` |
|                         | `CarrierWave::Uploader#store_dir`                             |                                  |
|   FileUploader
| ----------------------- + ------------------------- + --------------------------------- + -------------------------------- |
| `<gitlab_root>/shared/` | `artifacts/`              | `:year_:month/:id`                | `:filename`                      |
| `<gitlab_root>/shared/` | `snippets/`               | `:secret/`                        | `:filename`                      |
| ----------------------- + ------------------------- + --------------------------------- + -------------------------------- |
| `CarrierWave.root`      | `GitlabUploader.base_dir` | `GitlabUploader#dynamic_segment`  | `CarrierWave::Uploader#filename` |
|                         | `CarrierWave::Uploader#store_dir`                             |                                  |
|                         |                           | `FileUploader#upload_path                                            |
|   ObjectStore::Concern (store = remote)
| ----------------------- + ------------------------- + ----------------------------------- + -------------------------------- |
| `<bucket_name>`         | <ignored>                 | `user/avatar/:id/`                  | `:filename`                      |
| ----------------------- + ------------------------- + ----------------------------------- + -------------------------------- |
| `#fog_dir`              | `GitlabUploader.base_dir` | `GitlabUploader#dynamic_segment`    | `CarrierWave::Uploader#filename` |
|                         |                           | `ObjectStorage::Concern#store_dir`  |                                  |
|                         |                           | `ObjectStorage::Concern#upload_path                                    |
RecordsUploads::Concern 関数は、GitlabUploader によって格納されたすべてのファイルに対してUpload エントリを作成し、GitlabUploader#dynamic_path を使用してパスの動的部分を永続化します。その後、Upload#build_uploader メソッドを使用してファイルを操作できます。
オブジェクトストレージ
GitlabUploader 派生クラスにObjectStorage::Concern を含めることで、このアップローダのオブジェクトストレージを有効にすることができます。アップローダでオブジェクトストレージを有効にするには、1)RecordsUpload::Concern をインクルードしてObjectStorage::Extension::RecordsUploads をプリペンドするか、2) アップローダをマウントして<mount>_store という名前の新しいフィールドを作成する必要があります。
CarrierWave::Uploader#store_dir 。
- 
GitlabUploader.base_dir+GitlabUploader.dynamic_segmentに上書きされます。
- 
GitlabUploader.dynamic_segmentストアが REMOTE の場合 (バケツ名が名前空間に使用されます)
テストの拡張ObjectStorage::Extension::RecordsUploads
RecordsUploads::Concern が含まれていない場合は、この懸念が含まれます。
ObjectStorage::Concern アップローダーは、Upload 正しいオブジェクトストアを選択するために Upload一致するものを検索します。各ストア (LOCAL/REMOTE) に対して#store_dirs + identifier Upload を Upload使用してマッピングされます。
class SongUploader < GitlabUploader
  include RecordsUploads::Concern
  include ObjectStorage::Concern
  prepend ObjectStorage::Extension::RecordsUploads
  ...
end
class Thing < ActiveRecord::Base
  mount :theme, SongUploader # we have a great theme song!
  ...
end
マウントされたアップローダーの使用
ObjectStorage::Concern はmodel.<mount>_store 属性をクエリして、正しいオブジェクトストアを選択します。このカラムはモデルスキーマに存在しなければなりません。
class SongUploader < GitlabUploader
  include ObjectStorage::Concern
  ...
end
class Thing < ActiveRecord::Base
  attr_reader :theme_store # this is an ActiveRecord attribute
  mount :theme, SongUploader # we have a great theme song!
  def theme_store
    super || ObjectStorage::Store::LOCAL
  end
  ...
end
