Gitlab behind a reverse proxy
I am using GitLab for private projects. GitLab is run using the Docker image provided by GitLab. I can access my instance from outside via a reverse proxy (Apache).
The setup is simple:
- GitLab Docker container is running on NUC and listens on port 7080 for HTTP connections
- NUC is connected via OpenVPN to the server on AWS
- Apache as a reverse proxy listening on port 443 for HTTPS
- Apache terminates SSL: incoming requests are HTTPS, but forwarded as HTTP to GitLab
- Apache forwards incoming requests to GitLab on Docker
Standard setup of GitLab in Docker with Apache as reverse proxy will give access to GitLab without problems. Start GitLab container, configure Apache, done. You can access GitLab from the internet, create repositories, clone, push, etc.
While the setup will work out of the box, you need to carry out additional configuration for GitLab to really make it work with SSL terminating. What is not working correctly is:
- The external URL is not configured, so the URL in the repository clone dialog is not using HTTPS.
- You cannot upload attachments in the Wiki
- You cannot add pictures in the Wiki via copy & paste from the clipboard
- Uploading files / images may work in the issues dialog, but not in the wiki, as the wiki is using different upload service.
Attaching an image from clipboard fails.
My external URL is https://gitlab.itsfullofstars.de. Setting this value as external URL in gitlab.rb. You configure GitLab by setting the parameters in the file gitlab.rb and then reconfigure GitLab.
## GitLab URL ##! URL on which GitLab will be reachable. external_url 'https://gitlab.itsfullofstars.de'
Run reconfigure to enable the configuration.
This will set all parameters in all involved components of GitLab based on the values set in gitlab.rb. You can see the new value by looking at the automatically generated configuration file for the internal web server.
## GitLab settings gitlab: ## Web server settings (note: host is the FQDN, do not include http://) host: gitlab.itsfullofstars.de port: 443 https: true
The problem is: GitLab thinks it is running standalone, with direct access to the internet. There is not a specific parameter to inform that the requests are coming from a reverse proxy with SSL termination. Setting the values in gitlab.rb will result in an erroneous configuration:
- SSL for internal GitLab web server (nginx) is enabled
- Nginx is not listening on port 80, only on 443
- My Apache reverse proxy is configured to connect to nginx port 80. Hence the Service Unavailable error.
Port 80 is not working any longer. Accessing GitLab directly via 192.168.x.x:7443 on HTTPS port (Docker mapping 7443 to 443).
Access will work. GitLab tries to get a new TLS certificate during the reconfiguration process, but fails, therefore the self signed certificate.
Attaching an image won’t work
Because of the external_url value, GitLab will redirect to gitlab.itsfullofstars.de. As the reverse proxy is not able to connect, it’s a 503 error.
Configuring the external GitLab URLs results in:
- An incorrect HTTPS configuration due to wrong certificate
- Adjustment of Apache reverse proxy: no longer SSL termination
I do not want to take of managing GitLabs internal TLS certificate. I want to access it via HTTP only and use Apache for SSL termination.
The solution is to configure the external URL and to let the internal nginx run on port 80 and no HTTPS.
Configure a value for external_url.
external_url 'https://gitlab.itsfullofstars.de' nginx['listen_port'] = 80 nginx['listen_https'] = false gitlab-ctl reconfigure
GitLab HTTP server
Check the configuration for the internal GitLab web server. The server should be gitlab.itsfullofstars, the port 80 and protocol HTTP.
## GitLab settings gitlab: ## Web server settings (note: host is the FQDN, do not include http://) host: gitlab.itsfullofstars.de port: 80 https: false
Running reconfigure restarts the services, but if you want to be sure, restart GitLab.
My Apache configuration. Maybe not all parameters are needed, but it works.
<VirtualHost *:443> ServerName gitlab.itsfullofstars.de ProxyPreserveHost On ProxyRequests Off SSLProxyEngine on SSLEngine on SSLHonorCipherOrder on <Location /> RequestHeader unset Accept-Encoding RequestHeader set Host "gitlab.itsfullofstars.de" RequestHeader add X-Forwarded-Ssl on RequestHeader set X-Forwarded-Proto "https" ProxyPass http://nuc:7080/ ProxyPassReverse http://nuc:7080/ Order allow,deny Allow from all </Location> </VirtualHost>
After executing the above steps, your configuration should be:
- External URL is https://gitlab.itsfullofstars.de
- The internal GitLab nginx is listening
- Port: 80
- Protocol: HTTP
- Server: gitlab.itsfullofstars.de
An external request is now for server gitlab.itsfullofstars.de. Apache does SSL termination, and nginx is accepting the request without either blocking it or trying to redirect to HTTPS.
Attaching an image to GitLab Wiki by pasting it from the clipboard
Some resources I found while solving the issue for myself.