[{"data":1,"prerenderedAt":703},["ShallowReactive",2],{"/en-us/blog/gitlab-runner-with-docker/":3,"navigation-en-us":32,"banner-en-us":449,"footer-en-us":464,"Ahmet Kizilay":675,"next-steps-en-us":688},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"seo":8,"content":16,"config":22,"_id":25,"_type":26,"title":27,"_source":28,"_file":29,"_stem":30,"_extension":31},"/en-us/blog/gitlab-runner-with-docker","blog",false,"",{"title":9,"description":10,"ogTitle":9,"ogDescription":10,"noIndex":6,"ogImage":11,"ogUrl":12,"ogSiteName":13,"ogType":14,"canonicalUrls":12,"schema":15},"Setting up GitLab Runner For Continuous Integration","This tutorial will demonstrate how to get started with a CI workflow using GitLab Runner.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749663397/Blog/Hero%20Images/logoforblogpost.jpg","https://about.gitlab.com/blog/gitlab-runner-with-docker","https://about.gitlab.com","article","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Setting up GitLab Runner For Continuous Integration\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Ahmet Kizilay\"}],\n        \"datePublished\": \"2016-03-01\",\n      }",{"title":9,"description":10,"authors":17,"heroImage":11,"date":19,"body":20,"category":21},[18],"Ahmet Kizilay","2016-03-01","\n\nThere are many cloud-based [continuous integration (CI)](/solutions/continuous-integration/) providers out there and\nmost of them generously offer free plans for open-source projects.\nWhile this is great for the open-source community, paid plans and tiers can get a little\nbit too expensive for small start-ups that would prefer to keep their source code private.\nIn such an ecosystem, GitLab Inc. stands out as a viable option with unlimited private\nrepositories and its GitLab Runner, a free and open-source tool to automate the\ntesting and building of projects, thus giving software\ndevelopers the freedom to experiment with different approaches to build the\noptimal pipeline for their needs.\n\n## How to get started with a CI workflow using GitLab Runner\n\nThis tutorial will demonstrate how to get started with a CI workflow using\n[GitLab Runner](https://gitlab.com/gitlab-org/gitlab-runner) and its built-in Docker executor.\nWe will first set up a sample NodeJS project hosted on Gitlab.com to run tests\non build machines provided by GitLab Inc.\nThen, we will set up and configure our own specific runner on a private server.\nFinally, we will go over some good practices to speed up the build time as the project grows.\nBy the end of this tutorial you will feel comfortable building your own\nCI solution, custom-tailored for your existing projects.\nThis post will be useful for project managers looking for affordable\nCI solutions and developers wanting to build test-driven\nand sustainable software projects.\n\n\u003C!-- more -->\n\n## Introducing the sample project\n\nBefore we start with the GitLab Runner, let's briefly review this simple\n[NodeJS project](https://gitlab.com/gitlab-examples/nodejs/) we will\nwork with throughout this tutorial.\nOur project contains two independent modules we would like to test.\nOne module consists of some utility methods for asynchronous operations.\nThe other module implements a simple wrapper around a PostgreSQL database to\ninsert and retrieve records. Thanks to the latter module, we will need a\ndatabase instance in our testing environment to run the tests.\n\nAfter starting a test database, we can run the tests locally and see all tests pass.\n\n```\nDB_USER=[db-username] \\\nBD_PASS=[db-password] \\\nDB_HOST=[db-host:db-port] \\\nnode ./specs/start.js\n```\n\nFeel free to explore the project [source code](https://gitlab.com/gitlab-examples/nodejs/tree/master)\nif you are interested.\n\n## How to get started with GitLab Runner\n\nGitLab Runner is triggered with every push to the central repository or branch if a\n`.gitlab-ci.yml` file is present (unless explicitly configured not to).\nThis file specifies how the build environment should be set up and what\ncommands to be executed to build, test, and deploy our project in a series of\njobs that can be parallelized.\n\n## How to use Docker executor\n\nIn this tutorial, we will be using GitLab Runner's\nbuilt-in **docker executor** to set up the build environment.\nThis executor provides a powerful abstraction that uses Docker Engine in the\nbackground to load our app and run the tests in a Docker container.\nIn addition, this Docker executor conveniently starts any dependent services (such as\ndatabases) before running jobs and links containers to communicate with each other.\n\n### Creating `.gitlab-ci.yml` file\n\nOur first task is to add our `.gitlab-ci.yml` file to the root directory of our project.\n\n```\nimage: node:4.2.2\n\nservices:\n  - postgres:9.5.0\n\nall_tests:\n  script:\n   - npm install\n   - node ./specs/start.js\n```\n\nNow let's go over the parts of this file.\n\nThe first line specifies the base image against which our tests will run.\nSince we are testing a NodeJS app, our base image will be a recent NodeJS version.\n\nThe `services` section is where external dependencies are listed.\nIn our tests, we need a PostgreSQL database, so we add the image name for this database.\nAny Docker image name can be specified here, such as `mysql` for MySQL databases.\nThe database will start with default credentials before tests run and it will be\naccessible under the host name `postgres` on the default PostgreSQL port, 5432.\n\nIf we needed to use any credentials other than the defaults, we could add them\ninside the `variables` tag. Values under this tag are passed to all services\non initialization. As per the PostgreSQL service [documentation](http://doc.gitlab.com/ce/ci/services/postgres.html),\nthe following settings will overwrite the user and password for our database:\n\n```\nimage: node:4.2.2\n\nvariables:\n  POSTGRES_USER: testuser\n  POSTGRES_PASSWORD: testpass\n\nservices:\n  - postgres:9.5.0\n\nall_tests:\n  script:\n   - npm install\n   - node ./specs/start.js\n```\n\nNote that since these test credentials are internal to our project, it is OK to simply\nadd them to the `.gitlab-ci.yml` file. However, you should register any external\nconfiguration variables, such as API keys, in the **Secure Variables**\npage (**Settings -> Variables**) and reference them here by name.\n\nIn the final section, we define a job named `all_tests`, which contains the command\nthat will run our tests.\nIn the `script` subsection here, we simply add our commands to install the dependencies\nand start the tests.\n\nTo be extra cautious, we could lint-check our yml file on the\n[GitLab CI Lint page](https://gitlab.com/ci/lint) to see the breakdown of\nthe build steps to make sure we don't have a typo.\n\n## How to use Shared Runners\n\nGitLab Inc. provides a number of servers with GitLab Runner installed.\nOn the **Runners** page (**Settings -> Runners**), we can see the list of currently available runners.\nWe should see that Shared Runners are already available for us, so we can immediately queue our first build by simply pushing our `.gitlab-ci.yml` file to our repository.\nWe can track the progress of our build on the [Builds page](https://gitlab.com/gitlab-examples/nodejs/builds).\nOnce our build starts, we should see that it completes with success in a couple of minutes.\n\n### How to install a specific runner\n\nWhile these Shared Runners are great to get a sense of how to get started with\nCI, we will now install GitLab Runner on a private server to run exclusively\nfor our project.\nWe will use exactly the same [open-source software](https://gitlab.com/gitlab-org/gitlab-runner)\nGitLab.com uses on their Shared Runners, so we will have the extra benefit of\noptimizing and securing our builds for our specific project.\n\n\nWe will need a server instance where we will install the GitLab Runner.\nGitLab Runner can be installed on [Linux](https://gitlab.com/gitlab-org/gitlab-runner/blob/master/docs/install/linux-repository.md), [macOS](https://gitlab.com/gitlab-org/gitlab-ci-multi-runner/blob/master/docs/install/osx.md) and [Windows](https://gitlab.com/gitlab-org/gitlab-ci-multi-runner/blob/master/docs/install/windows.md).\nFor our sample project, a small server instance with 1 GB RAM should be enough.\nIn addition, since we will be running with the Docker executor, we also need to have [Docker Engine](https://docs.docker.com/engine/installation/) installed.\n\nUpon installation, we will register a new runner for our project.\nStart the registration with the following command:\n\n```\ngitlab-ci-multi-runner register\n```\n\nThe registration will walk us through a few steps to configure our registered runner.\n\n```\nRunning in system-mode.\n\nPlease enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/ci):\nhttps://gitlab.com/ci\n```\n\nSince our project is hosted on Gitlab.com, we will use the default\ngitlab-ci coordinator URL.\n\n```\nPlease enter the gitlab-ci token for this runner:\n[your private gitlab-ci token]\n```\n\nOn **Runners** page (**Settings -> Runners**), we will copy the private gitlab-ci token for our project and paste it here.\n\n```\nPlease enter the gitlab-ci description for this runner:\n[ubuntu-2gb-nyc3-01]: new-docker-executor\nPlease enter the gitlab-ci tags for this runner (comma separated):\ndocker\nRegistering runner... succeeded                     runner=8tB1zBiU\n```\n\nIt is a good practice to give a descriptive name and tags for runners to\nbe able to remember and target them later on. We will add the `docker` tag to this\nrunner since we can run any Docker image and services with it.\n\n```\nPlease enter the executor: virtualbox, ssh, shell, parallels, docker, docker-ssh:\ndocker\nPlease enter the default Docker image (eg. ruby:2.1):\nnode:4.2.2\nRunner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!\n```\n\nNotice that there are several executor options available.\nIn this post, we are using the `docker` executor.\nRemember from the `.gitlab-ci.yml` file, our base image is already set as node:4.2.2.\nNote that the default Docker image specified here will be used only when `.gitlab-ci.yml`\nfile does not contain an image declaration.\n\nSpecific runners take precedence over the Shared Runners.\nOur project won't be using Shared Runners as long as our specific runner is available.\nIf preferred, we can disable the Shared Runners on the **Runners** page\n(**Settings -> Runners**) by toggling off the Shared Runners button.\n\nFinally, we are ready to trigger a new build.\nWe should see the next build running with our specific runner on our private server.\n\n## How to enable cache\n\nNow that we have a functional CI workflow, let's talk about\nhow to make it faster and more efficient.\n\nTo start, we can eliminate redundant downloading of dependency libraries by\ncaching and restoring dependencies between builds.\nFor NodeJS projects, dependent libraries are installed in a folder called `node_modules`.\nWe should specify this folder to cache in our `.gitlab-ci.yml` file:\n\n```\nimage: node:4.2.2\n\ncache:\n  paths:\n  - node_modules/\n\nservices:\n  - postgres:9.5.0\n\nall_tests:\n  script:\n   - npm install\n   - node ./specs/start.js\n```\n\nAfter a successful build, you should see the `node_modules` folder is archived at\nthe end of builds to be restored at the beginning of following builds.\nAs long as our dependencies file remains unchanged, no new libraries will be\ndownloaded and our total build time will significantly decrease.\n\n### Adding concurrency\n\nAnother modification we can add to speed up the build process is to\nparallelize the tests.\nIn our project, we can split the tests into two jobs.\nOne for the database tests and another for the async module tests.\nFurthermore, we can restrict the PostgreSQL service to run only for our database\njob since we won't need a database for the async module.\n\n```\nimage: node:4.2.2\n\ncache:\n  paths:\n  - node_modules/\n\ntest_async:\n  script:\n   - npm install\n   - node ./specs/start.js ./specs/async.spec.js\n\ntest_db:\n  services:\n    - postgres:9.5.0\n  script:\n   - npm install\n   - node ./specs/start.js ./specs/db-postgres.spec.js\n```\n\nNote that we still need to introduce concurrency to the build.\nTo do that we could either create a new server and register a runner for\nour project, or increase the concurrency level for our existing runner.\nWe will go with the latter and edit the `concurrent` setting on the first\nline of our `config.toml` configuration file in the server.\nIf you installed GitLab Runner as the root user with the deb or rpm packages,\nthe config file will be in `/etc/gitlab-runner/config.toml` by default:\n\n```\nconcurrent = 2\n```\n\nAfter triggering a new build, we can see two jobs running\nat the same time.\n\n## Conclusion\n\nIn this tutorial, we set up automated testing with GitLab Runner and its built-in Docker executor for a NodeJS\nproject to get started with continuous integration on Gitlab.com.\nFor more information on the GitLab Runner and GitLab CI platform or using Docker with them, check out the [documentation](http://doc.gitlab.com/ce/ci/).\nHappy coding!\n\n### About Guest Author: Ahmet Kizilay\n\n[Ahmet Kizilay](https://about.me/ahmetkizilay) is a software developer living in Istanbul.\nHe is currently working as a full-stack developer at [Graph Commons](https://graphcommons.com/).\n","engineering",{"slug":23,"featured":6,"template":24},"gitlab-runner-with-docker","BlogPost","content:en-us:blog:gitlab-runner-with-docker.yml","yaml","Gitlab Runner With Docker","content","en-us/blog/gitlab-runner-with-docker.yml","en-us/blog/gitlab-runner-with-docker","yml",{"_path":33,"_dir":34,"_draft":6,"_partial":6,"_locale":7,"data":35,"_id":445,"_type":26,"title":446,"_source":28,"_file":447,"_stem":448,"_extension":31},"/shared/en-us/main-navigation","en-us",{"logo":36,"freeTrial":41,"sales":46,"login":51,"items":56,"search":386,"minimal":417,"duo":436},{"config":37},{"href":38,"dataGaName":39,"dataGaLocation":40},"/","gitlab logo","header",{"text":42,"config":43},"Get free trial",{"href":44,"dataGaName":45,"dataGaLocation":40},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":47,"config":48},"Talk to sales",{"href":49,"dataGaName":50,"dataGaLocation":40},"/sales/","sales",{"text":52,"config":53},"Sign in",{"href":54,"dataGaName":55,"dataGaLocation":40},"https://gitlab.com/users/sign_in/","sign in",[57,101,197,202,307,367],{"text":58,"config":59,"cards":61,"footer":84},"Platform",{"dataNavLevelOne":60},"platform",[62,68,76],{"title":58,"description":63,"link":64},"The most comprehensive AI-powered DevSecOps Platform",{"text":65,"config":66},"Explore our Platform",{"href":67,"dataGaName":60,"dataGaLocation":40},"/platform/",{"title":69,"description":70,"link":71},"GitLab Duo (AI)","Build software faster with AI at every stage of development",{"text":72,"config":73},"Meet GitLab Duo",{"href":74,"dataGaName":75,"dataGaLocation":40},"/gitlab-duo/","gitlab duo ai",{"title":77,"description":78,"link":79},"Why GitLab","10 reasons why Enterprises choose GitLab",{"text":80,"config":81},"Learn more",{"href":82,"dataGaName":83,"dataGaLocation":40},"/why-gitlab/","why gitlab",{"title":85,"items":86},"Get started with",[87,92,97],{"text":88,"config":89},"Platform Engineering",{"href":90,"dataGaName":91,"dataGaLocation":40},"/solutions/platform-engineering/","platform engineering",{"text":93,"config":94},"Developer Experience",{"href":95,"dataGaName":96,"dataGaLocation":40},"/developer-experience/","Developer experience",{"text":98,"config":99},"MLOps",{"href":100,"dataGaName":98,"dataGaLocation":40},"/topics/devops/the-role-of-ai-in-devops/",{"text":102,"left":103,"config":104,"link":106,"lists":110,"footer":179},"Product",true,{"dataNavLevelOne":105},"solutions",{"text":107,"config":108},"View all Solutions",{"href":109,"dataGaName":105,"dataGaLocation":40},"/solutions/",[111,136,158],{"title":112,"description":113,"link":114,"items":119},"Automation","CI/CD and automation to accelerate deployment",{"config":115},{"icon":116,"href":117,"dataGaName":118,"dataGaLocation":40},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[120,124,128,132],{"text":121,"config":122},"CI/CD",{"href":123,"dataGaLocation":40,"dataGaName":121},"/solutions/continuous-integration/",{"text":125,"config":126},"AI-Assisted Development",{"href":74,"dataGaLocation":40,"dataGaName":127},"AI assisted development",{"text":129,"config":130},"Source Code Management",{"href":131,"dataGaLocation":40,"dataGaName":129},"/solutions/source-code-management/",{"text":133,"config":134},"Automated Software Delivery",{"href":117,"dataGaLocation":40,"dataGaName":135},"Automated software delivery",{"title":137,"description":138,"link":139,"items":144},"Security","Deliver code faster without compromising security",{"config":140},{"href":141,"dataGaName":142,"dataGaLocation":40,"icon":143},"/solutions/security-compliance/","security and compliance","ShieldCheckLight",[145,148,153],{"text":146,"config":147},"Security & Compliance",{"href":141,"dataGaLocation":40,"dataGaName":146},{"text":149,"config":150},"Software Supply Chain Security",{"href":151,"dataGaLocation":40,"dataGaName":152},"/solutions/supply-chain/","Software supply chain security",{"text":154,"config":155},"Compliance & Governance",{"href":156,"dataGaLocation":40,"dataGaName":157},"/solutions/continuous-software-compliance/","Compliance and governance",{"title":159,"link":160,"items":165},"Measurement",{"config":161},{"icon":162,"href":163,"dataGaName":164,"dataGaLocation":40},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[166,170,174],{"text":167,"config":168},"Visibility & Measurement",{"href":163,"dataGaLocation":40,"dataGaName":169},"Visibility and Measurement",{"text":171,"config":172},"Value Stream Management",{"href":173,"dataGaLocation":40,"dataGaName":171},"/solutions/value-stream-management/",{"text":175,"config":176},"Analytics & Insights",{"href":177,"dataGaLocation":40,"dataGaName":178},"/solutions/analytics-and-insights/","Analytics and insights",{"title":180,"items":181},"GitLab for",[182,187,192],{"text":183,"config":184},"Enterprise",{"href":185,"dataGaLocation":40,"dataGaName":186},"/enterprise/","enterprise",{"text":188,"config":189},"Small Business",{"href":190,"dataGaLocation":40,"dataGaName":191},"/small-business/","small business",{"text":193,"config":194},"Public Sector",{"href":195,"dataGaLocation":40,"dataGaName":196},"/solutions/public-sector/","public sector",{"text":198,"config":199},"Pricing",{"href":200,"dataGaName":201,"dataGaLocation":40,"dataNavLevelOne":201},"/pricing/","pricing",{"text":203,"config":204,"link":206,"lists":210,"feature":294},"Resources",{"dataNavLevelOne":205},"resources",{"text":207,"config":208},"View all resources",{"href":209,"dataGaName":205,"dataGaLocation":40},"/resources/",[211,244,266],{"title":212,"items":213},"Getting started",[214,219,224,229,234,239],{"text":215,"config":216},"Install",{"href":217,"dataGaName":218,"dataGaLocation":40},"/install/","install",{"text":220,"config":221},"Quick start guides",{"href":222,"dataGaName":223,"dataGaLocation":40},"/get-started/","quick setup checklists",{"text":225,"config":226},"Learn",{"href":227,"dataGaLocation":40,"dataGaName":228},"https://university.gitlab.com/","learn",{"text":230,"config":231},"Product documentation",{"href":232,"dataGaName":233,"dataGaLocation":40},"https://docs.gitlab.com/","product documentation",{"text":235,"config":236},"Best practice videos",{"href":237,"dataGaName":238,"dataGaLocation":40},"/getting-started-videos/","best practice videos",{"text":240,"config":241},"Integrations",{"href":242,"dataGaName":243,"dataGaLocation":40},"/integrations/","integrations",{"title":245,"items":246},"Discover",[247,252,256,261],{"text":248,"config":249},"Customer success stories",{"href":250,"dataGaName":251,"dataGaLocation":40},"/customers/","customer success stories",{"text":253,"config":254},"Blog",{"href":255,"dataGaName":5,"dataGaLocation":40},"/blog/",{"text":257,"config":258},"Remote",{"href":259,"dataGaName":260,"dataGaLocation":40},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"text":262,"config":263},"TeamOps",{"href":264,"dataGaName":265,"dataGaLocation":40},"/teamops/","teamops",{"title":267,"items":268},"Connect",[269,274,279,284,289],{"text":270,"config":271},"GitLab Services",{"href":272,"dataGaName":273,"dataGaLocation":40},"/services/","services",{"text":275,"config":276},"Community",{"href":277,"dataGaName":278,"dataGaLocation":40},"/community/","community",{"text":280,"config":281},"Forum",{"href":282,"dataGaName":283,"dataGaLocation":40},"https://forum.gitlab.com/","forum",{"text":285,"config":286},"Events",{"href":287,"dataGaName":288,"dataGaLocation":40},"/events/","events",{"text":290,"config":291},"Partners",{"href":292,"dataGaName":293,"dataGaLocation":40},"/partners/","partners",{"backgroundColor":295,"textColor":296,"text":297,"image":298,"link":302},"#2f2a6b","#fff","Insights for the future of software development",{"altText":299,"config":300},"the source promo card",{"src":301},"/images/navigation/the-source-promo-card.svg",{"text":303,"config":304},"Read the latest",{"href":305,"dataGaName":306,"dataGaLocation":40},"/the-source/","the source",{"text":308,"config":309,"lists":311},"Company",{"dataNavLevelOne":310},"company",[312],{"items":313},[314,319,325,327,332,337,342,347,352,357,362],{"text":315,"config":316},"About",{"href":317,"dataGaName":318,"dataGaLocation":40},"/company/","about",{"text":320,"config":321,"footerGa":324},"Jobs",{"href":322,"dataGaName":323,"dataGaLocation":40},"/jobs/","jobs",{"dataGaName":323},{"text":285,"config":326},{"href":287,"dataGaName":288,"dataGaLocation":40},{"text":328,"config":329},"Leadership",{"href":330,"dataGaName":331,"dataGaLocation":40},"/company/team/e-group/","leadership",{"text":333,"config":334},"Team",{"href":335,"dataGaName":336,"dataGaLocation":40},"/company/team/","team",{"text":338,"config":339},"Handbook",{"href":340,"dataGaName":341,"dataGaLocation":40},"https://handbook.gitlab.com/","handbook",{"text":343,"config":344},"Investor relations",{"href":345,"dataGaName":346,"dataGaLocation":40},"https://ir.gitlab.com/","investor relations",{"text":348,"config":349},"Trust Center",{"href":350,"dataGaName":351,"dataGaLocation":40},"/security/","trust center",{"text":353,"config":354},"AI Transparency Center",{"href":355,"dataGaName":356,"dataGaLocation":40},"/ai-transparency-center/","ai transparency center",{"text":358,"config":359},"Newsletter",{"href":360,"dataGaName":361,"dataGaLocation":40},"/company/contact/","newsletter",{"text":363,"config":364},"Press",{"href":365,"dataGaName":366,"dataGaLocation":40},"/press/","press",{"text":368,"config":369,"lists":370},"Contact us",{"dataNavLevelOne":310},[371],{"items":372},[373,376,381],{"text":47,"config":374},{"href":49,"dataGaName":375,"dataGaLocation":40},"talk to sales",{"text":377,"config":378},"Get help",{"href":379,"dataGaName":380,"dataGaLocation":40},"/support/","get help",{"text":382,"config":383},"Customer portal",{"href":384,"dataGaName":385,"dataGaLocation":40},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":387,"login":388,"suggestions":395},"Close",{"text":389,"link":390},"To search repositories and projects, login to",{"text":391,"config":392},"gitlab.com",{"href":54,"dataGaName":393,"dataGaLocation":394},"search login","search",{"text":396,"default":397},"Suggestions",[398,400,404,406,410,414],{"text":69,"config":399},{"href":74,"dataGaName":69,"dataGaLocation":394},{"text":401,"config":402},"Code Suggestions (AI)",{"href":403,"dataGaName":401,"dataGaLocation":394},"/solutions/code-suggestions/",{"text":121,"config":405},{"href":123,"dataGaName":121,"dataGaLocation":394},{"text":407,"config":408},"GitLab on AWS",{"href":409,"dataGaName":407,"dataGaLocation":394},"/partners/technology-partners/aws/",{"text":411,"config":412},"GitLab on Google Cloud",{"href":413,"dataGaName":411,"dataGaLocation":394},"/partners/technology-partners/google-cloud-platform/",{"text":415,"config":416},"Why GitLab?",{"href":82,"dataGaName":415,"dataGaLocation":394},{"freeTrial":418,"mobileIcon":423,"desktopIcon":428,"secondaryButton":431},{"text":419,"config":420},"Start free trial",{"href":421,"dataGaName":45,"dataGaLocation":422},"https://gitlab.com/-/trials/new/","nav",{"altText":424,"config":425},"Gitlab Icon",{"src":426,"dataGaName":427,"dataGaLocation":422},"/images/brand/gitlab-logo-tanuki.svg","gitlab icon",{"altText":424,"config":429},{"src":430,"dataGaName":427,"dataGaLocation":422},"/images/brand/gitlab-logo-type.svg",{"text":432,"config":433},"Get Started",{"href":434,"dataGaName":435,"dataGaLocation":422},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/compare/gitlab-vs-github/","get started",{"freeTrial":437,"mobileIcon":441,"desktopIcon":443},{"text":438,"config":439},"Learn more about GitLab Duo",{"href":74,"dataGaName":440,"dataGaLocation":422},"gitlab duo",{"altText":424,"config":442},{"src":426,"dataGaName":427,"dataGaLocation":422},{"altText":424,"config":444},{"src":430,"dataGaName":427,"dataGaLocation":422},"content:shared:en-us:main-navigation.yml","Main Navigation","shared/en-us/main-navigation.yml","shared/en-us/main-navigation",{"_path":450,"_dir":34,"_draft":6,"_partial":6,"_locale":7,"title":451,"button":452,"image":456,"config":459,"_id":461,"_type":26,"_source":28,"_file":462,"_stem":463,"_extension":31},"/shared/en-us/banner","is now in public beta!",{"text":80,"config":453},{"href":454,"dataGaName":455,"dataGaLocation":40},"/gitlab-duo/agent-platform/","duo banner",{"config":457},{"src":458},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1753720689/somrf9zaunk0xlt7ne4x.svg",{"layout":460},"release","content:shared:en-us:banner.yml","shared/en-us/banner.yml","shared/en-us/banner",{"_path":465,"_dir":34,"_draft":6,"_partial":6,"_locale":7,"data":466,"_id":671,"_type":26,"title":672,"_source":28,"_file":673,"_stem":674,"_extension":31},"/shared/en-us/main-footer",{"text":467,"source":468,"edit":474,"contribute":479,"config":484,"items":489,"minimal":663},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":469,"config":470},"View page source",{"href":471,"dataGaName":472,"dataGaLocation":473},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":475,"config":476},"Edit this page",{"href":477,"dataGaName":478,"dataGaLocation":473},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":480,"config":481},"Please contribute",{"href":482,"dataGaName":483,"dataGaLocation":473},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":485,"facebook":486,"youtube":487,"linkedin":488},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[490,513,570,599,633],{"title":58,"links":491,"subMenu":496},[492],{"text":493,"config":494},"DevSecOps platform",{"href":67,"dataGaName":495,"dataGaLocation":473},"devsecops platform",[497],{"title":198,"links":498},[499,503,508],{"text":500,"config":501},"View plans",{"href":200,"dataGaName":502,"dataGaLocation":473},"view plans",{"text":504,"config":505},"Why Premium?",{"href":506,"dataGaName":507,"dataGaLocation":473},"/pricing/premium/","why premium",{"text":509,"config":510},"Why Ultimate?",{"href":511,"dataGaName":512,"dataGaLocation":473},"/pricing/ultimate/","why ultimate",{"title":514,"links":515},"Solutions",[516,521,524,526,531,536,540,543,547,552,554,557,560,565],{"text":517,"config":518},"Digital transformation",{"href":519,"dataGaName":520,"dataGaLocation":473},"/topics/digital-transformation/","digital transformation",{"text":146,"config":522},{"href":141,"dataGaName":523,"dataGaLocation":473},"security & compliance",{"text":135,"config":525},{"href":117,"dataGaName":118,"dataGaLocation":473},{"text":527,"config":528},"Agile development",{"href":529,"dataGaName":530,"dataGaLocation":473},"/solutions/agile-delivery/","agile delivery",{"text":532,"config":533},"Cloud transformation",{"href":534,"dataGaName":535,"dataGaLocation":473},"/topics/cloud-native/","cloud transformation",{"text":537,"config":538},"SCM",{"href":131,"dataGaName":539,"dataGaLocation":473},"source code management",{"text":121,"config":541},{"href":123,"dataGaName":542,"dataGaLocation":473},"continuous integration & delivery",{"text":544,"config":545},"Value stream management",{"href":173,"dataGaName":546,"dataGaLocation":473},"value stream management",{"text":548,"config":549},"GitOps",{"href":550,"dataGaName":551,"dataGaLocation":473},"/solutions/gitops/","gitops",{"text":183,"config":553},{"href":185,"dataGaName":186,"dataGaLocation":473},{"text":555,"config":556},"Small business",{"href":190,"dataGaName":191,"dataGaLocation":473},{"text":558,"config":559},"Public sector",{"href":195,"dataGaName":196,"dataGaLocation":473},{"text":561,"config":562},"Education",{"href":563,"dataGaName":564,"dataGaLocation":473},"/solutions/education/","education",{"text":566,"config":567},"Financial services",{"href":568,"dataGaName":569,"dataGaLocation":473},"/solutions/finance/","financial services",{"title":203,"links":571},[572,574,576,578,581,583,585,587,589,591,593,595,597],{"text":215,"config":573},{"href":217,"dataGaName":218,"dataGaLocation":473},{"text":220,"config":575},{"href":222,"dataGaName":223,"dataGaLocation":473},{"text":225,"config":577},{"href":227,"dataGaName":228,"dataGaLocation":473},{"text":230,"config":579},{"href":232,"dataGaName":580,"dataGaLocation":473},"docs",{"text":253,"config":582},{"href":255,"dataGaName":5,"dataGaLocation":473},{"text":248,"config":584},{"href":250,"dataGaName":251,"dataGaLocation":473},{"text":257,"config":586},{"href":259,"dataGaName":260,"dataGaLocation":473},{"text":270,"config":588},{"href":272,"dataGaName":273,"dataGaLocation":473},{"text":262,"config":590},{"href":264,"dataGaName":265,"dataGaLocation":473},{"text":275,"config":592},{"href":277,"dataGaName":278,"dataGaLocation":473},{"text":280,"config":594},{"href":282,"dataGaName":283,"dataGaLocation":473},{"text":285,"config":596},{"href":287,"dataGaName":288,"dataGaLocation":473},{"text":290,"config":598},{"href":292,"dataGaName":293,"dataGaLocation":473},{"title":308,"links":600},[601,603,605,607,609,611,613,617,622,624,626,628],{"text":315,"config":602},{"href":317,"dataGaName":310,"dataGaLocation":473},{"text":320,"config":604},{"href":322,"dataGaName":323,"dataGaLocation":473},{"text":328,"config":606},{"href":330,"dataGaName":331,"dataGaLocation":473},{"text":333,"config":608},{"href":335,"dataGaName":336,"dataGaLocation":473},{"text":338,"config":610},{"href":340,"dataGaName":341,"dataGaLocation":473},{"text":343,"config":612},{"href":345,"dataGaName":346,"dataGaLocation":473},{"text":614,"config":615},"Sustainability",{"href":616,"dataGaName":614,"dataGaLocation":473},"/sustainability/",{"text":618,"config":619},"Diversity, inclusion and belonging (DIB)",{"href":620,"dataGaName":621,"dataGaLocation":473},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":348,"config":623},{"href":350,"dataGaName":351,"dataGaLocation":473},{"text":358,"config":625},{"href":360,"dataGaName":361,"dataGaLocation":473},{"text":363,"config":627},{"href":365,"dataGaName":366,"dataGaLocation":473},{"text":629,"config":630},"Modern Slavery Transparency Statement",{"href":631,"dataGaName":632,"dataGaLocation":473},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"title":634,"links":635},"Contact Us",[636,639,641,643,648,653,658],{"text":637,"config":638},"Contact an expert",{"href":49,"dataGaName":50,"dataGaLocation":473},{"text":377,"config":640},{"href":379,"dataGaName":380,"dataGaLocation":473},{"text":382,"config":642},{"href":384,"dataGaName":385,"dataGaLocation":473},{"text":644,"config":645},"Status",{"href":646,"dataGaName":647,"dataGaLocation":473},"https://status.gitlab.com/","status",{"text":649,"config":650},"Terms of use",{"href":651,"dataGaName":652,"dataGaLocation":473},"/terms/","terms of use",{"text":654,"config":655},"Privacy statement",{"href":656,"dataGaName":657,"dataGaLocation":473},"/privacy/","privacy statement",{"text":659,"config":660},"Cookie preferences",{"dataGaName":661,"dataGaLocation":473,"id":662,"isOneTrustButton":103},"cookie preferences","ot-sdk-btn",{"items":664},[665,667,669],{"text":649,"config":666},{"href":651,"dataGaName":652,"dataGaLocation":473},{"text":654,"config":668},{"href":656,"dataGaName":657,"dataGaLocation":473},{"text":659,"config":670},{"dataGaName":661,"dataGaLocation":473,"id":662,"isOneTrustButton":103},"content:shared:en-us:main-footer.yml","Main Footer","shared/en-us/main-footer.yml","shared/en-us/main-footer",[676],{"_path":677,"_dir":678,"_draft":6,"_partial":6,"_locale":7,"content":679,"config":683,"_id":685,"_type":26,"title":18,"_source":28,"_file":686,"_stem":687,"_extension":31},"/en-us/blog/authors/ahmet-kizilay","authors",{"name":18,"config":680},{"headshot":681,"ctfId":682},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749659488/Blog/Author%20Headshots/gitlab-logo-extra-whitespace.png","Ahmet-Kizilay",{"template":684},"BlogAuthor","content:en-us:blog:authors:ahmet-kizilay.yml","en-us/blog/authors/ahmet-kizilay.yml","en-us/blog/authors/ahmet-kizilay",{"_path":689,"_dir":34,"_draft":6,"_partial":6,"_locale":7,"header":690,"eyebrow":691,"blurb":692,"button":693,"secondaryButton":697,"_id":699,"_type":26,"title":700,"_source":28,"_file":701,"_stem":702,"_extension":31},"/shared/en-us/next-steps","Start shipping better software faster","50%+ of the Fortune 100 trust GitLab","See what your team can do with the intelligent\n\n\nDevSecOps platform.\n",{"text":42,"config":694},{"href":695,"dataGaName":45,"dataGaLocation":696},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":47,"config":698},{"href":49,"dataGaName":50,"dataGaLocation":696},"content:shared:en-us:next-steps.yml","Next Steps","shared/en-us/next-steps.yml","shared/en-us/next-steps",1753981636729]