🐙

GitLab Workhorse を使わないでみる

2023/05/25に公開

GitLab Workhorse を使わないでみる

GitLab Workhorse は基本的に Puma (GitLab) 用のリバースプロキシなんですが、実際のところ何やってるのかよくわかりません。詳しいことは Features that rely on Workhorse にあります。

ドキュメントをいろいろ見てると、Workhorse なしでも GitLab は動きそうに思えます。メインの機能が X-Sendfileヘッダー の処理みたいなので。

試しに Workhorse をなしで動作するか確認してみます。特に意味はないです。

Workhorse なしで構築してみる

とりあえず Omnibus GitLabインストールします。

GitLab Workhorse を無効化します。

/etc/gitlab/gitlab.rb
external_url 'http://gitlab.local'
gitlab_workhorse['enable'] = false

GitLab を再構築します。

$ gitlab-ctl reconfigure
$ curl -v http://gitlab.local > /dev/null
> GET / HTTP/1.1
> Host: gitlab.local

...

< HTTP/1.1 502 Bad Gateway
< Server: nginx

ですよねー? みたいな。

Omnibus GitLab では Workhorse を無効化してもよろしく設定してくれないみたいです。

Puma (GitLab Rails) に Workhorse のふりをさせる

nginx が Workhorse に接続しようとして失敗しています。

/var/opt/gitlab/nginx/conf/nginx.conf
...

  upstream gitlab-workhorse {
    server unix:/var/opt/gitlab/gitlab-workhorse/sockets/socket;
  }
  
...

nginx の接続先を Puma (GitLab Rails) に設定してもいいんですが、Workhorse にアクセスするコンポーネントって nginx だけじゃないんですよね。Gitaly とかもです。それぞれの接続先を Puma (GitLab Rails) に書き換えて回るのは面倒なので、シンボリックリンクを使います。

$ sudo mkdir -p /var/opt/gitlab/gitlab-workhorse/sockets
$ sudo ln -s /var/opt/gitlab/gitlab-rails/sockets/gitlab.socket /var/opt/gitlab/gitlab-workhorse/sockets/socket
$ curl -v http://gitlab.local > /dev/null 

...

> GET / HTTP/1.1
> Host: gitlab.local

...

< HTTP/1.1 302 Found
< Server: nginx
< Date: Thu, 25 May 2023 03:43:25 GMT
< Content-Type: text/html; charset=utf-8
< Transfer-Encoding: chunked
< Connection: keep-alive
< X-Frame-Options: SAMEORIGIN
< X-XSS-Protection: 1; mode=block
< X-Content-Type-Options: nosniff
< X-Download-Options: noopen
< X-Permitted-Cross-Domain-Policies: none
< Permissions-Policy: interest-cohort=()
< X-UA-Compatible: IE=edge
< Location: http://gitlab.local/users/sign_in

今度はうまくいきました。

けど、ブラウザーで表示してもなんか変です。

nginx にページ表示用アセットを返させる

GitLab Workhorse のお仕事の一つに、GitLab のページを表示するための JavaScript や CSS などの静的ファイルを公開するというのがあります。なのでページが変な感じになるわけですね。

nginx でアセットを返すようにしてやればいいわけです。

次のように nginx の設定を書き換えます。(本来は直接書き換えてはいけないんですが、実験なので OK です)

--- /var/opt/gitlab/nginx/conf/gitlab-http.conf.backup  2023-05-25 12:48:39.529150977 +0900
+++ /var/opt/gitlab/nginx/conf/gitlab-http.conf 2023-05-25 12:51:13.885873608 +0900
@@ -127,7 +127,7 @@
   location /assets {
     add_header X-Content-Type-Options nosniff;
     proxy_cache gitlab;
-    proxy_pass  http://gitlab-workhorse;
+    root /opt/gitlab/embedded/service/gitlab-rails/public;
   }

   error_page 404 /404.html;

nginx を再起動します。

$ sudo gitlab-ctl restart nginx

無事表示されました!

使ってみる

ユーザーを作ってみたりプロジェクトを作ってみたり。とりあえずは問題なさそうです。って、基本的には Workhorse はリバースプロキシなので...

Workhorse X-Sendfile ヘッダーに介入します。なのでイシューの添付ファイルなどは Workhorse なしでは動作しないかもしれません。試してみます。

問題なさげです。

続いて git clone です。作成済みのパブリックプロジェクトで試します。

$ git clone http://gitlab.local/masakura/sample.git
Cloning into 'sample'...
remote: Nil JSON web token
fatal: unable to access 'http://gitlab.local/masakura/sample.git/': The requested URL returned error: 403

失敗しました... ログにもなんか残ってます...

production_json.log
{"method":"GET","path":"/masakura/sample.git/info/refs","format":"*/*","controller":"Repositories::GitHttpController","action":"info_refs","status":403,"time":"2023-05-25T04:13:28.818Z","params":[{"key":"service","value":"git-upload-pack"},{"key":"repository_path","value":"masakura/sample.git"}],

公式ドキュメントの Web Request (Git) を見る限り、info/refs?... は Puma (GitLab Rails) に通りそうなもんなのですが、403 になります。そのあとの Gitaly へのリクエストは Workhorse がないから失敗しそうですが...

ここまで!

本日はここまで。

  • GitLab Workhorse は X-Sendfile ヘッダーを利用して GitLab システム全体のパフォーマンスを向上させます。ないならないでも動作します。
  • GitLab のページを構成する静的 JavaScript / CSS ファイルなどは nginx に任せればいいです。
  • git clone は失敗しました。

って感じです。知ってても役に立ちません。

時間切れで調べられなかったものです。気が向けばそのうち頑張るかもしれません。

  • GitLab Workhorse が info/refs?... リクエストにちょっとだけ介入しているみたいです。パケットキャプチャーをして調べてみたいです。
  • X-Sendfile は nginx でもできるので、そっちでも動かしてみたいです。

以上!

Discussion