[{"data":1,"prerenderedAt":1183},["ShallowReactive",2],{"/blog/how-to-access-gitlab-on-a-private-network-with-tailscale":3,"navigation-en-us":397,"banner-en-us":823,"footer-en-us":833,"blog-post-authors-en-us-Brendan O'Leary":1078,"blog-related-posts-en-us-how-to-access-gitlab-on-a-private-network-with-tailscale":1093,"blog-promotions-en-us":1119,"next-steps-en-us":1173},{"id":4,"title":5,"authors":6,"body":8,"category":375,"date":376,"description":377,"extension":378,"externalUrl":379,"faq":379,"featured":380,"heroImage":381,"meta":382,"navigation":383,"path":384,"seo":385,"slug":389,"stem":390,"tags":391,"template":395,"updatedDate":379,"__hash__":396},"blogPosts/en-us/blog/how-to-access-gitlab-on-a-private-network-with-tailscale.md","How to access GitLab on a private network with Tailscale",[7],"Brendan O'Leary",{"type":9,"value":10,"toc":366},"minimark",[11,22,25,44,53,57,71,80,83,87,95,106,110,130,133,159,166,175,179,182,189,197,200,204,207,237,240,265,271,318,325,340,351,355,362],[12,13,14,15,21],"p",{},"GitLab provides an easy-to-install package for most Linux distributions and even for devices like the ",[16,17,20],"a",{"href":18,"rel":19},"https://docs.gitlab.com/omnibus/settings/rpi/",[],"Raspberry Pi",". However, if you want to install GitLab in a home lab or similar private network, you would then be faced with a new issue: how do you access the instance from outside that private network?",[12,23,24],{},"Traditionally, you would set up your router to forward traffic from your public IP address to the server inside your network. However, this comes with several drawbacks:",[26,27,28,32,35],"ul",{},[29,30,31],"li",{},"Opening a port on your home or private network comes with a sustainable amount of risk.",[29,33,34],{},"It can be hard or impossible for folks to do depending on their internet service provider and what routing equipment they use.",[29,36,37,38,43],{},"It can be especially tough if your ISP doesn't provide you with a statically assigned IP address which means your address can change from time to time, and you'll need to either update DNS manually or through some third-party ",[16,39,42],{"href":40,"rel":41},"https://www.cloudflare.com/learning/dns/glossary/dynamic-dns/",[],"dynamic DNS"," service.",[12,45,46,47,52],{},"For me, all of these challenges have meant that I've only ever really run GitLab \"for fun\" on my local network. Given the challenges above, running a permanent installation wasn't an option. That is until ",[16,48,51],{"href":49,"rel":50},"https://tailscale.com",[],"Tailscale"," entered my life.",[54,55,51],"h2",{"id":56},"tailscale",[12,58,59,60,65,66,70],{},"Tailscale isn't necessarily the \"newest\" technology. In fact, it is based on the ",[16,61,64],{"href":62,"rel":63},"https://www.wireguard.com/",[],"WireGuard protocol",", which has existed in one form or another since 2015 and has seen native kernel support added to various Linux distributions as well as the kernel itself over the past several years.  Wireguard VPN technology makes considerable improvements in the usability and setup of virtual private networks over earlier protocols like IPsec. Even with being easier to use, the \"problem\" with WireGuard, at least for me, was always that it was still too complex to set up and maintain. Much like configuring my ISP's router for port forwarding, it wasn't ",[67,68,69],"em",{},"impossible",", but it just wasn't practical.",[12,72,73,74,79],{},"Enter Tailscale. Tailscale provides a simple piece of client software, available for Linux, Mac, and Windows (and iOS and Android!), which implements the WireGuard protocol and allows you to control your VPN network from a handy web interface. Not only that, it's ",[16,75,78],{"href":76,"rel":77},"https://tailscale.com/pricing/",[],"free to use"," for individuals and small networks. When I started using Tailscale, it was to make sure I could connect back to my home network and troubleshoot it while traveling for work. As the only system administrator in my house, this was fantastic.",[12,81,82],{},"However, Tailscale also offers the ability to easily access services inside of various networks as well by setting up a mesh VPN between them, all with IP addresses in the 100.x.y.z range. That means for any web service or other service on my network, I can access it with a statically assigned IP address from any other device connected to Tailscale, and create a DNS record to have a domain point to the IP address. At last, I could run GitLab (and other open source tools) at home and safely connect to them from outside my house with as little hassle as possible. So how did I get it to work?",[54,84,86],{"id":85},"tailscale-and-gitlab-together","Tailscale and GitLab together",[12,88,89,90,94],{},"Assuming you already have a GitLab ",[16,91,93],{"href":92},"/install/","installation"," up and running on your network, getting it working through Tailscale involves a few steps:",[26,96,97,100,103],{},[29,98,99],{},"Installing Tailscale",[29,101,102],{},"Setting up DNS for the private address",[29,104,105],{},"Configuring HTTPS encryption",[107,108,99],"h3",{"id":109},"installing-tailscale",[12,111,112,113,118,119,123,124,129],{},"Packages are ",[16,114,117],{"href":115,"rel":116},"https://tailscale.com/kb/1031/install-linux/",[],"available"," for many Linux distributions. To install Tailscale, you can select your ",[16,120,122],{"href":115,"rel":121},[],"specific distribution"," for detailed instructions. There are also ",[16,125,128],{"href":126,"rel":127},"https://tailscale.com/kb/1053/install-static/",[],"static binaries"," if you can't find your particular distribution - they are available for x86 and ARM CPUs for both 32- and 64-bit variants.",[12,131,132],{},"Once Tailscale is installed, getting it running is as simple as running the following command on the CLI:",[134,135,140],"pre",{"className":136,"code":137,"language":138,"meta":139,"style":139},"language-bash shiki shiki-themes github-light","sudo tailscale up\n","bash","",[141,142,143],"code",{"__ignoreMap":139},[144,145,148,152,156],"span",{"class":146,"line":147},"line",1,[144,149,151],{"class":150},"s7eDp","sudo",[144,153,155],{"class":154},"sYBdl"," tailscale",[144,157,158],{"class":154}," up\n",[12,160,161,162,165],{},"The setup dialogue will walk you through the authentication process and get Tailscale running. After that process, you can see your new IP address for this node on your network with the CLI command ",[141,163,164],{},"tailscale ip -4",". You'll need that IP address for the next steps.",[12,167,168,169,174],{},"By default, Tailscale will set an expiration date for the token it issues to your device during the authentication process. This is desirable for typical devices that may be transient or portable. However, suppose your device is secured inside your home or another secure place AND is a server you're not accessing all the time. In that case, you can optionally ",[16,170,173],{"href":171,"rel":172},"https://tailscale.com/kb/1028/key-expiry/",[],"disable key expiry"," for that particular device.",[107,176,178],{"id":177},"setting-up-dns","Setting up DNS",[12,180,181],{},"You should be able to now access your device from any other Tailscale-connected device via the IP address from the last step. However, my goal was to make it easy for me to connect to GitLab, reference it by an URL, and encrypt the traffic end-to-end with TLS. As the next step I set up DNS.",[12,183,184,185,188],{},"Even though the 100.x.y.z address is a private IP address, you can still create a public DNS record and have the hostname to point to it. That won't mean the whole world can access your server - it just means once you're connected to your Tailscale network, you can resolve that hostname to the IP address and access the web server. For me, I set up an A record for ",[141,186,187],{},"gitpi.boleary.dev"," to resolve to an IPv4 address:",[134,190,195],{"className":191,"code":193,"language":194,"meta":139},[192],"language-text",";; QUESTION SECTION:\n;gitpi.boleary.dev.     IN  A\n\n;; ANSWER SECTION:\ngitpi.boleary.dev.  300 IN  A   100.64.205.40\n","text",[141,196,193],{"__ignoreMap":139},[12,198,199],{},"An important note here is that I use Cloudflare as my DNS provider - and I usually love Cloudflare's proxying service to make my \"real\" IP addresses private. In this case, you have to disable that proxying to make sure that you can resolve the correct address - Cloudflare can't proxy traffic into your Tailscale network.",[107,201,203],{"id":202},"configuring-https","Configuring HTTPS",[12,205,206],{},"Lastly, configuring HTTPS for your GitLab instance will ensure that all traffic is encrypted end-to-end. While Tailscale encrypts the traffic over the network, this will ensure there are no gaps between your device and your GitLab server.",[12,208,209,210,217,218,223,224,226,227,230,231,236],{},"To accomplish this, we'll use ",[16,211,214],{"href":212,"rel":213},"https://certbot.eff.org/",[],[141,215,216],{},"certbot"," from the EFF that lets us create and manage ",[16,219,222],{"href":220,"rel":221},"https://letsencrypt.org/",[],"Let's Encrypt"," certificates. First, install ",[141,225,216],{}," with ",[141,228,229],{},"sudo apt install certbot"," or follow the ",[16,232,235],{"href":233,"rel":234},"https://certbot.eff.org/instructions",[],"instructions for your distribution",".",[12,238,239],{},"After certbot is installed, issue a certificate to use with GitLab using a DNS challenge. Follow the steps to complete the DNS challenge after running this command:",[134,241,243],{"className":136,"code":242,"language":138,"meta":139,"style":139},"sudo certbot certonly --manual --preferred-challenges dns\n",[141,244,245],{"__ignoreMap":139},[144,246,247,249,252,255,259,262],{"class":146,"line":147},[144,248,151],{"class":150},[144,250,251],{"class":154}," certbot",[144,253,254],{"class":154}," certonly",[144,256,258],{"class":257},"sYu0t"," --manual",[144,260,261],{"class":257}," --preferred-challenges",[144,263,264],{"class":154}," dns\n",[12,266,267,268,270],{},"The output will show you the specific location of the certificate it created (in my case, in a ",[141,269,187],{}," folder), and you should link that certificate to GitLab's SSL directory by running:",[134,272,274],{"className":136,"code":273,"language":138,"meta":139,"style":139},"sudo mkdir /etc/gitlab/ssl/\nsudo ln -s /etc/letsencrypt/live/gitpi.boleary.dev/fullchain.pem /etc/gitlab/ssl/gitpi.boleary.dev.crt\nsudo ln -s /etc/letsencrypt/live/gitpi.boleary.dev/privkey.pem /etc/gitlab/ssl/gitpi.boleary.dev.key\n",[141,275,276,286,303],{"__ignoreMap":139},[144,277,278,280,283],{"class":146,"line":147},[144,279,151],{"class":150},[144,281,282],{"class":154}," mkdir",[144,284,285],{"class":154}," /etc/gitlab/ssl/\n",[144,287,289,291,294,297,300],{"class":146,"line":288},2,[144,290,151],{"class":150},[144,292,293],{"class":154}," ln",[144,295,296],{"class":257}," -s",[144,298,299],{"class":154}," /etc/letsencrypt/live/gitpi.boleary.dev/fullchain.pem",[144,301,302],{"class":154}," /etc/gitlab/ssl/gitpi.boleary.dev.crt\n",[144,304,306,308,310,312,315],{"class":146,"line":305},3,[144,307,151],{"class":150},[144,309,293],{"class":154},[144,311,296],{"class":257},[144,313,314],{"class":154}," /etc/letsencrypt/live/gitpi.boleary.dev/privkey.pem",[144,316,317],{"class":154}," /etc/gitlab/ssl/gitpi.boleary.dev.key\n",[12,319,320,321,324],{},"Next, configure GitLab to use the new certificate by opening the ",[141,322,323],{},"gitlab.rb"," with",[134,326,328],{"className":136,"code":327,"language":138,"meta":139,"style":139},"sudo vi /etc/gitlab/gitlab.rb\n",[141,329,330],{"__ignoreMap":139},[144,331,332,334,337],{"class":146,"line":147},[144,333,151],{"class":150},[144,335,336],{"class":154}," vi",[144,338,339],{"class":154}," /etc/gitlab/gitlab.rb\n",[12,341,342,343,346,347,350],{},"And change the ",[141,344,345],{},"external_url"," value to match the URL for the certificate (e.g. ",[141,348,349],{},"https://gitpi.boleary.dev","). That \"https\" will tell GitLab to enable TLS/SSL and use your linked certificate.",[54,352,354],{"id":353},"finishing-up","Finishing up",[12,356,357,358,361],{},"That's it! Now with a simple ",[141,359,360],{},"gitlab-ctl reconfigure",", GitLab will pick up the new certificate and start responding to requests at that URL. From any device - iOS, Android, laptop, etc. - connected to your Tailscale network, you can access your GitLab installation (securely) from anywhere!",[363,364,365],"style",{},"html pre.shiki code .s7eDp, html code.shiki .s7eDp{--shiki-default:#6F42C1}html pre.shiki code .sYBdl, html code.shiki .sYBdl{--shiki-default:#032F62}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sYu0t, html code.shiki .sYu0t{--shiki-default:#005CC5}",{"title":139,"searchDepth":288,"depth":288,"links":367},[368,369,374],{"id":56,"depth":288,"text":51},{"id":85,"depth":288,"text":86,"children":370},[371,372,373],{"id":109,"depth":305,"text":99},{"id":177,"depth":305,"text":178},{"id":202,"depth":305,"text":203},{"id":353,"depth":288,"text":354},"engineering","2022-07-21","If issues around a private network were preventing a permanent GitLab installation, Brendan O'Leary has the solution with Tailscale.","md",null,false,"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749679348/Blog/Hero%20Images/locks.jpg",{},true,"/en-us/blog/how-to-access-gitlab-on-a-private-network-with-tailscale",{"title":5,"description":377,"ogTitle":5,"ogDescription":377,"noIndex":380,"ogImage":381,"ogUrl":386,"ogSiteName":387,"ogType":388,"canonicalUrls":386},"https://about.gitlab.com/blog/how-to-access-gitlab-on-a-private-network-with-tailscale","https://about.gitlab.com","article","how-to-access-gitlab-on-a-private-network-with-tailscale","en-us/blog/how-to-access-gitlab-on-a-private-network-with-tailscale",[392,393,394],"tutorial","open source","integrations","BlogPost","GG8frVBOzthZ2of1qMtP8-v08vZ8PWNZdfH7KkDleRk",{"logo":398,"freeTrial":403,"sales":408,"login":413,"items":418,"search":743,"minimal":774,"duo":793,"switchNav":802,"pricingDeployment":813},{"config":399},{"href":400,"dataGaName":401,"dataGaLocation":402},"/","gitlab logo","header",{"text":404,"config":405},"Get free trial",{"href":406,"dataGaName":407,"dataGaLocation":402},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":409,"config":410},"Request a demo",{"href":411,"dataGaName":412,"dataGaLocation":402},"/sales/?contact-topic=request-demo","sales",{"text":414,"config":415},"Sign in",{"href":416,"dataGaName":417,"dataGaLocation":402},"https://gitlab.com/users/sign_in/","sign in",[419,448,548,553,665,721],{"text":420,"config":421,"menu":423},"Platform",{"dataNavLevelOne":422},"platform",{"type":424,"columns":425},"cards",[426,432,440],{"title":420,"description":427,"link":428},"The intelligent orchestration platform for DevSecOps",{"text":429,"config":430},"Explore our Platform",{"href":431,"dataGaName":422,"dataGaLocation":402},"/platform/",{"title":433,"description":434,"link":435},"GitLab Duo Agent Platform","Agentic AI for the entire software lifecycle",{"text":436,"config":437},"Meet GitLab Duo",{"href":438,"dataGaName":439,"dataGaLocation":402},"/gitlab-duo-agent-platform/","gitlab duo agent platform",{"title":441,"description":442,"link":443},"Why GitLab","See the top reasons enterprises choose GitLab",{"text":444,"config":445},"Learn more",{"href":446,"dataGaName":447,"dataGaLocation":402},"/why-gitlab/","why gitlab",{"text":449,"left":383,"config":450,"menu":452},"Product",{"dataNavLevelOne":451},"solutions",{"type":453,"link":454,"columns":458,"feature":527},"lists",{"text":455,"config":456},"View all Solutions",{"href":457,"dataGaName":451,"dataGaLocation":402},"/solutions/",[459,483,506],{"title":460,"description":461,"link":462,"items":467},"Automation","CI/CD and automation to accelerate deployment",{"config":463},{"icon":464,"href":465,"dataGaName":466,"dataGaLocation":402},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[468,472,475,479],{"text":469,"config":470},"CI/CD",{"href":471,"dataGaLocation":402,"dataGaName":469},"/solutions/continuous-integration/",{"text":433,"config":473},{"href":438,"dataGaLocation":402,"dataGaName":474},"gitlab duo agent platform - product menu",{"text":476,"config":477},"Source Code Management",{"href":478,"dataGaLocation":402,"dataGaName":476},"/solutions/source-code-management/",{"text":480,"config":481},"Automated Software Delivery",{"href":465,"dataGaLocation":402,"dataGaName":482},"Automated software delivery",{"title":484,"description":485,"link":486,"items":491},"Security","Deliver code faster without compromising security",{"config":487},{"href":488,"dataGaName":489,"dataGaLocation":402,"icon":490},"/solutions/application-security-testing/","security and compliance","ShieldCheckLight",[492,496,501],{"text":493,"config":494},"Application Security Testing",{"href":488,"dataGaName":495,"dataGaLocation":402},"Application security testing",{"text":497,"config":498},"Software Supply Chain Security",{"href":499,"dataGaLocation":402,"dataGaName":500},"/solutions/supply-chain/","Software supply chain security",{"text":502,"config":503},"Software Compliance",{"href":504,"dataGaName":505,"dataGaLocation":402},"/solutions/software-compliance/","software compliance",{"title":507,"link":508,"items":513},"Measurement",{"config":509},{"icon":510,"href":511,"dataGaName":512,"dataGaLocation":402},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[514,518,522],{"text":515,"config":516},"Visibility & Measurement",{"href":511,"dataGaLocation":402,"dataGaName":517},"Visibility and Measurement",{"text":519,"config":520},"Value Stream Management",{"href":521,"dataGaLocation":402,"dataGaName":519},"/solutions/value-stream-management/",{"text":523,"config":524},"Analytics & Insights",{"href":525,"dataGaLocation":402,"dataGaName":526},"/solutions/analytics-and-insights/","Analytics and insights",{"title":528,"type":453,"items":529},"GitLab for",[530,536,542],{"text":531,"config":532},"Enterprise",{"icon":533,"href":534,"dataGaLocation":402,"dataGaName":535},"Building","/enterprise/","enterprise",{"text":537,"config":538},"Small Business",{"icon":539,"href":540,"dataGaLocation":402,"dataGaName":541},"Work","/small-business/","small business",{"text":543,"config":544},"Public Sector",{"icon":545,"href":546,"dataGaLocation":402,"dataGaName":547},"Organization","/solutions/public-sector/","public sector",{"text":549,"config":550},"Pricing",{"href":551,"dataGaName":552,"dataGaLocation":402,"dataNavLevelOne":552},"/pricing/","pricing",{"text":554,"config":555,"menu":557},"Resources",{"dataNavLevelOne":556},"resources",{"type":453,"link":558,"columns":562,"feature":654},{"text":559,"config":560},"View all resources",{"href":561,"dataGaName":556,"dataGaLocation":402},"/resources/",[563,594,621],{"title":564,"items":565},"Getting started",[566,570,575,580,585,590],{"text":567,"config":568},"Install",{"href":92,"dataGaName":569,"dataGaLocation":402},"install",{"text":571,"config":572},"Quick start guides",{"href":573,"dataGaName":574,"dataGaLocation":402},"/get-started/","quick setup checklists",{"text":576,"config":577},"Learn",{"href":578,"dataGaLocation":402,"dataGaName":579},"https://university.gitlab.com/","learn",{"text":581,"config":582},"Product documentation",{"href":583,"dataGaName":584,"dataGaLocation":402},"https://docs.gitlab.com/","product documentation",{"text":586,"config":587},"Best practice videos",{"href":588,"dataGaName":589,"dataGaLocation":402},"/getting-started-videos/","best practice videos",{"text":591,"config":592},"Integrations",{"href":593,"dataGaName":394,"dataGaLocation":402},"/integrations/",{"title":595,"items":596},"Discover",[597,602,607,612,616],{"text":598,"config":599},"Customer success stories",{"href":600,"dataGaName":601,"dataGaLocation":402},"/customers/","customer success stories",{"text":603,"config":604},"Blog",{"href":605,"dataGaName":606,"dataGaLocation":402},"/blog/","blog",{"text":608,"config":609},"Demo Hub",{"href":610,"dataGaName":611,"dataGaLocation":402},"/demo-hub/","demo hub",{"text":613,"config":614},"The Source",{"href":615,"dataGaName":606,"dataGaLocation":402},"/the-source/",{"text":617,"config":618},"Remote",{"href":619,"dataGaName":620,"dataGaLocation":402},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"title":622,"items":623},"Connect",[624,629,634,639,644,649],{"text":625,"config":626},"GitLab Services",{"href":627,"dataGaName":628,"dataGaLocation":402},"/services/","services",{"text":630,"config":631},"Contribute",{"href":632,"dataGaName":633,"dataGaLocation":402},"https://contributors.gitlab.com","contribute",{"text":635,"config":636},"Community",{"href":637,"dataGaName":638,"dataGaLocation":402},"/community/","community",{"text":640,"config":641},"Forum",{"href":642,"dataGaName":643,"dataGaLocation":402},"https://forum.gitlab.com/","forum",{"text":645,"config":646},"Events",{"href":647,"dataGaName":648,"dataGaLocation":402},"/events/","events",{"text":650,"config":651},"Partners",{"href":652,"dataGaName":653,"dataGaLocation":402},"/partners/","partners",{"config":655,"title":658,"text":659,"link":660},{"background":656,"textColor":657},"url('https://res.cloudinary.com/about-gitlab-com/image/upload/v1777322348/qpq8yrgn8knii57omj0c.png')","#000","What’s new in GitLab","Stay updated with our latest features and improvements.",{"text":661,"config":662},"Read the latest",{"href":663,"dataGaName":664,"dataGaLocation":402},"/whats-new/","whats new",{"text":666,"config":667,"menu":669},"Company",{"dataNavLevelOne":668},"company",{"type":453,"columns":670},[671],{"items":672},[673,678,684,686,691,696,701,706,711,716],{"text":674,"config":675},"About",{"href":676,"dataGaName":677,"dataGaLocation":402},"/company/","about",{"text":679,"config":680,"footerGa":683},"Jobs",{"href":681,"dataGaName":682,"dataGaLocation":402},"/jobs/","jobs",{"dataGaName":682},{"text":645,"config":685},{"href":647,"dataGaName":648,"dataGaLocation":402},{"text":687,"config":688},"Leadership",{"href":689,"dataGaName":690,"dataGaLocation":402},"/company/team/e-group/","leadership",{"text":692,"config":693},"Handbook",{"href":694,"dataGaName":695,"dataGaLocation":402},"https://handbook.gitlab.com/","handbook",{"text":697,"config":698},"Investor relations",{"href":699,"dataGaName":700,"dataGaLocation":402},"https://ir.gitlab.com/overview/default.aspx","investor relations",{"text":702,"config":703},"Trust Center",{"href":704,"dataGaName":705,"dataGaLocation":402},"/security/","trust center",{"text":707,"config":708},"AI Transparency Center",{"href":709,"dataGaName":710,"dataGaLocation":402},"/ai-transparency-center/","ai transparency center",{"text":712,"config":713},"Newsletter",{"href":714,"dataGaName":715,"dataGaLocation":402},"/company/contact/#contact-forms","newsletter",{"text":717,"config":718},"Press",{"href":719,"dataGaName":720,"dataGaLocation":402},"/press/","press",{"text":722,"config":723,"menu":724},"Contact us",{"dataNavLevelOne":668},{"type":453,"columns":725},[726],{"items":727},[728,733,738],{"text":729,"config":730},"Talk to sales",{"href":731,"dataGaName":732,"dataGaLocation":402},"/sales/","talk to sales",{"text":734,"config":735},"Support portal",{"href":736,"dataGaName":737,"dataGaLocation":402},"https://support.gitlab.com/hc/en-us","support portal",{"text":739,"config":740},"Customer portal",{"href":741,"dataGaName":742,"dataGaLocation":402},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":744,"login":745,"suggestions":752},"Close",{"text":746,"link":747},"To search repositories and projects, login to",{"text":748,"config":749},"gitlab.com",{"href":416,"dataGaName":750,"dataGaLocation":751},"search login","search",{"text":753,"default":754},"Suggestions",[755,757,761,763,767,771],{"text":433,"config":756},{"href":438,"dataGaName":433,"dataGaLocation":751},{"text":758,"config":759},"Code Suggestions (AI)",{"href":760,"dataGaName":758,"dataGaLocation":751},"/solutions/code-suggestions/",{"text":469,"config":762},{"href":471,"dataGaName":469,"dataGaLocation":751},{"text":764,"config":765},"GitLab on AWS",{"href":766,"dataGaName":764,"dataGaLocation":751},"/partners/technology-partners/aws/",{"text":768,"config":769},"GitLab on Google Cloud",{"href":770,"dataGaName":768,"dataGaLocation":751},"/partners/technology-partners/google-cloud-platform/",{"text":772,"config":773},"Why GitLab?",{"href":446,"dataGaName":772,"dataGaLocation":751},{"freeTrial":775,"mobileIcon":780,"desktopIcon":785,"secondaryButton":788},{"text":776,"config":777},"Start free trial",{"href":778,"dataGaName":407,"dataGaLocation":779},"https://gitlab.com/-/trials/new/","nav",{"altText":781,"config":782},"Gitlab Icon",{"src":783,"dataGaName":784,"dataGaLocation":779},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":781,"config":786},{"src":787,"dataGaName":784,"dataGaLocation":779},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":789,"config":790},"Get Started",{"href":791,"dataGaName":792,"dataGaLocation":779},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/get-started/","get started",{"freeTrial":794,"mobileIcon":798,"desktopIcon":800},{"text":795,"config":796},"Learn more about GitLab Duo",{"href":438,"dataGaName":797,"dataGaLocation":779},"gitlab duo",{"altText":781,"config":799},{"src":783,"dataGaName":784,"dataGaLocation":779},{"altText":781,"config":801},{"src":787,"dataGaName":784,"dataGaLocation":779},{"button":803,"mobileIcon":808,"desktopIcon":810},{"text":804,"config":805},"/switch",{"href":806,"dataGaName":807,"dataGaLocation":779},"#contact","switch",{"altText":781,"config":809},{"src":783,"dataGaName":784,"dataGaLocation":779},{"altText":781,"config":811},{"src":812,"dataGaName":784,"dataGaLocation":779},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1773335277/ohhpiuoxoldryzrnhfrh.png",{"freeTrial":814,"mobileIcon":819,"desktopIcon":821},{"text":815,"config":816},"Back to pricing",{"href":551,"dataGaName":817,"dataGaLocation":779,"icon":818},"back to pricing","GoBack",{"altText":781,"config":820},{"src":783,"dataGaName":784,"dataGaLocation":779},{"altText":781,"config":822},{"src":787,"dataGaName":784,"dataGaLocation":779},{"title":824,"titleMobile":825,"button":826,"config":831},"Duo Agent Platform delivers 400% ROI, per new Forrester Consulting study.","400% ROI: Forrester TEI for GitLab Duo",{"text":444,"config":827},{"href":828,"dataGaName":829,"dataGaLocation":830},"https://about.gitlab.com/blog/gitlab-duo-agent-platform-delivers-400-percent-roi/","forrester-tei-dap-banner","global-banner",{"layout":832,"disabled":380},"release",{"data":834},{"text":835,"source":836,"edit":842,"contribute":847,"config":852,"items":857,"minimal":1067},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":837,"config":838},"View page source",{"href":839,"dataGaName":840,"dataGaLocation":841},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":843,"config":844},"Edit this page",{"href":845,"dataGaName":846,"dataGaLocation":841},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":848,"config":849},"Please contribute",{"href":850,"dataGaName":851,"dataGaLocation":841},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":853,"facebook":854,"youtube":855,"linkedin":856},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[858,905,959,1003,1035],{"title":549,"links":859,"subMenu":874},[860,864,869],{"text":861,"config":862},"View plans",{"href":551,"dataGaName":863,"dataGaLocation":841},"view plans",{"text":865,"config":866},"Why Premium?",{"href":867,"dataGaName":868,"dataGaLocation":841},"/pricing/premium/","why premium",{"text":870,"config":871},"Why Ultimate?",{"href":872,"dataGaName":873,"dataGaLocation":841},"/pricing/ultimate/","why ultimate",[875],{"title":876,"links":877},"Contact Us",[878,881,883,885,890,895,900],{"text":879,"config":880},"Contact sales",{"href":731,"dataGaName":412,"dataGaLocation":841},{"text":734,"config":882},{"href":736,"dataGaName":737,"dataGaLocation":841},{"text":739,"config":884},{"href":741,"dataGaName":742,"dataGaLocation":841},{"text":886,"config":887},"Status",{"href":888,"dataGaName":889,"dataGaLocation":841},"https://status.gitlab.com/","status",{"text":891,"config":892},"Terms of use",{"href":893,"dataGaName":894,"dataGaLocation":841},"/terms/","terms of use",{"text":896,"config":897},"Privacy statement",{"href":898,"dataGaName":899,"dataGaLocation":841},"/privacy/","privacy statement",{"text":901,"config":902},"Cookie preferences",{"dataGaName":903,"dataGaLocation":841,"id":904,"isOneTrustButton":383},"cookie preferences","ot-sdk-btn",{"title":449,"links":906,"subMenu":915},[907,911],{"text":908,"config":909},"DevSecOps platform",{"href":431,"dataGaName":910,"dataGaLocation":841},"devsecops platform",{"text":912,"config":913},"AI-Assisted Development",{"href":438,"dataGaName":914,"dataGaLocation":841},"ai-assisted development",[916],{"title":917,"links":918},"Topics",[919,924,929,934,939,944,949,954],{"text":920,"config":921},"CICD",{"href":922,"dataGaName":923,"dataGaLocation":841},"/topics/ci-cd/","cicd",{"text":925,"config":926},"GitOps",{"href":927,"dataGaName":928,"dataGaLocation":841},"/topics/gitops/","gitops",{"text":930,"config":931},"DevOps",{"href":932,"dataGaName":933,"dataGaLocation":841},"/topics/devops/","devops",{"text":935,"config":936},"Version Control",{"href":937,"dataGaName":938,"dataGaLocation":841},"/topics/version-control/","version control",{"text":940,"config":941},"DevSecOps",{"href":942,"dataGaName":943,"dataGaLocation":841},"/topics/devsecops/","devsecops",{"text":945,"config":946},"Cloud Native",{"href":947,"dataGaName":948,"dataGaLocation":841},"/topics/cloud-native/","cloud native",{"text":950,"config":951},"AI for Coding",{"href":952,"dataGaName":953,"dataGaLocation":841},"/topics/devops/ai-for-coding/","ai for coding",{"text":955,"config":956},"Agentic AI",{"href":957,"dataGaName":958,"dataGaLocation":841},"/topics/agentic-ai/","agentic ai",{"title":960,"links":961},"Solutions",[962,964,966,971,975,978,982,985,987,990,993,998],{"text":493,"config":963},{"href":488,"dataGaName":493,"dataGaLocation":841},{"text":482,"config":965},{"href":465,"dataGaName":466,"dataGaLocation":841},{"text":967,"config":968},"Agile development",{"href":969,"dataGaName":970,"dataGaLocation":841},"/solutions/agile-delivery/","agile delivery",{"text":972,"config":973},"SCM",{"href":478,"dataGaName":974,"dataGaLocation":841},"source code management",{"text":920,"config":976},{"href":471,"dataGaName":977,"dataGaLocation":841},"continuous integration & delivery",{"text":979,"config":980},"Value stream management",{"href":521,"dataGaName":981,"dataGaLocation":841},"value stream management",{"text":925,"config":983},{"href":984,"dataGaName":928,"dataGaLocation":841},"/solutions/gitops/",{"text":531,"config":986},{"href":534,"dataGaName":535,"dataGaLocation":841},{"text":988,"config":989},"Small business",{"href":540,"dataGaName":541,"dataGaLocation":841},{"text":991,"config":992},"Public sector",{"href":546,"dataGaName":547,"dataGaLocation":841},{"text":994,"config":995},"Education",{"href":996,"dataGaName":997,"dataGaLocation":841},"/solutions/education/","education",{"text":999,"config":1000},"Financial services",{"href":1001,"dataGaName":1002,"dataGaLocation":841},"/solutions/finance/","financial services",{"title":554,"links":1004},[1005,1007,1009,1011,1014,1016,1019,1021,1023,1025,1027,1029,1031,1033],{"text":567,"config":1006},{"href":92,"dataGaName":569,"dataGaLocation":841},{"text":571,"config":1008},{"href":573,"dataGaName":574,"dataGaLocation":841},{"text":576,"config":1010},{"href":578,"dataGaName":579,"dataGaLocation":841},{"text":581,"config":1012},{"href":583,"dataGaName":1013,"dataGaLocation":841},"docs",{"text":603,"config":1015},{"href":605,"dataGaName":606,"dataGaLocation":841},{"text":1017,"config":1018},"What's new",{"href":663,"dataGaName":664,"dataGaLocation":841},{"text":598,"config":1020},{"href":600,"dataGaName":601,"dataGaLocation":841},{"text":617,"config":1022},{"href":619,"dataGaName":620,"dataGaLocation":841},{"text":625,"config":1024},{"href":627,"dataGaName":628,"dataGaLocation":841},{"text":630,"config":1026},{"href":632,"dataGaName":633,"dataGaLocation":841},{"text":635,"config":1028},{"href":637,"dataGaName":638,"dataGaLocation":841},{"text":640,"config":1030},{"href":642,"dataGaName":643,"dataGaLocation":841},{"text":645,"config":1032},{"href":647,"dataGaName":648,"dataGaLocation":841},{"text":650,"config":1034},{"href":652,"dataGaName":653,"dataGaLocation":841},{"title":666,"links":1036},[1037,1039,1041,1043,1045,1047,1051,1056,1058,1060,1062],{"text":674,"config":1038},{"href":676,"dataGaName":668,"dataGaLocation":841},{"text":679,"config":1040},{"href":681,"dataGaName":682,"dataGaLocation":841},{"text":687,"config":1042},{"href":689,"dataGaName":690,"dataGaLocation":841},{"text":692,"config":1044},{"href":694,"dataGaName":695,"dataGaLocation":841},{"text":697,"config":1046},{"href":699,"dataGaName":700,"dataGaLocation":841},{"text":1048,"config":1049},"Sustainability",{"href":1050,"dataGaName":1048,"dataGaLocation":841},"/sustainability/",{"text":1052,"config":1053},"Diversity, inclusion and belonging (DIB)",{"href":1054,"dataGaName":1055,"dataGaLocation":841},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":702,"config":1057},{"href":704,"dataGaName":705,"dataGaLocation":841},{"text":712,"config":1059},{"href":714,"dataGaName":715,"dataGaLocation":841},{"text":717,"config":1061},{"href":719,"dataGaName":720,"dataGaLocation":841},{"text":1063,"config":1064},"Modern Slavery Transparency Statement",{"href":1065,"dataGaName":1066,"dataGaLocation":841},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"items":1068},[1069,1072,1075],{"text":1070,"config":1071},"Terms",{"href":893,"dataGaName":894,"dataGaLocation":841},{"text":1073,"config":1074},"Cookies",{"dataGaName":903,"dataGaLocation":841,"id":904,"isOneTrustButton":383},{"text":1076,"config":1077},"Privacy",{"href":898,"dataGaName":899,"dataGaLocation":841},[1079],{"id":1080,"title":1081,"body":379,"config":1082,"content":1084,"description":379,"extension":1087,"meta":1088,"navigation":383,"path":1089,"seo":1090,"stem":1091,"__hash__":1092},"blogAuthors/en-us/blog/authors/brendan-oleary.yml","Brendan Oleary",{"template":1083},"BlogAuthor",{"name":7,"config":1085},{"headshot":139,"ctfId":1086},"brendan","yml",{},"/en-us/blog/authors/brendan-oleary",{},"en-us/blog/authors/brendan-oleary","IkXVLft77WlFK-Vgo210ZM3Io_PCcrXnYzkBCzx153k",[1094,1103,1111],{"title":1095,"description":1096,"heroImage":1097,"category":375,"date":1098,"authors":1099,"slug":1102,"externalUrl":379},"Confidential AI for GitLab Self-Hosted","Give developers AI coding agents in GitLab Duo without source code leaving a hardware-encrypted boundary — no GPUs needed.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1773866173/vte9qh8rriznvyclhkes.png","2026-08-06",[1100,1101],"Mathias Ewald","Martin Paloncy, Edgeless Systems","confidential-ai-for-gitlab-self-hosted",{"title":1104,"description":1105,"heroImage":1106,"category":375,"date":1107,"authors":1108,"slug":1110,"externalUrl":379},"Green DevOps: Why carbon measurement belongs in your CI/CD pipeline","CI/CD pipelines have a hidden carbon cost. Here's why measuring it matters, and how you can get started with Eco CI and Carmen in GitLab.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1765809212/noh0mdfn9o94ry9ykura.png","2026-07-09",[1109],"Lysanne Pinto","green-devops-carbon-measurement-cicd-pipeline",{"title":1112,"description":1113,"heroImage":1114,"category":375,"date":1115,"authors":1116,"slug":1118,"externalUrl":379},"How to build CI/CD observability at scale","This practical guide to GitLab pipeline analytics helps self-managed users gain operational insights using Prometheus and Grafana.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1774465167/n5hlvrsrheadeccyr1oz.png","2026-04-28",[1117],"Paul Meresanu","how-to-build-ci-cd-observability-at-scale",{"promotions":1120},[1121,1135,1147,1159],{"id":1122,"categories":1123,"header":1125,"text":1126,"button":1127,"image":1132},"ai-modernization",[1124],"ai","Is AI achieving its promise at scale?","Quiz will take 5 minutes or less",{"text":1128,"config":1129},"Get your AI maturity score",{"href":1130,"dataGaName":1131,"dataGaLocation":606},"/assessments/ai-modernization-assessment/","modernization assessment",{"config":1133},{"src":1134},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/qix0m7kwnd8x2fh1zq49.png",{"id":1136,"categories":1137,"header":1139,"text":1126,"button":1140,"image":1144},"devops-modernization",[1138,943],"product","Are you just managing tools or shipping innovation?",{"text":1141,"config":1142},"Get your DevOps maturity score",{"href":1143,"dataGaName":1131,"dataGaLocation":606},"/assessments/devops-modernization-assessment/",{"config":1145},{"src":1146},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138785/eg818fmakweyuznttgid.png",{"id":1148,"categories":1149,"header":1151,"text":1126,"button":1152,"image":1156},"security-modernization",[1150],"security","Are you trading speed for security?",{"text":1153,"config":1154},"Get your security maturity score",{"href":1155,"dataGaName":1131,"dataGaLocation":606},"/assessments/security-modernization-assessment/",{"config":1157},{"src":1158},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/p4pbqd9nnjejg5ds6mdk.png",{"id":1160,"paths":1161,"header":1164,"text":1165,"button":1166,"image":1171},"github-azure-migration",[1162,1163],"migration-from-azure-devops-to-gitlab","integrating-azure-devops-scm-and-gitlab","Is your team ready for GitHub's Azure move?","GitHub is already rebuilding around Azure. Find out what it means for you.",{"text":1167,"config":1168},"See how GitLab compares to GitHub",{"href":1169,"dataGaName":1170,"dataGaLocation":606},"/compare/gitlab-vs-github/github-azure-migration/","github azure migration",{"config":1172},{"src":1146},{"header":1174,"blurb":1175,"button":1176,"secondaryButton":1181},"Start building faster today","See what your team can do with the intelligent orchestration platform for DevSecOps.\n",{"text":1177,"config":1178},"Get your free trial",{"href":1179,"dataGaName":407,"dataGaLocation":1180},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":879,"config":1182},{"href":731,"dataGaName":412,"dataGaLocation":1180},1786803771343]