Use gitlab pages under the same domain as gitlab
Description
Allow the usage of one SSL certificate for both gitlab and gitlab pages
Proposal
You need to reserve a word and prevent the creation of a group with this name (like "admin" is not a valid group name). The main idea is to use a reverse proxy (we use an external nginx) to present the correct Host http header to the gitlab pages server without the user browser knowing it. You still need a DNS wildcard but no Wildcard SSL certificate and the link in Gitlab also works directly (redirects to the correct domain).
Links / references
These issues are partly related
Documentation
Example : gitlab instance runs at https://gitlab.example.org with a nginx reverse proxy in front of it
## gitlab.rb ##
external_url 'https://gitlab.example.org'
gitlab.example.org "http://gitlab.example.org/"
## nginx-vhost.conf ##
server {
listen 80;
# Rewrite
# http://MYGROUP.gitlab.example.org/myproject/index.html
# to
# https://gitlab.example.org/pages/MYGROUP/myproject/index.html
server_name ~^(?<subdomain>.*)\.gitlab.example.org$;
rewrite ^/(.*)$ https://gitlab.example.org/pages/$subdomain/$1;
}
server {
listen 80;
return 301 https://$host$request_uri;
}
server {
listen 443;
error_log /var/log/nginx/gitlab.access.log;
ssl on;
ssl_certificate /etc/nginx/external/cert.pem;
ssl_certificate_key /etc/nginx/external/key.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # don’t use SSLv3 ref: POODLE
location / {
# our gitlab runs in another docker container available at gitlab
proxy_pass http://gitlab:80/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forward-Proto http;
proxy_set_header X-Nginx-Proxy true;
proxy_redirect off;
}
location /pages {
# Redirect http://gitlab.example.org/pages/MYGROUP/MYPROJECT
# to http://gitlab.example.org/pages/MYGROUP/MYPROJECT/index.html
# because without the "/" the second rewrite is not working
rewrite ^(/pages/[^/]+/[^/]+)$ $1/index.html permanent;
# Proxy set header with rewrite example:
# http://gitlab.example.org/pages/MYGROUP/MYPROJECT/index.html
# to
# http://gitlab.example.org/MYPROJECT/index.html with header "Host: MYGROUP.gitlab.example.org"
# see doc here: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass
rewrite ^/pages/([^/]+)/(.*)$ /$2 break;
proxy_set_header Host $1.gitlab.example.org;
proxy_pass http://gitlab:80/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forward-Proto http;
proxy_set_header X-Nginx-Proxy true;
proxy_redirect off;
}
}
The two important bits of the Nginx config are
server_name ~^(?<subdomain>.*)\.gitlab.example.org$;
rewrite ^/(.*)$ https://gitlab.example.org/pages/$subdomain/$1;
http://group.gitlab.example.org/project is redirected to https://gitlab.example.org/pages/group/project We reserved the name "pages" so no group "pages" can be used in our gitlab instance
and
location /pages {
# Redirect http://gitlab.example.org/pages/MYGROUP/MYPROJECT
# to http://gitlab.example.org/pages/MYGROUP/MYPROJECT/index.html
# because without the "/" the second rewrite is not working
rewrite ^(/pages/[^/]+/[^/]+)$ $1/index.html permanent;
# Proxy set header with rewrite example:
# http://gitlab.example.org/pages/MYGROUP/MYPROJECT/index.html
# to
# http://gitlab.example.org/MYPROJECT/index.html with header "Host: MYGROUP.gitlab.example.org"
# see doc here: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass
rewrite ^/pages/([^/]+)/(.*)$ /$2 break;
proxy_set_header Host $1.gitlab.example.org;
I will describe each request with its http header Host to ease comprehension :
https://gitlab.example.org/pages/group/project
Host : gitlab.example.org
is proxyfied as http://gitlab.example.org/project
Host : group.gitlab.example.org
At this point the request hits the nginx bundled with gitlab that forwards it to the gitlab pages server (the correct Host http header is present). I don't know how to integrate into the bundled nginx but I thought it is worth sharing with the community.