Stable

Run GitLab behind BusinessProxy App Gateway

Step-by-step setup for publishing a self-hosted GitLab through BusinessProxy without exposing the GitLab server directly.

Steps

Follow these in order.

  1. 01Choose one canonical domainGitLab redirects, cookies, assets and WebSocket endpoints must use the same public host.
  2. 02Prepare the GitLab originLet BusinessProxy terminate public TLS and make GitLab listen on plain HTTP inside the private network.
  3. 03Create the BusinessProxy private appPublish GitLab through the connector and bind the custom domain that matches GitLab external_url.
  4. 04Verify redirects, assets and WebSocketA successful setup returns the sign-in page and loads CSS, JavaScript and live endpoints from the same public domain.
  5. 05Troubleshoot common failures502, pending assets, redirect loops and CSRF failures usually point to URL, scheme or upstream TLS mismatch.

Reference

Implementation details for setup and review.

When to use this guideUse this setup when GitLab is self-hosted in a private network and should be opened only through a managed BusinessProxy private-app session. BusinessProxy controls who can open the GitLab web app; GitLab still controls GitLab users, projects, groups, permissions and repository access inside GitLab.
  • Do not leave the GitLab upstream directly reachable from the public internet.
  • Use one permanent customer domain, for example gitlab.example.com, instead of a temporary system alias.
  • Run the BusinessProxy connector where it can reach the GitLab HTTP endpoint.
1. Pick the canonical public domainGitLab is sensitive to its public URL. Redirects, CSRF checks, cookies, assets and WebSocket URLs are generated from GitLab external_url. Choose one domain users will type in the browser, then use that exact domain everywhere.
  • Recommended shape: https://gitlab.example.com.
  • Avoid opening the same GitLab through several public aliases; cookies and redirects can become inconsistent.
  • Create the DNS record required by the BusinessProxy custom-domain flow and wait until the certificate is active.
2. Configure GitLab for reverse-proxy modeIf BusinessProxy terminates public HTTPS, GitLab should normally receive plain HTTP from the connector side. Configure Omnibus GitLab so external_url remains HTTPS, while the embedded GitLab NGINX listens without TLS internally.
external_url 'https://gitlab.example.com'

nginx['listen_port'] = 80
nginx['listen_https'] = false
  • Run sudo gitlab-ctl reconfigure after editing /etc/gitlab/gitlab.rb.
  • If you deliberately keep HTTPS on the GitLab upstream, use a certificate trusted by the connector host or disable upstream TLS verification only for that private app after understanding the risk.
3. Check GitLab from the connector hostBefore publishing the app, confirm that the connector host can reach GitLab by the same internal URL you will configure as upstream. This isolates GitLab and network problems from BusinessProxy routing problems.
curl -I http://gitlab.internal/users/sign_in
curl -I -H "Host: gitlab.example.com" http://gitlab.internal/users/sign_in
  • The response should be HTTP 200 or a normal GitLab redirect, not a TLS error or connection timeout.
  • If GitLab redirects to another host, fix external_url before continuing.
4. Create the private app in BusinessProxyIn the workspace dashboard, create a private app for GitLab. Select the connector that can reach the GitLab server, set the upstream to the internal GitLab HTTP URL, then attach the custom domain that matches external_url.
  • Public/custom domain: gitlab.example.com.
  • Upstream URL: http://gitlab.internal or another internal HTTP URL reachable by the connector.
  • Rewrite redirects and cookie domains should stay enabled unless support asks otherwise.
  • Verify upstream TLS can stay disabled only when the upstream URL is HTTP. For HTTPS upstreams, the setting controls certificate verification, not GitLab URL generation.
5. Open GitLab and verify the browser sessionLaunch GitLab from BusinessProxy or open the custom domain after a valid app session is created. The sign-in page should load as HTML 200, and CSS, JavaScript, images and WebSocket requests should use the same public GitLab domain.
  • Expected URL in the browser: https://gitlab.example.com/users/sign_in.
  • DevTools Network should not show static files hanging forever as pending.
  • If GitLab opens but later redirects to a different host, fix GitLab external_url and reconfigure GitLab again.
Common symptom: 502 from BusinessProxyA 502 means BusinessProxy could not get a usable response from the GitLab upstream through the connector. If the upstream is HTTPS, the cause is often certificate verification. If the upstream is HTTP, check connector readiness, DNS, TCP reachability and the configured upstream URL.
  • Use the private app diagnostics first; it checks the path from connector to upstream.
  • Disabling Verify upstream TLS helps only with upstream certificate trust. It does not fix a wrong external_url or redirect loop.
Common symptom: page is 200 but assets stay pendingWhen /users/sign_in returns 200 but CSS or JavaScript never finishes loading, GitLab is usually generating asset URLs, redirects or headers for a different public URL or scheme. Re-check external_url, listen_https, the public custom domain and Host handling.
  • external_url must be https://gitlab.example.com, not the internal host and not a BusinessProxy temporary system alias.
  • If GitLab is behind BusinessProxy TLS termination, nginx listen_https should normally be false.
  • Clear browser cache or service worker state after changing GitLab public URL settings.
Common symptom: sign-in or CSRF failsGitLab sign-in and CSRF protection depend on scheme, host and cookies. If the form loads but sign-in fails unexpectedly, check that the browser stays on the canonical domain and that cookies are set for that domain only.
  • Do not mix gitlab.example.com and a *.business-proxy.com system alias in the same browser session.
  • After changing external_url, sign out and clear old GitLab cookies for the previous host.
Operational notesBusinessProxy protects the web access path to GitLab, but it does not replace GitLab administration. Keep GitLab user lifecycle, project permissions, SSH clone policy, runners and backups under your normal GitLab controls.
  • For the first rollout, test web sign-in, project browsing, repository view, merge requests, artifacts and WebSocket/live UI behavior.
  • If users also need Git over SSH, plan that separately. This guide covers the GitLab web application path.
  • Keep a direct administrative recovery path available on a restricted private network for maintenance.