{"id":236,"date":"2025-10-09T09:41:53","date_gmt":"2025-10-09T09:41:53","guid":{"rendered":"https:\/\/blog.ngocha.biz\/?p=236"},"modified":"2025-10-09T09:41:53","modified_gmt":"2025-10-09T09:41:53","slug":"gitlab-architecture","status":"publish","type":"post","link":"https:\/\/blog.ngocha.biz\/?p=236","title":{"rendered":"GitLab Architecture: A Complete Guide"},"content":{"rendered":"<p>In this blog, we will explore the GitLab architecture and the components that work together to build a comprehensive software development lifecycle.<\/p>\n<p>By the end of this blog, you will have learned the following.<\/p>\n<ol>\n<li>The GitLab architecture<\/li>\n<li>The core components of GitLab<\/li>\n<li>CI\/CD architecture of GitLab<\/li>\n<li>GitLab storage<\/li>\n<li>High availability and scalability of GitLab<\/li>\n<li>GitLab authentication and authorization <\/li>\n<li>GitLab monitoring<\/li>\n<\/ol>\n<p>Lets get started.<\/p>\n<h2 id=\"what-is-gitlab\">What is Gitlab<\/h2>\n<p>GitLab is a popular <a href=\"https:\/\/devopscube.com\/best-devops-tools\/\" rel=\"noreferrer\">DevOps tool<\/a> that combines version control, <a href=\"https:\/\/devopscube.com\/learning-ci-cd-tools\/\" rel=\"noreferrer\">CI\/CD<\/a>, and <a href=\"https:\/\/devopscube.com\/project-management-software\/\" rel=\"noreferrer\">project management<\/a> tools.<\/p>\n<p>It is a end to end platform that can handle the  complete software development lifecycle. It is a perfect fit for organisations that needs a unified platform instead of multiple tools.<\/p>\n<p>Companies like Agoda, Airbus, CERN, Goldman Sachs, and NVIDIA use GitLab for their CI\/CD and DevSecOps implementations.<\/p>\n<p>Overall Gitlab offers the following.<\/p>\n<ul>\n<li><strong>Git repository management<\/strong> &#8211; You can host and manage your code like Github.<\/li>\n<li><strong>CI\/CD pipelines: <\/strong> It supports entire CI\/CD workflow using simple yaml configs.<\/li>\n<li><strong>Issue tracking: <\/strong>You can Plan and track work, bugs, and feature requests<\/li>\n<li><strong>Code review: <\/strong>You can perform reviews,  merge requests with approval workflows.<\/li>\n<li><strong>Container registry: <\/strong>You can store and manage <a href=\"https:\/\/devopscube.com\/build-docker-image\/\" rel=\"noreferrer\">Docker images<\/a><\/li>\n<li><strong>Security scanning: <\/strong>If offers Built-in security testing and vulnerability detection.<\/li>\n<\/ul>\n<p>Overall, it has everything integrated in one place rather than managing multiple separate tools.<\/p>\n<div class=\"kg-card kg-callout-card kg-callout-card-blue\">\n<div class=\"kg-callout-emoji\">\ud83d\udccc<\/div>\n<div class=\"kg-callout-text\"><b><strong style=\"white-space: pre-wrap;\">GitLab<\/strong><\/b> = Code hosting + CI\/CD + Issue tracking + DevOps tools<\/div>\n<\/div>\n<h2 id=\"gitlab-architecture\">GitLab Architecture<\/h2>\n<p>The following outlines the architecture of GitLab and how its components interact with one another.<\/p>\n<figure class=\"kg-card kg-image-card kg-card-hascaption\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/10\/image-4.png\" class=\"kg-image\" alt=\"The architecture diagram of the GitLab\" loading=\"lazy\" width=\"2000\" height=\"1108\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/10\/image-4.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1000\/2025\/10\/image-4.png 1000w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1600\/2025\/10\/image-4.png 1600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w2400\/2025\/10\/image-4.png 2400w\" sizes=\"auto, (min-width: 720px) 720px\"><figcaption><span style=\"white-space: pre-wrap;\">GitLab Architecture<\/span><\/figcaption><\/figure>\n<p>Here is how all the components work together, as shown in the above arcitecture diagram.<\/p>\n<ul>\n<li>When a <strong>web user<\/strong> accesses GitLab, the HTTP(S) request first goes to <strong>Nginx<\/strong>, which acts as a <strong>reverse proxy<\/strong>.<\/li>\n<li>Nginx routes the request to the <strong>GitLab Workhorse<\/strong>, which decides whether to handle it itself or send it to <strong>Puma<\/strong>.<\/li>\n<li><strong>Puma<\/strong> is a <strong>web server <\/strong>that handles time-sensitive requests, such as retrieving project, issue, and user data from <strong>PostgreSQL<\/strong>, or caching or session information from <strong>Redis<\/strong>.<\/li>\n<li>If there are background tasks, such as sending notifications or executing CI\/CD jobs, Puma sends them to <strong>Sidekiq<\/strong>, which manages the jobs using <strong>Redis<\/strong> and stores and retrieves data in <strong>PostgreSQL<\/strong> and <strong>Gitaly<\/strong>.<\/li>\n<li>Gitaly is a storage where all the Git repository data is stored.<\/li>\n<li>When users perform the Git operations, they directly access the Gitaly through the <strong>GitLab<\/strong> shell over SSH.<\/li>\n<\/ul>\n<p>All these components need to work with GitLab properly. We can explore them in the next section.<\/p>\n<h2 id=\"core-components-of-gitlab\">Core Components of GitLab<\/h2>\n<p>Once of the key requirement of DevOps engineers is to understand the core architecture of Gitlab. Becuase,you cant optimize or fix what you dont understand.<\/p>\n<p>By understanding the core architecture, you can trohbleshoot, scale, perform upgrades, integrations and more.<\/p>\n<p>GitLab consists of many components. We broke down each component and explained what each component does. Lets get started.<\/p>\n<h3 id=\"proxyhttp-server-nginx\">Proxy\/HTTP Server (Nginx)<\/h3>\n<p>GitLab uses the <a href=\"https:\/\/docs.gitlab.com\/omnibus\/settings\/nginx\/?ref=devopscube.com\" rel=\"noreferrer\">Nginx<\/a> web server as the <strong>reverse proxy<\/strong> for user requests.<\/p>\n<p>This <a href=\"https:\/\/devopscube.com\/setup-and-configure-proxy-server\/\" rel=\"noreferrer\">proxy <\/a>even handles the SSL\/TLS termination to encrypt the traffic between the user and GitLab.<\/p>\n<h3 id=\"gitlab-web-ui-api\">GitLab Web UI \/ API<\/h3>\n<p>We can interact with GitLab in two ways: directly from a web browser using the User Interface (Web UI), and through API calls, primarily for programs to interact with.<\/p>\n<div class=\"kg-card kg-callout-card kg-callout-card-blue\">\n<div class=\"kg-callout-emoji\">\ud83d\udca1<\/div>\n<div class=\"kg-callout-text\">GitLab offers two API endpoints, which are <b><strong style=\"white-space: pre-wrap;\">REST<\/strong><\/b> and <b><strong style=\"white-space: pre-wrap;\">GraphQL<\/strong><\/b>. <\/p>\n<p><b><strong style=\"white-space: pre-wrap;\">GraphQL<\/strong><\/b> is efficient for complex queries, modern integrations, UI applications<\/div>\n<\/div>\n<h3 id=\"controllers-rails-puma\">Controllers \/ Rails \/ Puma<\/h3>\n<p>GitLab core is built on the Ruby on Rails web application framework.<\/p>\n<p>When you perform an action in Gitlab, several components work together at the backend to handle the requests.<\/p>\n<p>It starts with<strong> <\/strong><a href=\"https:\/\/about.gitlab.com\/blog\/migrating-to-puma-on-gitlab\/?ref=devopscube.com\" rel=\"noreferrer\"><strong>Puma<\/strong><\/a>. It is a <strong>web server<\/strong> of GitLab that listens to HTTP requests. It forwards the requests to the Rails application.<\/p>\n<p><strong>Rails<\/strong> follows the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Model%E2%80%93view%E2%80%93controller?ref=devopscube.com\" rel=\"noreferrer\"><strong>Model-View-Controller (MVC)<\/strong><\/a> pattern. When Puma passes the request to Rails, it routes to the <strong>appropriate Controller<\/strong> to tell what action should be performed.<\/p>\n<h3 id=\"gitlab-workhorse\">GitLab Workhorse<\/h3>\n<p><strong>Workhorse<\/strong> is a <strong>reverse proxy<\/strong> that sits in front of Puma.<\/p>\n<p>It <strong>handles<\/strong> <strong>slow and large HTTP requests <\/strong>(e.g., Big uploads\/downloads). Once it picks the larger requests, it forwards the remaining time-sensitive requests to Puma.<\/p>\n<h3 id=\"gitlab-shell\">GitLab Shell<\/h3>\n<p>We can access the shell of GitLab over the SSH protocol to download the code and upload the changes from the local to the remote.<\/p>\n<p>We use the standard authentication methods to securely perform these Git operations on GitLab.<\/p>\n<p>The storage and access of  Git in GitLab is handled by <strong>Gitaly<\/strong>.<\/p>\n<h3 id=\"gitaly\">Gitaly<\/h3>\n<p>The storage of the GitLab for the <strong>code we store<\/strong> is managed by a service called <strong>Gitaly<\/strong>.<\/p>\n<p>The requests come from Rails and Shell for the Git operations, such as push, commit, MR, etc. These components talk to Gitaly through the <strong>gRPC<\/strong> protocol.<\/p>\n<h3 id=\"sidekiq\">Sidekiq<\/h3>\n<p>Sidekiq is a <strong>background job processing<\/strong> unit for long running tasks. <\/p>\n<p>For example, a task needs to send hundreds of emails to users, and Rails creates a job queue in Redis.<\/p>\n<p>The Sidekiq workers then pick them and execute. So the main requests will not be affected.<\/p>\n<h3 id=\"redis\">Redis<\/h3>\n<p><strong>Redis<\/strong> server is an<strong> in memory store<\/strong> of GitLab to store the temporary data for the following key operations.<\/p>\n<ul>\n<li>Queue system for the Sidekiq jobs<\/li>\n<li>A caching system for the frequently accessed data.<\/li>\n<li>Store temporary information of the applications, like the state of a CI\/CD job.<\/li>\n<\/ul>\n<p>All the long lived data will be stored in the <a href=\"https:\/\/devopscube.com\/install-postgresql-on-ubuntu\/\" rel=\"noreferrer\">PostgreSQL<\/a> database.<\/p>\n<h3 id=\"postgresql\">PostgreSQL<\/h3>\n<p><strong>PostgreSQL<\/strong> is a relational database that <strong>stores long lived data<\/strong> like user account information, project information, permissions, issues, and MR, pipeline metadata, registry metadata, etc.<\/p>\n<h3 id=\"gitlab-bare-repository\">GitLab Bare Repository<\/h3>\n<p>In Gitlab, every project has a <strong>bare repository<\/strong> on the server side. It is a special type of Git repository that does not have a working directory.<\/p>\n<p>Normally, in a local Git repository, the <code>.git<\/code> directory stores all the data commits, branches, tags, and history.<\/p>\n<p>In GitLab, only this <code>.git<\/code> data is stored on the server. That is what forms the <strong>bare repository<\/strong>. This repository exists mainly for <strong>synchronization. <\/strong><\/p>\n<p>In short, the bare repository in GitLab exists mainly to implement core Git functionality (git push, git pull etc)<\/p>\n<p>Also, all GitLab components, such as GitLab Rails, GitLab Shell, and Gitaly, work together to handle these Git operations, whether they come through HTTP or SSH.<\/p>\n<h2 id=\"gitlab-storage-and-data-persistence\">GitLab Storage and Data Persistence<\/h2>\n<p>We have already looked at the storage components of GitLab individually. <\/p>\n<p>Overall, here is how storage works in Gitlab.<\/p>\n<ol>\n<li>All the GitLab repository information is stored in the <strong>bare repository <\/strong>(like a database of repositories) and the data is stored in the file system by the <strong>Gitaly<\/strong> server.<\/li>\n<li>All the <strong>metadata<\/strong> (users, projects, issues, CI\/CD builds, labels, etc) of GitLab is stored in the <strong>PostgreSQL<\/strong> database.<\/li>\n<li>GitLab uses a multi layer <a href=\"https:\/\/docs.gitlab.com\/development\/caching\/?ref=devopscube.com\" rel=\"noreferrer\"><strong>cache<\/strong><\/a> using <strong>Redis, In-memory and HTTP<\/strong> for quick response, also uses for the job queues.<\/li>\n<\/ol>\n<div class=\"kg-card kg-callout-card kg-callout-card-blue\">\n<div class=\"kg-callout-emoji\">\ud83d\udca1<\/div>\n<div class=\"kg-callout-text\">To store the <b><strong style=\"white-space: pre-wrap;\">large binary data<\/strong><\/b> like CI\/CD artifacts, package registries, attachments, etc, we can use <b><strong style=\"white-space: pre-wrap;\">object storage<\/strong><\/b> like <a href=\"https:\/\/devopscube.com\/mount-aws-s3-bucket-to-ec2-instance\/\" rel=\"noreferrer\">AWS S3<\/a>, Azure Blob, or MinIO.<\/div>\n<\/div>\n<h2 id=\"gitlab-scaling-and-high-availability\">GitLab Scaling and High Availability <\/h2>\n<p>When implementing Gitlab in <a href=\"https:\/\/devopscube.com\/devops-projects\/\" rel=\"noreferrer\">DevOps projects<\/a>, scaling &amp; avaialbilty  ]becomes a key part when the projects grow. For example, if a central platform team provides GitLab as a service, many teams may onboard to the same GitLab instance.<\/p>\n<p>In such cases, you dont need to scale the entire GitLab system at once. Instead, you can scale individual components based on the workload and requirements.<\/p>\n<p>For example, PostgreSQL, Redis, and Gitaly are the <strong>stateful components<\/strong> and these handle heavy I\/O and background operations. So instead of running them a single instances, you can deploy them a clusters.<\/p>\n<p>The replicas in the clusters should <strong>span multiple zones<\/strong> for high availability. Also, periodic backups will help in <a href=\"https:\/\/docs.gitlab.com\/administration\/geo\/disaster_recovery\/?ref=devopscube.com\" rel=\"noreferrer\">disaster recovery <\/a>scenarios.<\/p>\n<h2 id=\"gitlab-authentication\">GitLab Authentication<\/h2>\n<p>GitLab by default, provides the standard login using username and password. Additionally you can enable Two-Factor authentication to improve security.<\/p>\n<p>For enterprise setups, you can use the <strong>external <\/strong><a href=\"https:\/\/docs.gitlab.com\/administration\/auth\/?ref=devopscube.com\" rel=\"noreferrer\"><strong>authentication providers<\/strong><\/a> such as LDAP, SAML, or OAuth2 for the user authentication.<\/p>\n<p>To securely access the GitLab shell for the Git operation, we can use the <a href=\"https:\/\/devopscube.com\/generate-ssh-key-pair\/\" rel=\"noreferrer\">Secure Shell (SSH)<\/a> method.<\/p>\n<p>For API based authentication, you can use the Personal Access Tokens (PATs) or Bearer Token.<\/p>\n<h2 id=\"gitlab-authorization\">GitLab Authorization<\/h2>\n<p>We can control access to Gitlab by assigning permissions to users or applications, specifying what actions they are allowed to perform and on which resources.<\/p>\n<p>GitLab follows a <strong>hierarchical permission model<\/strong>, where access can be granted at either the group level or the project level.<\/p>\n<p>The following are the roles that we can assign.<\/p>\n<ol>\n<li>Guest (view only)<\/li>\n<li>Reporter (Read all &amp; Issues management)<\/li>\n<li>Developer (Read &amp; Write)<\/li>\n<li>Maintainer (Project Admin &#8211; Almost full control)<\/li>\n<li>Owner (Full control)<\/li>\n<\/ol>\n<h2 id=\"gitlab-monitoring-with-prometheus-grafana\">GitLab Monitoring with Prometheus &amp; Grafana<\/h2>\n<p>A Self-hosted GitLab insrtance can be monitored using <a href=\"https:\/\/devopscube.com\/prometheus-architecture\/\" rel=\"noreferrer\">Prometheus <\/a>and <a href=\"https:\/\/devopscube.com\/setup-grafana-kubernetes\/\" rel=\"noreferrer\">Grafana<\/a>. We can track all the performance, system health and issues using its internal metrics and visualize them on <a href=\"https:\/\/devopscube.com\/integrate-visualize-prometheus-grafana\/\" rel=\"noreferrer\">dashbaords<\/a>.<\/p>\n<p>GitLab also stores logs for all its components in a central location at <code>\/var\/log\/gitlab\/<\/code>. You can use log collectors such as Fluent Bit to gather these logs and send them to a <a href=\"https:\/\/devopscube.com\/setup-grafana-loki\/\" rel=\"noreferrer\">central logging<\/a> or monitoring system for further analysis.<\/p>\n<h2 id=\"conclusion\">Conclusion<\/h2>\n<p>Thats a wrap!<\/p>\n<p>In this blog, we have looked at the Gitlab architecture and how all the key components interact behind the scenes.<\/p>\n<p>We also discussed important topics such as storage, scalability, authentication, and authorization, which are very important in enterprise environments.<\/p>\n<p>To know more about how real organizations use GitLab for their project, you can refer to this <a href=\"https:\/\/about.gitlab.com\/customers\/all\/?ref=devopscube.com\" rel=\"noreferrer\">official documentation.<\/a><\/p>\n<p>In the upcoming blogs, we will cover the setup and configurations of GitLab.<\/p>\n<hr>\n<p><strong>Ngu\u1ed3n:<\/strong> <a href=\"https:\/\/devopscube.com\/gitlab-architecture\/\" target=\"_blank\" rel=\"noopener noreferrer\">GitLab Architecture: A Complete Guide \u2014 DevOpsCube<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Source: https:\/\/devopscube.com\/gitlab-architecture\/<\/p>\n","protected":false},"author":1,"featured_media":237,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-236","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-devops"],"_links":{"self":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/posts\/236","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=236"}],"version-history":[{"count":0,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/posts\/236\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/media\/237"}],"wp:attachment":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=236"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=236"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=236"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}