GitLab architecture overview

Software delivery

There are two software distributions of GitLab:

GitLab is available under different subscriptions.

New versions of GitLab are released from stable branches, and the main branch is used for bleeding-edge development.

For more information, visit the GitLab Release Process.

Both distributions require additional components. These components are described in the Component details section, and all have their own repositories. New versions of each dependent component are usually tags, but staying on the main branch of the GitLab codebase gives you the latest stable version of those components. New versions are generally released around the same time as GitLab releases, with the exception of informal security updates deemed critical.

Components

A typical install of GitLab is on GNU/Linux, but growing number of deployments also use the Kubernetes platform. The largest known GitLab instance is on GitLab.com, which is deployed using our official GitLab Helm chart and the official Linux package.

A typical installation uses NGINX or Apache as a web server to proxy through GitLab Workhorse and into the Puma application server. GitLab serves web pages and the GitLab API using the Puma application server. It uses Sidekiq as a job queue which, in turn, uses Redis as a non-persistent database backend for job information, metadata, and incoming jobs.

By default, communication between Puma and Workhorse is via a Unix domain socket, but forwarding requests via TCP is also supported. Workhorse accesses the gitlab/public directory, bypassing the Puma application server to serve static pages, uploads (for example, avatar images or attachments), and pre-compiled assets.

The GitLab application uses PostgreSQL for persistent database information (for example, users, permissions, issues, or other metadata). GitLab stores the bare Git repositories in the location defined in the configuration file, repositories: section. It also keeps default branch and hook information with the bare repository.

When serving repositories over HTTP/HTTPS GitLab uses the GitLab API to resolve authorization and access and to serve Git objects.

The add-on component GitLab Shell serves repositories over SSH. It manages the SSH keys within the location defined in the configuration file, GitLab Shell section. The file in that location should never be manually edited. GitLab Shell accesses the bare repositories through Gitaly to serve Git objects, and communicates with Redis to submit jobs to Sidekiq for GitLab to process. GitLab Shell queries the GitLab API to determine authorization and access.

Gitaly executes Git operations from GitLab Shell and the GitLab web app, and provides an API to the GitLab web app to get attributes from Git (for example, title, branches, tags, or other metadata), and to get blobs (for example, diffs, commits, or files).

You may also be interested in the production architecture of GitLab.com.

Adapting existing and introducing new components

There are fundamental differences in how the application behaves when it is installed on a traditional Linux machine compared to a containerized platform, such as Kubernetes.

Compared to our official installation methods, some of the notable differences are:

  • Official Linux packages can access files on the same file system with different services. Shared files are not an option for the application running on the Kubernetes platform.
  • Official Linux packages by default have services that have access to the shared configuration and network. This is not the case for services running in Kubernetes, where services might be running in complete isolation, or only accessible through specific ports.

In other words, the shared state between services needs to be carefully considered when architecting new features and adding new components. Services that need to have access to the same files, need to be able to exchange information through the appropriate APIs. Whenever possible, this should not be done with files.

Since components written with the API-first philosophy in mind are compatible with both methods, all new features and services must be written to consider Kubernetes compatibility first.

The simplest way to ensure this, is to add support for your feature or service to the official GitLab Helm chart or reach out to the Distribution team.

Refer to the process for adding new service components for more details.

Simplified component overview

This is a simplified architecture diagram that can be used to understand the GitLab architecture.

A complete architecture diagram is available in our component diagram below.

Simplified Component Overview

Component diagram

%%{init: {"flowchart": { "useMaxWidth": false } }}%% graph LR %% Anchor items in the appropriate subgraph. %% Link them where the destination* is. subgraph Clients Browser((Browser)) Git((Git)) end %% External Components / Applications Geo{{GitLab Geo}} -- TCP 80, 443 --> HTTP Geo -- TCP 22 --> SSH Geo -- TCP 5432 --> PostgreSQL Runner{{GitLab Runner}} -- TCP 443 --> HTTP K8sAgent{{GitLab Agent}} -- TCP 443 --> HTTP %% GitLab Application Suite subgraph GitLab subgraph Ingress HTTP[[HTTP/HTTPS]] SSH[[SSH]] NGINX[NGINX] GitLabShell[GitLab Shell] %% inbound/internal Browser -- TCP 80,443 --> HTTP Git -- TCP 80,443 --> HTTP Git -- TCP 22 --> SSH HTTP -- TCP 80, 443 --> NGINX SSH -- TCP 22 --> GitLabShell end subgraph GitLab Services %% inbound from NGINX NGINX --> GitLabWorkhorse NGINX -- TCP 8090 --> GitLabPages NGINX -- TCP 8150 --> GitLabKas NGINX --> Registry %% inbound from GitLabShell GitLabShell --> GitLabWorkhorse %% services Puma["Puma (GitLab Rails)"] Puma <--> Registry GitLabWorkhorse[GitLab Workhorse] <--> Puma GitLabKas[GitLab Agent Server] --> GitLabWorkhorse GitLabPages[GitLab Pages] --> GitLabWorkhorse Mailroom Sidekiq end subgraph Integrated Services %% Mattermost Mattermost Mattermost ---> GitLabWorkhorse NGINX --> Mattermost %% Grafana Grafana NGINX --> Grafana end subgraph Metadata %% PostgreSQL PostgreSQL PostgreSQL --> Consul %% Consul and inbound Consul Puma ---> Consul Sidekiq ---> Consul Migrations --> PostgreSQL %% PgBouncer and inbound PgBouncer PgBouncer --> Consul PgBouncer --> PostgreSQL Sidekiq --> PgBouncer Puma --> PgBouncer end subgraph State %% Redis and inbound Redis Puma --> Redis Sidekiq --> Redis GitLabWorkhorse --> Redis Mailroom --> Redis GitLabKas --> Redis %% Sentinel and inbound Sentinel <--> Redis Puma --> Sentinel Sidekiq --> Sentinel GitLabWorkhorse --> Sentinel Mailroom --> Sentinel GitLabKas --> Sentinel end subgraph Git Repositories %% Gitaly / Praefect Praefect --> Gitaly GitLabKas --> Praefect GitLabShell --> Praefect GitLabWorkhorse --> Praefect Puma --> Praefect Sidekiq --> Praefect Praefect <--> PraefectPGSQL[PostgreSQL] %% Gitaly makes API calls %% Ordered here to ensure placement. Gitaly --> GitLabWorkhorse end subgraph Storage %% ObjectStorage and inbound traffic ObjectStorage["Object Storage"] Puma -- TCP 443 --> ObjectStorage Sidekiq -- TCP 443 --> ObjectStorage GitLabWorkhorse -- TCP 443 --> ObjectStorage Registry -- TCP 443 --> ObjectStorage GitLabPages -- TCP 443 --> ObjectStorage end subgraph Monitoring %% Prometheus Grafana -- TCP 9090 --> Prometheus[Prometheus] Prometheus -- TCP 80, 443 --> Puma RedisExporter[Redis Exporter] --> Redis Prometheus -- TCP 9121 --> RedisExporter PostgreSQLExporter[PostgreSQL Exporter] --> PostgreSQL PgBouncerExporter[PgBouncer Exporter] --> PgBouncer Prometheus -- TCP 9187 --> PostgreSQLExporter Prometheus -- TCP 9100 --> NodeExporter[Node Exporter] Prometheus -- TCP 9168 --> GitLabExporter[GitLab Exporter] Prometheus -- TCP 9127 --> PgBouncerExporter Prometheus --> Alertmanager GitLabExporter --> PostgreSQL GitLabExporter --> GitLabShell GitLabExporter --> Sidekiq %% Alertmanager Alertmanager -- TCP 25 --> SMTP end %% end subgraph GitLab end subgraph External subgraph External Services SMTP[SMTP Gateway] LDAP %% Outbound SMTP Sidekiq -- TCP 25 --> SMTP Puma -- TCP 25 --> SMTP Mailroom -- TCP 25 --> SMTP %% Outbound LDAP Puma -- TCP 369 --> LDAP Sidekiq -- TCP 369 --> LDAP %% Elasticsearch Elasticsearch Puma -- TCP 9200 --> Elasticsearch Sidekiq -- TCP 9200 --> Elasticsearch end subgraph External Monitoring %% Sentry Sidekiq -- TCP 80, 443 --> Sentry Puma -- TCP 80, 443 --> Sentry %% Jaeger Jaeger Sidekiq -- UDP 6831 --> Jaeger Puma -- UDP 6831 --> Jaeger Gitaly -- UDP 6831 --> Jaeger GitLabShell -- UDP 6831 --> Jaeger GitLabWorkhorse -- UDP 6831 --> Jaeger end %% end subgraph External end click Alertmanager "./architecture.html#alertmanager" click Praefect "./architecture.html#praefect" click Geo "./architecture.html#gitlab-geo" click NGINX "./architecture.html#nginx" click Runner "./architecture.html#gitlab-runner" click Registry "./architecture.html#registry" click ObjectStorage "./architecture.html#minio" click Mattermost "./architecture.html#mattermost" click Gitaly "./architecture.html#gitaly" click Jaeger "./architecture.html#jaeger" click GitLabWorkhorse "./architecture.html#gitlab-workhorse" click LDAP "./architecture.html#ldap-authentication" click Puma "./architecture.html#puma" click GitLabShell "./architecture.html#gitlab-shell" click SSH "./architecture.html#ssh-request-22" click Sidekiq "./architecture.html#sidekiq" click Sentry "./architecture.html#sentry" click GitLabExporter "./architecture.html#gitlab-exporter" click Elasticsearch "./architecture.html#elasticsearch" click Migrations "./architecture.html#database-migrations" click PostgreSQL "./architecture.html#postgresql" click Consul "./architecture.html#consul" click PgBouncer "./architecture.html#pgbouncer" click PgBouncerExporter "./architecture.html#pgbouncer-exporter" click RedisExporter "./architecture.html#redis-exporter" click Redis "./architecture.html#redis" click Prometheus "./architecture.html#prometheus" click Grafana "./architecture.html#grafana" click GitLabPages "./architecture.html#gitlab-pages" click PostgreSQLExporter "./architecture.html#postgresql-exporter" click SMTP "./architecture.html#outbound-email" click NodeExporter "./architecture.html#node-exporter"

Component legend

  • ✅ - Installed by default
  • ⚙ - Requires additional configuration
  • ⤓ - Manual installation required
  • ❌ - Not supported or no instructions available
  • N/A - Not applicable

Component statuses are linked to configuration documentation for each component.

Component list

Component Description Omnibus GitLab GitLab Environment Toolkit (GET) GitLab chart minikube Minimal GitLab.com Source GDK CE/EE
Certificate Management TLS Settings, Let’s Encrypt CE & EE
Consul Database node discovery, failover EE Only
Database Migrations Database migrations CE & EE
Elasticsearch Improved search within GitLab EE Only
Gitaly Git RPC service for handling all Git calls made by GitLab CE & EE
GitLab Exporter Generates a variety of GitLab metrics CE & EE
GitLab Geo Geographically distributed GitLab site EE Only
GitLab Pages Hosts static websites CE & EE
GitLab agent Integrate Kubernetes clusters in a cloud-native way EE Only
GitLab self-monitoring: Alertmanager Deduplicates, groups, and routes alerts from Prometheus CE & EE
GitLab self-monitoring: Grafana Metrics dashboard