GitLab
About our GitLab configuration
Our GitLab installation is designed to provide a secure, lightweight platform for hosting Git repositories and reviewing code. GitLab includes many additional capabilities—including continuous integration, package registries, container registries, wikis, and deployment tools—but most are disabled by default to keep the interface focused on source code management.
Configuration is managed entirely through Ansible using the GitLab Omnibus package for Debian.
Configuration management
The Debian apt package does not directly write to the main configuration file /etc/gitlab/gitlab.rb so rather than modifying this file line by line, we manage the entire file as an Ansible template.
- name: Configure GitLab
ansible.builtin.template:
src: gitlab.rb.j2
dest: /etc/gitlab/gitlab.rb
notify: reconfigure gitlab
GitLab ships a complete gitlab.rb.template containing every supported option for reference but only the settings that differ from the defaults are included in our template. This keeps the configuration concise while making upgrades easier to review against the latest GitLab template.
HTTPS
GitLab’s bundled NGINX server terminates HTTPS using certificates placed directly on the host.
nginx['ssl_certificate'] = '/etc/ssl/mayfirst/{{ gitlab_site_domain }}/fullchain.pem'
nginx['ssl_certificate_key'] = '/etc/ssl/mayfirst/{{ gitlab_site_domain }}/privkey.pem'
nginx['ssl_dhparam'] = '/etc/ssl/dhparam.pem'
GitLab sends notifications through May First’s mail servers and is configured to accept replies through an IMAP mailbox.
gitlab_rails['smtp_enable'] = true
gitlab_rails['incoming_email_enabled'] = true
The IMAP password is stored in Ansible Vault rather than in the playbook or repository.
Default project features
New projects begin with only the features most repositories require.
gitlab_rails['gitlab_default_projects_features_issues'] = false
gitlab_rails['gitlab_default_projects_features_merge_requests'] = true
gitlab_rails['gitlab_default_projects_features_wiki'] = false
gitlab_rails['gitlab_default_projects_features_snippets'] = false
gitlab_rails['gitlab_default_projects_features_builds'] = false
gitlab_rails['gitlab_default_projects_features_container_registry'] = false
By default, repositories support merge requests but do not enable issues, wikis, CI/CD, snippets, or the container registry. Individual projects can enable these features later through the GitLab web interface when needed.
Disabled services
Services that are not used are disabled entirely.
gitlab_rails['registry_enabled'] = false
gitlab_pages['enable'] = false
Disabling unused services reduces resource usage and the number of externally accessible components that must be maintained.
Anubis reverse proxy
All web traffic passes through Anubis before reaching GitLab.
GitLab’s bundled NGINX is set to listen on an alternate port while a custom Anubis nginx config is setup to accept public HTTPS connections on port 443.
nginx['listen_port'] = 8443
nginx['custom_nginx_config'] =
'include /var/opt/gitlab/nginx/conf/anubis-custom.conf;'
The custom NGINX configuration is installed by the Ansible role before GitLab is reconfigured, ensuring the include file exists when GitLab regenerates its configuration.
This arrangement allows Anubis to filter automated traffic before requests reach GitLab.
Rate limiting
GitLab’s own unauthenticated web and API rate limits remain enabled as a second layer of protection behind Anubis.
The values we have changed from default 3600 requests per hour per ip are:
| Setting | Value |
|---|---|
| Unauthenticated API | 300 requests/hour/IP |
| Unauthenticated web | 600 requests/hour/IP |
These limits are configured through the GitLab administration interface rather than gitlab.rb.
Administrative policy
Several security policies are managed through the GitLab administration interface because they are application settings rather than Omnibus configuration.
After deployment, review the following settings:
- Disable user self-registration.
- Set the default project visibility to Private.
- Restrict group creation to administrators.
- Disable Auto DevOps.
- Disable shared runners unless CI/CD is introduced.
Together with the gitlab.rb configuration, these settings produce a GitLab instance that is focused on collaborative source code management while minimizing unnecessary features, services, and administrative overhead.
Reconfiguration
Changes to gitlab.rb require GitLab to regenerate the configuration for several bundled services. For this reason, the Ansible role runs gitlab-ctl reconfigure whenever the template changes, rather than simply restarting the service.
handlers:
- name: Reconfigure GitLab
ansible.builtin.command:
cmd: gitlab-ctl reconfigure
- filter automated traffic before it reaches GitLab
- apply rate limits to anonymous traffic
This approach reduces administrative overhead, minimizes the exposed attack surface, and presents users with a simpler interface focused on collaborative source code management while still allowing additional GitLab capabilities to be enabled selectively as organizational needs evolve.