Setting up a private GitLab instance

I was inspired by this blog post (I subscribe to his YouTube channel) to set up a GitLab Community Edition instance of my own. However, there were a few things I wanted to do differently:

  1. I have a Proxmox VE cluster as part of my home lab, so I wanted to set it up as a virtual machine hosted there.
  2. I wanted to have it publicly available, but without exposing it through my firewall or exposing my public IP address.

I had previously followed Jay’s tutorial on setting up an Ubuntu 22.04 template in Proxmox, so I cloned that template and followed the instructions for installing GitLab. I had also set up a Cloudflare Tunnel to my home network and had set up a couple of other services that I wanted to be able to reach from outside of my home network. My setup for that is a Docker container running cloudflared on my Unraid server. Ideally, I’d be able to combine the two and protect my instance of Gitlab using the Cloudflare reverse proxy tunnel and still be able to access it.

While the instructions from Jay were straightforward, they didn’t cover how to set it up behind a proxy. I did find this post on Cloudflare’s site, but it was for Gitlab Enterprise Edition and didn’t apply to the version I was using. I did, however, use the instructions there for setting up a Cloudflare application. Additionally, I did run into a snag with the install that Jay didn’t cover: namely, when installing GitLab it complained UTF-8 English was not installed. If you run into that, follow the instructions here and try installing GitLab again.

It took me quite a while to figure out how to get past the proxy issue. Eventually, I found in GitLab’s documentation information on what to do if running it behind a reverse proxy and terminating SSL before it. I preferred to do that, rather than using a Let’s Encrypt certificate on this server. It ended up being quite simple. You specify the domain you’re going to use on the external_url setting in /etc/gitlab/gitlab.rb (e.g., “https://gitlab.briankavanaugh.com”), and also change these two settings:

##! **Override only if you use a reverse proxy**
##! Docs: https://docs.gitlab.com/omnibus/settings/nginx.html#setting-the-nginx-listen-port
nginx['listen_port'] = 80

##! **Override only if your reverse proxy internally communicates over HTTP**
##! Docs: https://docs.gitlab.com/omnibus/settings/nginx.html#supporting-proxied-ssl
nginx['listen_https'] = false

If you also want to add the ability to send email notifications, here’s how you do it for a Gmail address. If you have multifactor authentication set up, you’ll need to generate an application password, instead of using your email password.

gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.gmail.com"
gitlab_rails['smtp_port'] = 587
gitlab_rails['smtp_user_name'] = "<your email address>"
gitlab_rails['smtp_password'] = "<your password/app password>"
gitlab_rails['smtp_domain'] = "smtp.gmail.com"
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['smtp_tls'] = false
# gitlab_rails['smtp_pool'] = false

###! **Can be: 'none', 'peer', 'client_once', 'fail_if_no_peer_cert'**
###! Docs: http://api.rubyonrails.org/classes/ActionMailer/Base.html
gitlab_rails['smtp_openssl_verify_mode'] = 'peer'

After that, it was a matter of configuring access to the application in my Cloudflare tunnel, and everything started working.

I did something similar this morning, setting up a private instance of SearXNG on my network, but accessible outside of it and protected by Cloudflare.

Using Cloudflare as a reverse proxy tunnel is an easy (and free!) way to expose services on your local network, while keeping your IP address hidden (plus not having to update anything when it changes), limiting access to it, and without having to open ports on your firewall.