[{"data":1,"prerenderedAt":702},["ShallowReactive",2],{"/en-us/blog/dependency-proxy-updates/":3,"navigation-en-us":35,"banner-en-us":451,"footer-en-us":463,"Steve Abrams":674,"next-steps-en-us":687},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"seo":8,"content":16,"config":25,"_id":28,"_type":29,"title":30,"_source":31,"_file":32,"_stem":33,"_extension":34},"/en-us/blog/dependency-proxy-updates","blog",false,"",{"title":9,"description":10,"ogTitle":9,"ogDescription":10,"noIndex":6,"ogImage":11,"ogUrl":12,"ogSiteName":13,"ogType":14,"canonicalUrls":12,"schema":15},"Using the Dependency Proxy to improve your pipelines","The Dependency Proxy helps make pipelines faster and mitigates Docker Hub rate limits.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749681815/Blog/Hero%20Images/dependency_proxy_header.jpg","https://about.gitlab.com/blog/dependency-proxy-updates","https://about.gitlab.com","article","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Using the Dependency Proxy to improve your pipelines\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Steve Abrams\"}],\n        \"datePublished\": \"2020-12-15\",\n      }",{"title":9,"description":10,"authors":17,"heroImage":11,"date":19,"body":20,"category":21,"tags":22},[18],"Steve Abrams","2020-12-15","\n\n{::options parse_block_html=\"true\" /}\n\n\n\nHi! I'm Steve, a backend engineer at GitLab. I work on the Package stage, which includes the Dependency Proxy.\n\nIn versions 13.6 and 13.7, we improved the [Dependency Proxy](https://docs.gitlab.com/ee/user/packages/dependency_proxy/) so it's no longer an [MVC feature](https://about.gitlab.com/handbook/product/product-principles/#the-minimal-viable-change-mvc). Before, the Dependency Proxy was only available to paid users who may have been wary to use it, because they did not want to be forced to use a public group. Now the Dependency Proxy is a robust free feature that can really provide value for free and paid users alike.\n\nIf you haven't tried the feature out before, now is a great time to take a look. If you have previously tried the Dependency Proxy and found it was not quite the solution you were looking for, I invite you to take a look at the new functionality detailed here. The Dependency Proxy is more available, more secure, and easier to use than ever. These updates also come right as Docker Hub has rolled out rate limits on image pulls, which the Dependency Proxy can help alleviate.\n\nYou can also watch a demo of most of these features in this video:\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/Nc4nUo7Pq08\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\n## Move to Core\n\nIn 13.6, we moved the [Dependency Proxy to Core](/releases/2020/11/22/gitlab-13-6-released/#the-dependency-proxy-is-now-open-source). The ability to speed up pipelines and create a safety net behind Docker Hub seemed like functionality that everyone should benefit from.\n\n## Support for private groups\n\nStarting in 13.7, you can now use the Dependency Proxy with all groups. Each group and subgroup can have its own space to cache images.\n\n![Dependency Proxy interface](https://about.gitlab.com/images/blogimages/dependency_proxy_interface.png)\n\n## Authentication\n\n[Authentication](https://docs.gitlab.com/ee/user/packages/dependency_proxy/#authenticate-with-the-dependency-proxy) is also new in 13.7. If you had previously used the Dependency Proxy, you will need to update your CI scripts or workflow to make sure that you are now logged in.\n\nAuthentication was not only necessary to enable the ability to support private groups with the Dependency Proxy, but it's also a security upgrade. The Dependency Proxy caches image data in your group's storage, so without authentication, public groups could easily be abused to store images that your group might not even be using.\n\n### How does it work\n\nThe Dependency Proxy is a proxy, so from the perspective of the Docker client, it is just another registry to authenticate with:\n\n```shell\ndocker login --username stanley --password tanuki gitlab.com\n```\n\nWhen Docker makes a request to a registry it first asks:\n\n```shell\nGET gitlab.com/v2 # are you a registry?\n```\n\nTo which GitLab responds:\n\n```shell\n401 Unauthorized\n\nWWW-Authenticate: Bearer realm=https://gitlab.com/auth/jwt, service=dependency_proxy\n# Yes! But you have to get permission to access me.\n# Please request a token from this other URL first.\n```\n\nThen Docker requests a token using the username and password you supplied, and if things check out, GitLab returns a JWT. Docker uses it to make its next request, which in the case of the Dependency Proxy is the image pull. If things don't check out, you'll likely see a `403 Forbidden` error.\n\n## Docker Hub rate limiting\n\nIn November 2020, Docker Hub began rate limiting image pulls. The Dependency Proxy was already caching the image layers (blobs), so it made sense that [the Dependency Proxy should help mitigate this problem for users](https://docs.gitlab.com/ee/user/packages/dependency_proxy/#docker-hub-rate-limits-and-the-dependency-proxy).\n\nIt is not uncommon for a project's pipeline to run every time a user pushes a commit. In an active project or group, this could happen many times in an hour. If your CI script starts with something as simple as:\n\n```yaml\nimage: node:latest\n```\n\nEvery time your pipeline runs, even though you are using the same image every time, Docker will count an additional image pull against your account.\n\nAn image consists of many different files, and a `docker pull` command will make several requests. So what counts as one image pull?\n\nThere are two types of files that make up an image. First is the manifest. You can think of it as a table of contents for an image. It contains information about what layers, or blobs, the image is made of. Once the Docker client has received the manifest, it will make a request for each blob described in the manifest.\n\nDocker uses the [manifest requests to count the image pulls](https://docs.docker.com/docker-hub/download-rate-limit/). This means that if the Dependency Proxy is going to help mitigate the rate limiting, it needs to store the manifest in addition to the blobs. This presents a small problem: a manifest is usually requested by tag name, which is a mutable reference. If I request `node:latest` this week, it might be different than the `node:latest` I requested last week. Each manifest contains a digest, or hash signature, that can be used to tell if it has changed. You can see this digest when you pull the image:\n\n```shell\n$ docker pull alpine:latest\n\nlatest: Pulling from library/alpine\nDigest: sha256:a126728cb7db157f0deb377bcba3c5e473e612d7bafc27f6bb4e5e083f9f08c2\nStatus: Image is up to date for alpine:latest\ndocker.io/library/alpine:latest\n```\n\nDocker has allowed HEAD requests to be made for a manifest for free. The HEAD request response contains the digest of the underlying manifest. So we can make a HEAD request to determine if the manifest we have cached in the Dependency Proxy is up to date.\n\n```shell\ncurl --head -H \"Authorization: Bearer $TOKEN\" https://registry-1.docker.io/v2/library/alpine/manifests/latest\n\nHTTP/1.1 200 OK\nContent-Length: 2782\nContent-Type: application/vnd.docker.distribution.manifest.v1+prettyjws\nDocker-Content-Digest: sha256:a126728cb7db157f0deb377bcba3c5e473e612d7bafc27f6bb4e5e083f9f08c2\nDocker-Distribution-Api-Version: registry/2.0\nEtag: \"sha256:a126728cb7db157f0deb377bcba3c5e473e612d7bafc27f6bb4e5e083f9f08c2\"\nDate: Wed, 15 Dec 2020 03:34:24 GMT\nStrict-Transport-Security: max-age=31536000\nRateLimit-Limit: 100;w=21600\nRateLimit-Remaining: 72;w=21600\n```\n\nThe response even contains information telling us how many requests we have remaining within our rate limit. In this example, we see we have 72 out of 100 remaining.\n\nWhen the Dependency Proxy first receives a request for the manifest, it decides whether or not it needs to pull an image from Docker Hub based on a few rules:\n\n![Dependency Proxy manifest caching](https://about.gitlab.com/images/blogimages/dependency_proxy_flow_chart.png)\n\nThe really great thing about the Dependency Proxy is that you don't have to do anything special to take advantage of these abilities. If you simply update your CI script with your Dependency Proxy image prefix to something like:\n\n```yaml\nimage: gitlab.com/super-awesome-group/dependency_proxy/containers/node:latest\n```\n\nThen you will automatically bypass Docker Hub rate limiting and your cache will have the most up-to-date version of each image tag.\n\n## CI/CD\n\nThe Dependency Proxy makes the most sense as a compliment to CI/CD pipelines. Rather than pulling directly from Docker Hub, you can use the Dependency Proxy to speed up your pipelines, avoid rate limiting, and create security in case of an upstream outage.\n\nAs of 13.9, runners log in to the Dependency Proxy automatically, so you don't need to explicitly log in unless you want to for reasons like using specific tokens.\n\nTo make the Dependency Proxy easier to use, we have added a few predefined environment variables you can use in your `.gitlab-ci.yml` files.\n\n- `CI_DEPENDENCY_PROXY_USER`: A CI user for logging in to the Dependency Proxy.\n- `CI_DEPENDENCY_PROXY_PASSWORD`: A CI password for logging in to the Dependency Proxy.\n- `CI_DEPENDENCY_PROXY_SERVER`: The server for logging in to the Dependency Proxy.\n- `CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX`: The image prefix for pulling images through the Dependency Proxy. This pulls through the top-level group.\n- `CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX` (starting in version 14.3): An alternative image prefix for pulling images through the Dependency Proxy. This pulls through the subgroup, or direct group the project exists in.\n\nDepending on how your scripts and pipelines look you can use these variables in a variety of ways. If you are manually pulling images in the script using `docker pull`, you can log in and pull like this:\n\n```yaml\n# .gitlab-ci.yml\n\ndependency-proxy-pull-master:\n  # Official docker image.\n  image: docker:latest\n  stage: build\n  services:\n    - docker:dind\n  before_script:\n    - docker login -u \"$CI_DEPENDENCY_PROXY_USER\" -p \"$CI_DEPENDENCY_PROXY_PASSWORD\" \"$CI_DEPENDENCY_PROXY_SERVER\"\n  script:\n    - docker pull \"$CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX\"/alpine:latest\n```\n\nIf you want to use the Dependency Proxy to pull images defined as `image` yaml attributes (the base images of the script), you can [create a custom environment variable](https://docs.gitlab.com/ee/ci/variables/#custom-cicd-variables) named `DOCKER_AUTH_CONFIG` with a value of:\n\n```yaml\n{\n    \"auths\": {\n        \"https://gitlab.com:443\": { # if you are using $CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX, you should explicitely include the port here.\n            \"auth\": \"(Base64 of username:password)\"\n        }\n    }\n}\n```\n\nYou will need to calculate the base64 value of your credentials. You can do this from the command line:\n\n```shell\n# The use of \"-n\" - prevents encoding a newline in the password.\necho -n \"my_username:my_password\" | base64\n\n# Example output to copy\nbXlfdXNlcm5hbWU6bXlfcGFzc3dvcmQ==\n\n# A personal access token also works!\necho -n \"my_username:personal_access_token\" | base64\n```\n\nOnce you have the custom environment variable defined, you can use the Dependency Proxy without having to manually log in within your CI script:\n\n```yaml\n# This is a working script that would publish an NPM package to the GitLab package registry\n# if a properly formatted package.json file exists in the project root.\nimage: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/node:latest\n\nstages:\n  - deploy\n\ndeploy:\n  stage: deploy\n  script:\n    - echo \"//gitlab.com/api/v4/projects/${CI_PROJECT_ID}/packages/npm/:_authToken=${CI_JOB_TOKEN}\">.npmrc\n    - npm publish\n```\n\n## Support when Docker Hub is offline\n\nBy caching all files that make up an image, we also now have the ability to keep pipelines green even if Docker Hub experiences an outage. As long as the Dependency Proxy has the image you are using cached, when it makes the HEAD request to check if the cached image is stale or not, if the HEAD request fails, we will just fall back to the cached image.\n\nThanks for reading! If you haven't used the Dependency Proxy yet, [get started using it today](https://docs.gitlab.com/ee/user/packages/dependency_proxy/)!\n\n## Updates\n\nSince this was published in December 2020, there have been many additional improvements and changes to the Dependency Proxy. As a result, some of the suggested approaches in this post have been improved or have become outdated. I suggest looking through [the most recent documentation](https://docs.gitlab.com/ee/user/packages/dependency_proxy/) to learn more.\n","unfiltered",[23,24],"CI/CD","features",{"slug":26,"featured":6,"template":27},"dependency-proxy-updates","BlogPost","content:en-us:blog:dependency-proxy-updates.yml","yaml","Dependency Proxy Updates","content","en-us/blog/dependency-proxy-updates.yml","en-us/blog/dependency-proxy-updates","yml",{"_path":36,"_dir":37,"_draft":6,"_partial":6,"_locale":7,"data":38,"_id":447,"_type":29,"title":448,"_source":31,"_file":449,"_stem":450,"_extension":34},"/shared/en-us/main-navigation","en-us",{"logo":39,"freeTrial":44,"sales":49,"login":54,"items":59,"search":388,"minimal":419,"duo":438},{"config":40},{"href":41,"dataGaName":42,"dataGaLocation":43},"/","gitlab logo","header",{"text":45,"config":46},"Get free trial",{"href":47,"dataGaName":48,"dataGaLocation":43},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":50,"config":51},"Talk to sales",{"href":52,"dataGaName":53,"dataGaLocation":43},"/sales/","sales",{"text":55,"config":56},"Sign in",{"href":57,"dataGaName":58,"dataGaLocation":43},"https://gitlab.com/users/sign_in/","sign in",[60,104,199,204,309,369],{"text":61,"config":62,"cards":64,"footer":87},"Platform",{"dataNavLevelOne":63},"platform",[65,71,79],{"title":61,"description":66,"link":67},"The most comprehensive AI-powered DevSecOps Platform",{"text":68,"config":69},"Explore our Platform",{"href":70,"dataGaName":63,"dataGaLocation":43},"/platform/",{"title":72,"description":73,"link":74},"GitLab Duo (AI)","Build software faster with AI at every stage of development",{"text":75,"config":76},"Meet GitLab Duo",{"href":77,"dataGaName":78,"dataGaLocation":43},"/gitlab-duo/","gitlab duo ai",{"title":80,"description":81,"link":82},"Why GitLab","10 reasons why Enterprises choose GitLab",{"text":83,"config":84},"Learn more",{"href":85,"dataGaName":86,"dataGaLocation":43},"/why-gitlab/","why gitlab",{"title":88,"items":89},"Get started with",[90,95,100],{"text":91,"config":92},"Platform Engineering",{"href":93,"dataGaName":94,"dataGaLocation":43},"/solutions/platform-engineering/","platform engineering",{"text":96,"config":97},"Developer Experience",{"href":98,"dataGaName":99,"dataGaLocation":43},"/developer-experience/","Developer experience",{"text":101,"config":102},"MLOps",{"href":103,"dataGaName":101,"dataGaLocation":43},"/topics/devops/the-role-of-ai-in-devops/",{"text":105,"left":106,"config":107,"link":109,"lists":113,"footer":181},"Product",true,{"dataNavLevelOne":108},"solutions",{"text":110,"config":111},"View all Solutions",{"href":112,"dataGaName":108,"dataGaLocation":43},"/solutions/",[114,138,160],{"title":115,"description":116,"link":117,"items":122},"Automation","CI/CD and automation to accelerate deployment",{"config":118},{"icon":119,"href":120,"dataGaName":121,"dataGaLocation":43},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[123,126,130,134],{"text":23,"config":124},{"href":125,"dataGaLocation":43,"dataGaName":23},"/solutions/continuous-integration/",{"text":127,"config":128},"AI-Assisted Development",{"href":77,"dataGaLocation":43,"dataGaName":129},"AI assisted development",{"text":131,"config":132},"Source Code Management",{"href":133,"dataGaLocation":43,"dataGaName":131},"/solutions/source-code-management/",{"text":135,"config":136},"Automated Software Delivery",{"href":120,"dataGaLocation":43,"dataGaName":137},"Automated software delivery",{"title":139,"description":140,"link":141,"items":146},"Security","Deliver code faster without compromising security",{"config":142},{"href":143,"dataGaName":144,"dataGaLocation":43,"icon":145},"/solutions/security-compliance/","security and compliance","ShieldCheckLight",[147,150,155],{"text":148,"config":149},"Security & Compliance",{"href":143,"dataGaLocation":43,"dataGaName":148},{"text":151,"config":152},"Software Supply Chain Security",{"href":153,"dataGaLocation":43,"dataGaName":154},"/solutions/supply-chain/","Software supply chain security",{"text":156,"config":157},"Compliance & Governance",{"href":158,"dataGaLocation":43,"dataGaName":159},"/solutions/continuous-software-compliance/","Compliance and governance",{"title":161,"link":162,"items":167},"Measurement",{"config":163},{"icon":164,"href":165,"dataGaName":166,"dataGaLocation":43},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[168,172,176],{"text":169,"config":170},"Visibility & Measurement",{"href":165,"dataGaLocation":43,"dataGaName":171},"Visibility and Measurement",{"text":173,"config":174},"Value Stream Management",{"href":175,"dataGaLocation":43,"dataGaName":173},"/solutions/value-stream-management/",{"text":177,"config":178},"Analytics & Insights",{"href":179,"dataGaLocation":43,"dataGaName":180},"/solutions/analytics-and-insights/","Analytics and insights",{"title":182,"items":183},"GitLab for",[184,189,194],{"text":185,"config":186},"Enterprise",{"href":187,"dataGaLocation":43,"dataGaName":188},"/enterprise/","enterprise",{"text":190,"config":191},"Small Business",{"href":192,"dataGaLocation":43,"dataGaName":193},"/small-business/","small business",{"text":195,"config":196},"Public Sector",{"href":197,"dataGaLocation":43,"dataGaName":198},"/solutions/public-sector/","public sector",{"text":200,"config":201},"Pricing",{"href":202,"dataGaName":203,"dataGaLocation":43,"dataNavLevelOne":203},"/pricing/","pricing",{"text":205,"config":206,"link":208,"lists":212,"feature":296},"Resources",{"dataNavLevelOne":207},"resources",{"text":209,"config":210},"View all resources",{"href":211,"dataGaName":207,"dataGaLocation":43},"/resources/",[213,246,268],{"title":214,"items":215},"Getting started",[216,221,226,231,236,241],{"text":217,"config":218},"Install",{"href":219,"dataGaName":220,"dataGaLocation":43},"/install/","install",{"text":222,"config":223},"Quick start guides",{"href":224,"dataGaName":225,"dataGaLocation":43},"/get-started/","quick setup checklists",{"text":227,"config":228},"Learn",{"href":229,"dataGaLocation":43,"dataGaName":230},"https://university.gitlab.com/","learn",{"text":232,"config":233},"Product documentation",{"href":234,"dataGaName":235,"dataGaLocation":43},"https://docs.gitlab.com/","product documentation",{"text":237,"config":238},"Best practice videos",{"href":239,"dataGaName":240,"dataGaLocation":43},"/getting-started-videos/","best practice videos",{"text":242,"config":243},"Integrations",{"href":244,"dataGaName":245,"dataGaLocation":43},"/integrations/","integrations",{"title":247,"items":248},"Discover",[249,254,258,263],{"text":250,"config":251},"Customer success stories",{"href":252,"dataGaName":253,"dataGaLocation":43},"/customers/","customer success stories",{"text":255,"config":256},"Blog",{"href":257,"dataGaName":5,"dataGaLocation":43},"/blog/",{"text":259,"config":260},"Remote",{"href":261,"dataGaName":262,"dataGaLocation":43},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"text":264,"config":265},"TeamOps",{"href":266,"dataGaName":267,"dataGaLocation":43},"/teamops/","teamops",{"title":269,"items":270},"Connect",[271,276,281,286,291],{"text":272,"config":273},"GitLab Services",{"href":274,"dataGaName":275,"dataGaLocation":43},"/services/","services",{"text":277,"config":278},"Community",{"href":279,"dataGaName":280,"dataGaLocation":43},"/community/","community",{"text":282,"config":283},"Forum",{"href":284,"dataGaName":285,"dataGaLocation":43},"https://forum.gitlab.com/","forum",{"text":287,"config":288},"Events",{"href":289,"dataGaName":290,"dataGaLocation":43},"/events/","events",{"text":292,"config":293},"Partners",{"href":294,"dataGaName":295,"dataGaLocation":43},"/partners/","partners",{"backgroundColor":297,"textColor":298,"text":299,"image":300,"link":304},"#2f2a6b","#fff","Insights for the future of software development",{"altText":301,"config":302},"the source promo card",{"src":303},"/images/navigation/the-source-promo-card.svg",{"text":305,"config":306},"Read the latest",{"href":307,"dataGaName":308,"dataGaLocation":43},"/the-source/","the source",{"text":310,"config":311,"lists":313},"Company",{"dataNavLevelOne":312},"company",[314],{"items":315},[316,321,327,329,334,339,344,349,354,359,364],{"text":317,"config":318},"About",{"href":319,"dataGaName":320,"dataGaLocation":43},"/company/","about",{"text":322,"config":323,"footerGa":326},"Jobs",{"href":324,"dataGaName":325,"dataGaLocation":43},"/jobs/","jobs",{"dataGaName":325},{"text":287,"config":328},{"href":289,"dataGaName":290,"dataGaLocation":43},{"text":330,"config":331},"Leadership",{"href":332,"dataGaName":333,"dataGaLocation":43},"/company/team/e-group/","leadership",{"text":335,"config":336},"Team",{"href":337,"dataGaName":338,"dataGaLocation":43},"/company/team/","team",{"text":340,"config":341},"Handbook",{"href":342,"dataGaName":343,"dataGaLocation":43},"https://handbook.gitlab.com/","handbook",{"text":345,"config":346},"Investor relations",{"href":347,"dataGaName":348,"dataGaLocation":43},"https://ir.gitlab.com/","investor relations",{"text":350,"config":351},"Trust Center",{"href":352,"dataGaName":353,"dataGaLocation":43},"/security/","trust center",{"text":355,"config":356},"AI Transparency Center",{"href":357,"dataGaName":358,"dataGaLocation":43},"/ai-transparency-center/","ai transparency center",{"text":360,"config":361},"Newsletter",{"href":362,"dataGaName":363,"dataGaLocation":43},"/company/contact/","newsletter",{"text":365,"config":366},"Press",{"href":367,"dataGaName":368,"dataGaLocation":43},"/press/","press",{"text":370,"config":371,"lists":372},"Contact us",{"dataNavLevelOne":312},[373],{"items":374},[375,378,383],{"text":50,"config":376},{"href":52,"dataGaName":377,"dataGaLocation":43},"talk to sales",{"text":379,"config":380},"Get help",{"href":381,"dataGaName":382,"dataGaLocation":43},"/support/","get help",{"text":384,"config":385},"Customer portal",{"href":386,"dataGaName":387,"dataGaLocation":43},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":389,"login":390,"suggestions":397},"Close",{"text":391,"link":392},"To search repositories and projects, login to",{"text":393,"config":394},"gitlab.com",{"href":57,"dataGaName":395,"dataGaLocation":396},"search login","search",{"text":398,"default":399},"Suggestions",[400,402,406,408,412,416],{"text":72,"config":401},{"href":77,"dataGaName":72,"dataGaLocation":396},{"text":403,"config":404},"Code Suggestions (AI)",{"href":405,"dataGaName":403,"dataGaLocation":396},"/solutions/code-suggestions/",{"text":23,"config":407},{"href":125,"dataGaName":23,"dataGaLocation":396},{"text":409,"config":410},"GitLab on AWS",{"href":411,"dataGaName":409,"dataGaLocation":396},"/partners/technology-partners/aws/",{"text":413,"config":414},"GitLab on Google Cloud",{"href":415,"dataGaName":413,"dataGaLocation":396},"/partners/technology-partners/google-cloud-platform/",{"text":417,"config":418},"Why GitLab?",{"href":85,"dataGaName":417,"dataGaLocation":396},{"freeTrial":420,"mobileIcon":425,"desktopIcon":430,"secondaryButton":433},{"text":421,"config":422},"Start free trial",{"href":423,"dataGaName":48,"dataGaLocation":424},"https://gitlab.com/-/trials/new/","nav",{"altText":426,"config":427},"Gitlab Icon",{"src":428,"dataGaName":429,"dataGaLocation":424},"/images/brand/gitlab-logo-tanuki.svg","gitlab icon",{"altText":426,"config":431},{"src":432,"dataGaName":429,"dataGaLocation":424},"/images/brand/gitlab-logo-type.svg",{"text":434,"config":435},"Get Started",{"href":436,"dataGaName":437,"dataGaLocation":424},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/compare/gitlab-vs-github/","get started",{"freeTrial":439,"mobileIcon":443,"desktopIcon":445},{"text":440,"config":441},"Learn more about GitLab Duo",{"href":77,"dataGaName":442,"dataGaLocation":424},"gitlab duo",{"altText":426,"config":444},{"src":428,"dataGaName":429,"dataGaLocation":424},{"altText":426,"config":446},{"src":432,"dataGaName":429,"dataGaLocation":424},"content:shared:en-us:main-navigation.yml","Main Navigation","shared/en-us/main-navigation.yml","shared/en-us/main-navigation",{"_path":452,"_dir":37,"_draft":6,"_partial":6,"_locale":7,"title":453,"button":454,"config":458,"_id":460,"_type":29,"_source":31,"_file":461,"_stem":462,"_extension":34},"/shared/en-us/banner","GitLab Duo Agent Platform is now in public beta!",{"text":83,"config":455},{"href":456,"dataGaName":457,"dataGaLocation":43},"/gitlab-duo/agent-platform/","duo banner",{"layout":459},"release","content:shared:en-us:banner.yml","shared/en-us/banner.yml","shared/en-us/banner",{"_path":464,"_dir":37,"_draft":6,"_partial":6,"_locale":7,"data":465,"_id":670,"_type":29,"title":671,"_source":31,"_file":672,"_stem":673,"_extension":34},"/shared/en-us/main-footer",{"text":466,"source":467,"edit":473,"contribute":478,"config":483,"items":488,"minimal":662},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":468,"config":469},"View page source",{"href":470,"dataGaName":471,"dataGaLocation":472},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":474,"config":475},"Edit this page",{"href":476,"dataGaName":477,"dataGaLocation":472},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":479,"config":480},"Please contribute",{"href":481,"dataGaName":482,"dataGaLocation":472},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":484,"facebook":485,"youtube":486,"linkedin":487},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[489,512,569,598,632],{"title":61,"links":490,"subMenu":495},[491],{"text":492,"config":493},"DevSecOps platform",{"href":70,"dataGaName":494,"dataGaLocation":472},"devsecops platform",[496],{"title":200,"links":497},[498,502,507],{"text":499,"config":500},"View plans",{"href":202,"dataGaName":501,"dataGaLocation":472},"view plans",{"text":503,"config":504},"Why Premium?",{"href":505,"dataGaName":506,"dataGaLocation":472},"/pricing/premium/","why premium",{"text":508,"config":509},"Why Ultimate?",{"href":510,"dataGaName":511,"dataGaLocation":472},"/pricing/ultimate/","why ultimate",{"title":513,"links":514},"Solutions",[515,520,523,525,530,535,539,542,546,551,553,556,559,564],{"text":516,"config":517},"Digital transformation",{"href":518,"dataGaName":519,"dataGaLocation":472},"/topics/digital-transformation/","digital transformation",{"text":148,"config":521},{"href":143,"dataGaName":522,"dataGaLocation":472},"security & compliance",{"text":137,"config":524},{"href":120,"dataGaName":121,"dataGaLocation":472},{"text":526,"config":527},"Agile development",{"href":528,"dataGaName":529,"dataGaLocation":472},"/solutions/agile-delivery/","agile delivery",{"text":531,"config":532},"Cloud transformation",{"href":533,"dataGaName":534,"dataGaLocation":472},"/topics/cloud-native/","cloud transformation",{"text":536,"config":537},"SCM",{"href":133,"dataGaName":538,"dataGaLocation":472},"source code management",{"text":23,"config":540},{"href":125,"dataGaName":541,"dataGaLocation":472},"continuous integration & delivery",{"text":543,"config":544},"Value stream management",{"href":175,"dataGaName":545,"dataGaLocation":472},"value stream management",{"text":547,"config":548},"GitOps",{"href":549,"dataGaName":550,"dataGaLocation":472},"/solutions/gitops/","gitops",{"text":185,"config":552},{"href":187,"dataGaName":188,"dataGaLocation":472},{"text":554,"config":555},"Small business",{"href":192,"dataGaName":193,"dataGaLocation":472},{"text":557,"config":558},"Public sector",{"href":197,"dataGaName":198,"dataGaLocation":472},{"text":560,"config":561},"Education",{"href":562,"dataGaName":563,"dataGaLocation":472},"/solutions/education/","education",{"text":565,"config":566},"Financial services",{"href":567,"dataGaName":568,"dataGaLocation":472},"/solutions/finance/","financial services",{"title":205,"links":570},[571,573,575,577,580,582,584,586,588,590,592,594,596],{"text":217,"config":572},{"href":219,"dataGaName":220,"dataGaLocation":472},{"text":222,"config":574},{"href":224,"dataGaName":225,"dataGaLocation":472},{"text":227,"config":576},{"href":229,"dataGaName":230,"dataGaLocation":472},{"text":232,"config":578},{"href":234,"dataGaName":579,"dataGaLocation":472},"docs",{"text":255,"config":581},{"href":257,"dataGaName":5,"dataGaLocation":472},{"text":250,"config":583},{"href":252,"dataGaName":253,"dataGaLocation":472},{"text":259,"config":585},{"href":261,"dataGaName":262,"dataGaLocation":472},{"text":272,"config":587},{"href":274,"dataGaName":275,"dataGaLocation":472},{"text":264,"config":589},{"href":266,"dataGaName":267,"dataGaLocation":472},{"text":277,"config":591},{"href":279,"dataGaName":280,"dataGaLocation":472},{"text":282,"config":593},{"href":284,"dataGaName":285,"dataGaLocation":472},{"text":287,"config":595},{"href":289,"dataGaName":290,"dataGaLocation":472},{"text":292,"config":597},{"href":294,"dataGaName":295,"dataGaLocation":472},{"title":310,"links":599},[600,602,604,606,608,610,612,616,621,623,625,627],{"text":317,"config":601},{"href":319,"dataGaName":312,"dataGaLocation":472},{"text":322,"config":603},{"href":324,"dataGaName":325,"dataGaLocation":472},{"text":330,"config":605},{"href":332,"dataGaName":333,"dataGaLocation":472},{"text":335,"config":607},{"href":337,"dataGaName":338,"dataGaLocation":472},{"text":340,"config":609},{"href":342,"dataGaName":343,"dataGaLocation":472},{"text":345,"config":611},{"href":347,"dataGaName":348,"dataGaLocation":472},{"text":613,"config":614},"Sustainability",{"href":615,"dataGaName":613,"dataGaLocation":472},"/sustainability/",{"text":617,"config":618},"Diversity, inclusion and belonging (DIB)",{"href":619,"dataGaName":620,"dataGaLocation":472},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":350,"config":622},{"href":352,"dataGaName":353,"dataGaLocation":472},{"text":360,"config":624},{"href":362,"dataGaName":363,"dataGaLocation":472},{"text":365,"config":626},{"href":367,"dataGaName":368,"dataGaLocation":472},{"text":628,"config":629},"Modern Slavery Transparency Statement",{"href":630,"dataGaName":631,"dataGaLocation":472},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"title":633,"links":634},"Contact Us",[635,638,640,642,647,652,657],{"text":636,"config":637},"Contact an expert",{"href":52,"dataGaName":53,"dataGaLocation":472},{"text":379,"config":639},{"href":381,"dataGaName":382,"dataGaLocation":472},{"text":384,"config":641},{"href":386,"dataGaName":387,"dataGaLocation":472},{"text":643,"config":644},"Status",{"href":645,"dataGaName":646,"dataGaLocation":472},"https://status.gitlab.com/","status",{"text":648,"config":649},"Terms of use",{"href":650,"dataGaName":651,"dataGaLocation":472},"/terms/","terms of use",{"text":653,"config":654},"Privacy statement",{"href":655,"dataGaName":656,"dataGaLocation":472},"/privacy/","privacy statement",{"text":658,"config":659},"Cookie preferences",{"dataGaName":660,"dataGaLocation":472,"id":661,"isOneTrustButton":106},"cookie preferences","ot-sdk-btn",{"items":663},[664,666,668],{"text":648,"config":665},{"href":650,"dataGaName":651,"dataGaLocation":472},{"text":653,"config":667},{"href":655,"dataGaName":656,"dataGaLocation":472},{"text":658,"config":669},{"dataGaName":660,"dataGaLocation":472,"id":661,"isOneTrustButton":106},"content:shared:en-us:main-footer.yml","Main Footer","shared/en-us/main-footer.yml","shared/en-us/main-footer",[675],{"_path":676,"_dir":677,"_draft":6,"_partial":6,"_locale":7,"content":678,"config":682,"_id":684,"_type":29,"title":18,"_source":31,"_file":685,"_stem":686,"_extension":34},"/en-us/blog/authors/steve-abrams","authors",{"name":18,"config":679},{"headshot":680,"ctfId":681},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749681809/Blog/Author%20Headshots/sabrams-headshot.png","sabrams",{"template":683},"BlogAuthor","content:en-us:blog:authors:steve-abrams.yml","en-us/blog/authors/steve-abrams.yml","en-us/blog/authors/steve-abrams",{"_path":688,"_dir":37,"_draft":6,"_partial":6,"_locale":7,"header":689,"eyebrow":690,"blurb":691,"button":692,"secondaryButton":696,"_id":698,"_type":29,"title":699,"_source":31,"_file":700,"_stem":701,"_extension":34},"/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":45,"config":693},{"href":694,"dataGaName":48,"dataGaLocation":695},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":50,"config":697},{"href":52,"dataGaName":53,"dataGaLocation":695},"content:shared:en-us:next-steps.yml","Next Steps","shared/en-us/next-steps.yml","shared/en-us/next-steps",1753475334221]