Amedee Van Gasse
Amedee Van Gasse

Reputation: 7644

Gitlab Omnibus: how to rewrite URLs with bundled nginx

Current configuration

I migrated my GitLab to a new server. As part of the migration, some repositories were reorganized. We have a website that links directly to raw and blob files on GitLab. I'd like to redirect all HTTPS requests from the old URLs to the new ones, for these raw and blob files.

I use Gitlab Omnibus package, with the bundled nginx install. I based myself on the accepted answer to this question: Gitlab Omnibus: how to redirect all requests to another domain, 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. Create nginx config directory, because it did not yet exist:

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

  2. Create /etc/nginx/conf.d/redirect.conf:

.

server {
  server_name gitlab.itextsupport.com;
  rewrite ^\/itext7\/samples\/(blob|raw)\/master\/(?!samples\/)(.*)$ https://$server_name/itext7/samples/$1/master/samples/$2 permanent;
}
  1. Edit the configuration file at /etc/gitlab/gitlab.rb to add the following line:

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

  2. Rewrite the nginx configuration:

    sudo gitlab-ctl reconfigure

  3. Restart the bundled nginx:

    sudo gitlab-ctl restart nginx

  4. Verify that the bundled nginx includes the redirect file:

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

Testing the configuration

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

Expected result

/samples gets inserted after /blob/master. I expect to see a 301 rewrite to https://gitlab.itextsupport.com/itext/tutorial/blob/master/samples/signatures/src/main/java/signatures/chapter4/C4_05_SignWithBEID.java

Actual result

200 OK on the unmodified URL.

Ugly hack

Add this line to /var/opt/gitlab/nginx/conf/gitlab-http.conf and restart the bundled nginx:

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

By doing it this way, I have verified that my actual rewrite rule itself is correct.

Drawback: this line will be lost every time gitlab-ctl reconfigure is run.

Question

What do I need to change to make the URL rewrite work as expected? Without the ugly hack?

Additional information

When I run sudo /opt/gitlab/embedded/sbin/nginx -p /var/opt/gitlab/nginx -T, I see two server { } blocks. My working theory so far is that nginx is picking up only the first server block, and ignoring the second one. If I could find a way to merge both server blocks, in a way that is compatible with the configuration file /etc/gitlab/gitlab.rb, then my problem is most likely solved.

Upvotes: 2

Views: 2622

Answers (1)

Amedee Van Gasse
Amedee Van Gasse

Reputation: 7644

Well, it looks like the answer was staring me in the face in gitlab.rb. One line above nginx['custom_nginx_config'], there is nginx['custom_gitlab_server_config']. I put the include statement there, and removed the server {} brackets around the rewrite rules. This is also described in the GitLab documentation at https://docs.gitlab.com/omnibus/settings/nginx.html#inserting-custom-nginx-settings-into-the-gitlab-server-block:

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

So this is what I did:

  1. In /etc/gitlab/gitlab.rb, comment out the nginx['custom_nginx_config'] line and add:

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

  2. In /etc/nginx/conf.d/redirect.conf, only keep the rewrite line on its own:

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

  3. Reconfigure GitLab:

    sudo gitlab-ctl reconfigure

  4. Restart nginx:

    sudo gitlab-ctl restart nginx

  5. Verify the nginx configuration:

    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/$1/master/samples/$2 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. Verify the URL rewrite:

    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

One thing I am still curious about:

  • The rewrite line ended up outside the server{} block.
  • The rewrite line uses the $server_name variable.
  • The $server_name variable is defined inside the server{} block.

Is that visually confusing because of how the weird way included statements are displayed by nginx -T? Is the rewrite line really inside the server{} block even if it appears to be outside? Why are things oft not as they appear to be, and why is GitLab documentation written in a hermetic language? Alas, these ponderings may forever remain unanswered.

Upvotes: 4

Related Questions