Running GitLab Pages behind a HTTPS reverse proxy

By Ward Pieters at

Intro

GitLab Pages is a great way to host static websites. However, when using a reverse proxy custom domains can be tricky to set up. The GitLab docs describe you need a secondary IP address for this, but this is not always possible.

This guide will show you how to set up GitLab Pages behind a reverse proxy with HTTPS using Caddy and a custom GitLab Pages API written by me (wardpieters/gitlab-pages-caddy-api).

Steps

Note: make sure to replace example.com and other example domains with your own domain, and ca@example.com with your own Let's Encrypt contact email address.

1. Enable GitLab Pages

Update the values shown below in your gitlab.rb file to enable GitLab Pages, configure the external pages URL and expose the necessary ports locally. Leave everything else as-is.

gitlab.rb

##! Define to enable GitLab Pages
pages_external_url "https://pages.example.com/"
gitlab_pages['enable'] = true

##! Configure to expose GitLab Pages on external IP address, serving the HTTP
# gitlab_pages['external_http'] = []
gitlab_pages['external_http'] = ['0.0.0.0:8888']
# Below you can find settings that are exclusive to "GitLab Pages NGINX"
pages_nginx['enable'] = true
pages_nginx['listen_port'] = 8091
pages_nginx['listen_https'] = false
pages_nginx['redirect_http_to_https'] = true

docker-compose.yml

Make sure to expose the ports for GitLab Pages and add the local GitLab Pages API using the docker-compose.yml file, only the relevant lines are shown below.

  • Port 8091 is used for the GitLab pages domain (e.g. pages.example.com).
  • Port 8888 is used for the external domains (e.g. handbook.example.nl).
services:
  gitlab-ee:
    ports:
      - "127.0.0.1:8091:8091"
      - "127.0.0.1:8888:8888"
  caddy-api:
    restart: unless-stopped
    image: ghcr.io/wardpieters/gitlab-pages-caddy-api:latest
    ports:
      - "127.0.0.1:8000:5000"
    env_file:
      - .env

.env

In the same directory as the docker-compose.yml file, create a .env file with the below contents. Make sure to replace the values with your own. The GITLAB_TOKEN can be created from the GitLab UI and needs to have the api and admin scopes.

GITLAB_TOKEN=xyz
GITLAB_DOMAIN=git.example.com
GITLAB_PAGES_DOMAIN=pages.example.com

2. Configure Caddy

The Caddyfile needs three additions:

{
    on_demand_tls {
        ask http://localhost:8000/api
        interval 2m
        burst 5
    }
}
:443 {
    tls ca@example.com {
        on_demand
    }

    reverse_proxy http://127.0.0.1:8888 {
        header_down -server
    }
}
pages.example.com,
*.pages.example.com {
    tls ca@example.com {
        on_demand
    }

    reverse_proxy http://127.0.0.1:8091 {
        header_down -server
    }

    import hsts
}

3. Restart

Restart your GitLab instance and run docker compose up -d to make sure the local GitLab Pages API is running

Profit!

That's it! You should now have GitLab Pages running behind a reverse proxy with HTTPS!

Problems?

This post has been written with the outmost care, but if you find any mistakes or have any suggestions, please let me know.

If you encounter any problems, check all the steps again and make sure you have followed them correctly. Setting up GitLab Pages involves multiple steps, so it's important to double-check and ensure that each step is followed correctly.