Gitlab Omnibus:如何使用捆绑的 nginx 重写 URL

Gitlab Omnibus: how to rewrite URLs with bundled nginx

当前配置

我将 GitLab 迁移到了新服务器。作为迁移的一部分,一些存储库进行了重组。我们有一个网站直接链接到 GitLab 上的 rawblob 文件。对于这些 rawblob 文件,我想将所有 HTTPS 请求从旧 URL 重定向到新请求。

我使用 Gitlab Omnibus 包,捆绑了 nginx 安装。我基于这个问题的公认答案:, which in turn refers to the official GitLab documentation: https://docs.gitlab.com/omnibus/settings/nginx.html#inserting-custom-settings-into-the-nginx-config.

  1. 创建 nginx 配置目录,因为它还不存在:

    sudo mkdir -p /etc/nginx/conf.d/

  2. 创建 /etc/nginx/conf.d/redirect.conf:

.

server {
  server_name gitlab.itextsupport.com;
  rewrite ^\/itext7\/samples\/(blob|raw)\/master\/(?!samples\/)(.*)$ https://$server_name/itext7/samples//master/samples/ permanent;
}
  1. /etc/gitlab/gitlab.rb 处编辑配置文件以添加以下行:

    nginx['custom_nginx_config'] = "include /etc/nginx/conf.d/redirect.conf;"

  2. 重写nginx配置:

    sudo gitlab-ctl reconfigure

  3. 重新启动捆绑的 nginx:

    sudo gitlab-ctl restart nginx

  4. 验证捆绑的 nginx 是否包含重定向文件:

    sudo grep 'redirect.conf' /var/opt/gitlab/nginx/conf/nginx.conf

正在测试配置

curl -I https://gitlab.itextsupport.com/itext/tutorial/blob/master/signatures/src/main/java/signatures/chapter4/C4_05_SignWithBEID.java

预期结果

/samples/blob/master 之后插入。我希望看到 301 重写为 https://gitlab.itextsupport.com/itext/tutorial/blob/master/samples/signatures/src/main/java/signatures/chapter4/C4_05_SignWithBEID.java

实际结果

200 OK 未修改 URL.

丑陋的骇客

将此行添加到 /var/opt/gitlab/nginx/conf/gitlab-http.conf 并重新启动捆绑的 nginx:

rewrite ^\/itext7\/samples\/(blob|raw)\/master\/(?!samples\/)(.*)$ https://$server_name/itext7/samples//master/samples/ permanent;

通过这样做,我已经验证了我的实际重写规则本身是正确的。

缺点:每次 gitlab-ctl reconfigure 为 运行 时都会丢失此行。

问题

我需要更改什么才能使 URL 重写按预期工作?没有丑陋的黑客?

附加信息

当我 运行 sudo /opt/gitlab/embedded/sbin/nginx -p /var/opt/gitlab/nginx -T 时,我看到两个 server { } 块。到目前为止,我的工作理论是 nginx 只选择第一个服务器块,而忽略第二个。如果我能找到一种方法来合并两个服务器块,以一种与配置文件兼容的方式/etc/gitlab/gitlab.rb,那么我的问题很可能就解决了。

嗯,看起来 gitlab.rb 中的答案就在眼前。 nginx['custom_nginx_config']上面一行是nginx['custom_gitlab_server_config']。我将 include 语句放在那里,并删除了重写规则周围的 server {} 括号。 https://docs.gitlab.com/omnibus/settings/nginx.html#inserting-custom-nginx-settings-into-the-gitlab-server-block:

的 GitLab 文档中也对此进行了描述

This inserts the defined string into the end of the server block of /var/opt/gitlab/nginx/conf/gitlab-http.conf.

所以这就是我所做的:

  1. /etc/gitlab/gitlab.rb中,注释掉nginx['custom_nginx_config']行并添加:

    nginx['custom_gitlab_server_config'] = "include /etc/nginx/conf.d/redirect.conf;"

  2. /etc/nginx/conf.d/redirect.conf中,只保留重写行:

    rewrite ^\/itext7\/samples\/(blob|raw)\/master\/(?!samples\/)(.*)$ https://$server_name/itext7/samples//master/samples/ permanent;

  3. 重新配置 GitLab:

    sudo gitlab-ctl reconfigure

  4. 重启nginx:

    sudo gitlab-ctl restart nginx

  5. 验证 nginx 配置:

    sudo /opt/gitlab/embedded/sbin/nginx -p /var/opt/gitlab/nginx -T | tail -n 20

.

nginx: the configuration file /var/opt/gitlab/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /var/opt/gitlab/nginx/conf/nginx.conf test is successful

  include /etc/nginx/conf.d/redirect.conf;
}

# configuration file /etc/nginx/conf.d/redirect.conf:
rewrite ^\/itext7\/samples\/(blob|raw)\/master\/(?!samples\/)(.*)$ https://$server_name/itext7/samples//master/samples/ permanent;

# configuration file /var/opt/gitlab/nginx/conf/nginx-status.conf:
server  {
    listen 127.0.0.1:8060;
    server_name localhost;
    location /nginx_status {
      stub_status on;
      server_tokens off;
      access_log off;
      allow 127.0.0.1;
      deny all;
    }
}
  1. 验证 URL 重写:

    curl -I https://gitlab.itextsupport.com/itext/tutorial/blob/master/signatures/src/main/java/signatures/chapter4/C4_05_SignWithBEID.java

.

HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Thu, 27 Sep 2018 11:32:23 GMT
Content-Type: text/html
Content-Length: 178
Connection: keep-alive
Location: https://gitlab.itextsupport.com/itext/tutorial/blob/master/samples/signatures/src/main/java/signatures/chapter4/C4_05_SignWithBEID.java
Strict-Transport-Security: max-age=31536000

有一件事我还很好奇:

  • rewrite 行结束于 server{} 块之外。
  • rewrite 行使用了 $server_name 变量。
  • $server_name 变量定义在 内部 server{} 块中。

是否因为 nginx -T 以奇怪的方式显示包含的语句而造成视觉上的混淆? rewrite 行真的 位于 server{} 块的 内部,即使它看起来是 外部 吗?为什么事情往往不像看起来的那样,为什么 GitLab 文档是用一种封闭的语言编写的?唉,这些思考可能永远没有答案。