[{"data":1,"prerenderedAt":718},["ShallowReactive",2],{"/en-us/blog/set-up-flux-for-gitops-on-openshift/":3,"navigation-en-us":35,"banner-en-us":464,"footer-en-us":481,"Bart Zhang":690,"next-steps-en-us":703},{"_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/set-up-flux-for-gitops-on-openshift","blog",false,"",{"title":9,"description":10,"ogTitle":9,"ogDescription":10,"noIndex":6,"ogImage":11,"ogUrl":12,"ogSiteName":13,"ogType":14,"canonicalUrls":12,"schema":15},"Set up Flux for GitOps to deploy workloads on OpenShift","Learn how to set up a sample project, complete a bootstrap Flux installation, and authenticate your installation with a project deploy token.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749682825/Blog/Hero%20Images/genericworkflow.jpg","https://about.gitlab.com/blog/set-up-flux-for-gitops-on-openshift","https://about.gitlab.com","article","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Set up Flux for GitOps to deploy workloads on OpenShift\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Bart Zhang\"}],\n        \"datePublished\": \"2023-07-05\",\n      }",{"title":9,"description":10,"authors":17,"heroImage":11,"date":19,"body":20,"category":21,"tags":22},[18],"Bart Zhang","2023-07-05","In February, we announced that [Flux CD would be our recommended approach to\ndo GitOps with\nGitLab](https://about.gitlab.com/blog/why-did-we-choose-to-integrate-fluxcd-with-gitlab/).\nThis tutorial explains how to set up GitLab and Flux to deploy workloads on\nRed Hat OpenShift. You’ll set up a sample project, complete a bootstrap Flux\ninstallation, and authenticate your installation with a project deploy\ntoken. By the end of this tutorial, you should be able to deploy an example\nNGINX workload to OpenShift from a GitLab Repo via Flux.\n\n\nYou can find the fully configured tutorial project in [this GitLab\nrepository](https://gitlab.com/gitlab-partner-demos/red-hat-demos/flux). It\nworks in conjunction with [this\nrepository](https://gitlab.com/gitlab-partner-demos/red-hat-demos/web-app-manifests),\nwhich contains the example OpenShift manifest. \n\n\n### To set up Flux for GitOps:\n\n1. Create a personal access token\n\n2. Create the Flux repository\n\n3. Create the OpenShift manifest repository\n\n4. Configure Flux to sync your manifests\n\n5. Verify your configuration\n\n\n### Prerequisites:\n\nYou must have an OpenShift cluster running. Cluster-admin privileges are\nrequired to install Flux on OpenShift, which can either be installed via\nOperatorHub or the CLI.\n\n\nWhen installing Flux with CLI, you need to set the nonroot SCC for all\ncontrollers in the flux-system namespace like this:\n\n\n```\n\nNS=\"flux-system\"\n\noc adm policy add-scc-to-user nonroot\nsystem:serviceaccount:${NS}:kustomize-controller\n\noc adm policy add-scc-to-user nonroot\nsystem:serviceaccount:${NS}:helm-controller\n\noc adm policy add-scc-to-user nonroot\nsystem:serviceaccount:${NS}:source-controller\n\noc adm policy add-scc-to-user nonroot\nsystem:serviceaccount:${NS}:notification-controller\n\noc adm policy add-scc-to-user nonroot\nsystem:serviceaccount:${NS}:image-automation-controller\n\noc adm policy add-scc-to-user nonroot\nsystem:serviceaccount:${NS}:image-reflector-controller\n\n```\n\nExpected output:\n\n```\n\nclusterrole.rbac.authorization.k8s.io/system:openshift:scc:nonroot added:\n\"kustomize-controller\"\n\nclusterrole.rbac.authorization.k8s.io/system:openshift:scc:nonroot added:\n\"helm-controller\"\n\nclusterrole.rbac.authorization.k8s.io/system:openshift:scc:nonroot added:\n\"source-controller\"\n\nclusterrole.rbac.authorization.k8s.io/system:openshift:scc:nonroot added:\n\"notification-controller\"\n\nclusterrole.rbac.authorization.k8s.io/system:openshift:scc:nonroot added:\n\"image-automation-controller\"\n\nclusterrole.rbac.authorization.k8s.io/system:openshift:scc:nonroot added:\n\"image-reflector-controller\"\n\n```\n\n\nAlso, you'll need to [patch your\nKustomization](https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html/security_and_compliance/seccomp-profiles)\nto remove the SecComp Profile and enforce runUserAs to the same UID provided\nby the images to prevent OpenShift to alter the user expected by our\ncontrollers, prior to bootstrapping the cluster.\n\n\nYou’ll need to create a Git repository and clone it locally. I chose to\ncreate [the web-app-manifests\nrepository](https://gitlab.com/gitlab-partner-demos/red-hat-demos/web-app-manifests)\nto store my manifest file once it is created through the following steps.\n\n\nCreate the file structure required by bootstrap using the following command:\n\n\n```\n\ngit clone https://gitlab.com/gitlab-partner-demos/red-hat-demos/flux/\n\ncd flux\n\nmkdir -p clusters/my-cluster/flux-system\n\ntouch clusters/my-cluster/flux-system/gotk-components.yaml \\\n    clusters/my-cluster/flux-system/gotk-sync.yaml \\\n    clusters/my-cluster/flux-system/kustomization.yaml\n```\n\n\nAdd the following YAML snippet and its patches section to\nflux/clusters/my-cluster/flux-system/kustomization.yaml:\n\n\n```\n\napiVersion: kustomize.config.k8s.io/v1beta1\n\nkind: Kustomization\n\nresources:\n  - gotk-components.yaml\n  - gotk-sync.yaml\npatches:\n  - patch: |\n      apiVersion: apps/v1\n      kind: Deployment\n      metadata:\n        name: all\n      spec:\n        template:\n          spec:\n            containers:\n              - name: manager\n                securityContext:\n                  runAsUser: 65534\n                  seccompProfile:\n                    $patch: delete      \n    target:\n      kind: Deployment\n      labelSelector: app.kubernetes.io/part-of=flux\n```\n\n\nCommit and push the changes to main branch:\n\n\n```\n\ncd ~/flux\n\ngit add -A && git commit -m \"init flux for openshift\" && git push\n\n```\n\n\n### Create a personal access token\n\n\nTo authenticate with the Flux CLI, you must create a GitLab personal access\ntoken\n([PAT](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html))\nwith the api scope:\n\n1. In the upper-right corner, select your avatar.\n\n2. Select Edit profile.\n\n3. On the left sidebar, select Access Tokens.\n\n4. Enter a name and expiry date for the token.\n\n5. Select the api scope.\n\n6. Select Create personal access token.\n\n7. Copy the new token to your clipboard.\n\n\nNote: You can also use a project or group access token with the api scope.\n\n\n### Create the Flux repository\n\nCreate a Git repository, install Flux, and authenticate Flux with your repo\nin RedHat OpenShift:\n\n1. Make sure you are logged in as an OpenShift user in your CLI to access\nyour cluster. `oc login` command is useful here.\n\n2. [Install the Flux CLI](https://fluxcd.io/flux/installation/#bootstrap).\nYou must install Flux v2 or higher. `brew install fluxcd/tap/flux` on Mac\nOSX. Check your flux version with `flux -v`. Mine is `flux version\n2.0.0-rc.1`.\n\n3. In GitLab, create a new empty project called `flux`. I chose to use [the\nrespository in this\nreadme](https://gitlab.com/gitlab-partner-demos/red-hat-demos/flux/)\n\n4. From your shell, export a GITLAB_TOKEN environment variable with the\nvalue of your personal access token. For example, `export\nGITLAB_TOKEN=\u003Cpersonal-access-token>`.\n\n5. Run the bootstrap command. The exact command depends on whether you are\ncreating the Flux repository under a GitLab user, group, or subgroup. For\nmore information, see the Flux bootstrap documentation.\n\n\nIn this tutorial, you’re working with a public project in a subgroup. The\nbootstrap command looks like this:\n\n\n```\n\ncd ~/flux\n\nflux bootstrap gitlab \\\n  --owner=gitlab-partner-demos/red-hat-demos \\\n  --repository=flux \\\n  --branch=master \\\n  --path=clusters/my-cluster \\\n  --token-auth\n```\n\nExpected output:\n\n```\n\n► connecting to https://gitlab.com\n\n► cloning branch \"master\" from Git repository\n\"https://gitlab.com/gitlab-partner-demos/red-hat-demos/flux.git\"\n\n✔ cloned repository\n\n► generating component manifests\n\n✔ generated component manifests\n\n✔ component manifests are up to date\n\n► installing components in \"flux-system\" namespace\n\n✔ installed components\n\n✔ reconciled components\n\n► determining if source secret \"flux-system/flux-system\" exists\n\n✔ source secret up to date\n\n► generating sync manifests\n\n✔ generated sync manifests\n\n✔ sync manifests are up to date\n\n► applying sync manifests\n\n✔ reconciled sync configuration\n\n◎ waiting for Kustomization \"flux-system/flux-system\" to be reconciled\n\n```\n\n\nThis command installs the Flux agent on the OpenShift cluster and configures\nit to manage itself from the repository flux-config. The command also\nautomatically creates the project deploy token required to access the\nflux-config repository.\n\n\nGreat work! You now have a repository bootstrapped with a Flux\nconfiguration. Any updates to your repository are automatically synced to\nthe cluster.\n\n\n### Create the OpenShift manifest repository\n\nNext, create a repository for your Flux manifest files. These are stateful\nfiles that track the current running configuration by\n\nthe Flux agent. I chose to use\n[web-app-manifests](https://gitlab.com/gitlab-partner-demos/red-hat-demos/web-app-manifests)\nproject to track my manifest files.\n\n1. In GitLab, create a new repository called `web-app-manifests`.\n\n1. Add a file to web-app-manifests named `nginx-deployment.yaml` with the\nfollowing contents:\n\n\n```\n\napiVersion: apps/v1\n\n\nkind: Deployment\n\n\nmetadata:\n  name: nginx-deployment\n  labels:\n    app: nginx\nspec:\n  replicas: 3\n  selector:\n    matchLabels:\n      app: nginx\n  template:\n    metadata:\n      labels:\n        app: nginx\n    spec:\n      containers:\n      - name: nginx-unprivileged\n        image: nginxinc/nginx-unprivileged:latest\n        ports:\n        - containerPort: 80\n```\n\n\nIn the new `web-app-manifests` repository, create a [GitLab deploy\ntoken](https://docs.gitlab.com/ee/user/project/deploy_tokens/) with only the\n`read_repository` scope.\n\n\nStore your deploy token username and password somewhere safe. I used\nenvironmental variables to save mine:\n\n\n```\n\nexport GITLAB_DEPLOY_TOKEN_USER=\u003Cmy-gitlab-deployment-token-username>\n\nexport GITLAB_DEPLOY_TOKEN_PASS=\u003Cmy-gitlab-deployment-token-password>\n\nenv |grep GITLAB_DEPLOY_TOKEN\n\n```\n\nExpected output:\n\n```\n\nGITLAB_DEPLOY_TOKEN_USER=myGitLabUserName\n\nGITLAB_DEPLOY_TOKEN_PASS=MySecretToken\n\n```\n\n\nIn Flux CLI, create a secret with your deploy token and point the secret to\nthe new repository. For example:\n\n\n```\n\nflux create secret git flux-deploy-authentication \\\n         --url=https://gitlab.com/gitlab-partner-demos/red-hat-demos/web-app-manifests \\\n         --namespace=default \\\n         --username=$GITLAB_DEPLOY_TOKEN_USER \\\n         --password=$GITLAB_DEPLOY_TOKEN_PASS\n```\n\nExpected output:\n\n```\n\n► git secret 'flux-deploy-authentication' created in 'default' namespace\n\n```\n\n\nTo check if your secret was generated successfully, run:\n\n\n```\n\noc -n default get secrets flux-deploy-authentication -o yaml\n\n```\n\nExpected output:\n\n```\n\napiVersion: v1\n\ndata:\n  password: Base64EncodedPassword=\n  username: Base64EncodedUsername\nkind: Secret\n\nmetadata:\n  creationTimestamp: \"2023-04-20T18:22:33Z\"\n  name: flux-deploy-authentication\n  namespace: default\n  resourceVersion: \"8168670\"\n  uid: 16292254-83cd-4df2-8a9c-bc4c718e4b4a\ntype: Opaque\n\n```\n\n\nUnder data, you should see base64-encoded values associated with your token\nusername and password.\n\n\nCongratulations! You now have a manifest repository, a deploy token, and a\nsecret generated directly on your cluster.\n\n\n### Configure Flux to sync your manifests\n\nNext, tell flux-config to sync with the web-app-manifests repository.\n\n\nTo do so, create a [GitRepository\nresource](https://docs.openshift.com/container-platform/3.11/dev_guide/application_lifecycle/new_app.html)\nin OpenShift:\n\n\n1. Clone the flux repo to your machine.\n\n```\n\n# Remember that we already have the flux repo cloned into our home dir.\n\ncd ~/flux\n\ngit pull\n\n```\n\n\n2. In your local clone of flux, add the GitRepository file\n`clusters/my-cluster/web-app-manifests-source.yaml`:\n  \n```\n","engineering",[23,24],"tutorial","GitOps",{"slug":26,"featured":6,"template":27},"set-up-flux-for-gitops-on-openshift","BlogPost","content:en-us:blog:set-up-flux-for-gitops-on-openshift.yml","yaml","Set Up Flux For Gitops On Openshift","content","en-us/blog/set-up-flux-for-gitops-on-openshift.yml","en-us/blog/set-up-flux-for-gitops-on-openshift","yml",{"_path":36,"_dir":37,"_draft":6,"_partial":6,"_locale":7,"data":38,"_id":460,"_type":29,"title":461,"_source":31,"_file":462,"_stem":463,"_extension":34},"/shared/en-us/main-navigation","en-us",{"logo":39,"freeTrial":44,"sales":49,"login":54,"items":59,"search":391,"minimal":422,"duo":441,"pricingDeployment":450},{"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,202,207,312,372],{"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":184},"Product",true,{"dataNavLevelOne":108},"solutions",{"text":110,"config":111},"View all Solutions",{"href":112,"dataGaName":108,"dataGaLocation":43},"/solutions/",[114,139,163],{"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,127,131,135],{"text":124,"config":125},"CI/CD",{"href":126,"dataGaLocation":43,"dataGaName":124},"/solutions/continuous-integration/",{"text":128,"config":129},"AI-Assisted Development",{"href":77,"dataGaLocation":43,"dataGaName":130},"AI assisted development",{"text":132,"config":133},"Source Code Management",{"href":134,"dataGaLocation":43,"dataGaName":132},"/solutions/source-code-management/",{"text":136,"config":137},"Automated Software Delivery",{"href":120,"dataGaLocation":43,"dataGaName":138},"Automated software delivery",{"title":140,"description":141,"link":142,"items":147},"Security","Deliver code faster without compromising security",{"config":143},{"href":144,"dataGaName":145,"dataGaLocation":43,"icon":146},"/solutions/security-compliance/","security and compliance","ShieldCheckLight",[148,153,158],{"text":149,"config":150},"Application Security Testing",{"href":151,"dataGaName":152,"dataGaLocation":43},"/solutions/application-security-testing/","Application security testing",{"text":154,"config":155},"Software Supply Chain Security",{"href":156,"dataGaLocation":43,"dataGaName":157},"/solutions/supply-chain/","Software supply chain security",{"text":159,"config":160},"Software Compliance",{"href":161,"dataGaName":162,"dataGaLocation":43},"/solutions/software-compliance/","software compliance",{"title":164,"link":165,"items":170},"Measurement",{"config":166},{"icon":167,"href":168,"dataGaName":169,"dataGaLocation":43},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[171,175,179],{"text":172,"config":173},"Visibility & Measurement",{"href":168,"dataGaLocation":43,"dataGaName":174},"Visibility and Measurement",{"text":176,"config":177},"Value Stream Management",{"href":178,"dataGaLocation":43,"dataGaName":176},"/solutions/value-stream-management/",{"text":180,"config":181},"Analytics & Insights",{"href":182,"dataGaLocation":43,"dataGaName":183},"/solutions/analytics-and-insights/","Analytics and insights",{"title":185,"items":186},"GitLab for",[187,192,197],{"text":188,"config":189},"Enterprise",{"href":190,"dataGaLocation":43,"dataGaName":191},"/enterprise/","enterprise",{"text":193,"config":194},"Small Business",{"href":195,"dataGaLocation":43,"dataGaName":196},"/small-business/","small business",{"text":198,"config":199},"Public Sector",{"href":200,"dataGaLocation":43,"dataGaName":201},"/solutions/public-sector/","public sector",{"text":203,"config":204},"Pricing",{"href":205,"dataGaName":206,"dataGaLocation":43,"dataNavLevelOne":206},"/pricing/","pricing",{"text":208,"config":209,"link":211,"lists":215,"feature":299},"Resources",{"dataNavLevelOne":210},"resources",{"text":212,"config":213},"View all resources",{"href":214,"dataGaName":210,"dataGaLocation":43},"/resources/",[216,249,271],{"title":217,"items":218},"Getting started",[219,224,229,234,239,244],{"text":220,"config":221},"Install",{"href":222,"dataGaName":223,"dataGaLocation":43},"/install/","install",{"text":225,"config":226},"Quick start guides",{"href":227,"dataGaName":228,"dataGaLocation":43},"/get-started/","quick setup checklists",{"text":230,"config":231},"Learn",{"href":232,"dataGaLocation":43,"dataGaName":233},"https://university.gitlab.com/","learn",{"text":235,"config":236},"Product documentation",{"href":237,"dataGaName":238,"dataGaLocation":43},"https://docs.gitlab.com/","product documentation",{"text":240,"config":241},"Best practice videos",{"href":242,"dataGaName":243,"dataGaLocation":43},"/getting-started-videos/","best practice videos",{"text":245,"config":246},"Integrations",{"href":247,"dataGaName":248,"dataGaLocation":43},"/integrations/","integrations",{"title":250,"items":251},"Discover",[252,257,261,266],{"text":253,"config":254},"Customer success stories",{"href":255,"dataGaName":256,"dataGaLocation":43},"/customers/","customer success stories",{"text":258,"config":259},"Blog",{"href":260,"dataGaName":5,"dataGaLocation":43},"/blog/",{"text":262,"config":263},"Remote",{"href":264,"dataGaName":265,"dataGaLocation":43},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"text":267,"config":268},"TeamOps",{"href":269,"dataGaName":270,"dataGaLocation":43},"/teamops/","teamops",{"title":272,"items":273},"Connect",[274,279,284,289,294],{"text":275,"config":276},"GitLab Services",{"href":277,"dataGaName":278,"dataGaLocation":43},"/services/","services",{"text":280,"config":281},"Community",{"href":282,"dataGaName":283,"dataGaLocation":43},"/community/","community",{"text":285,"config":286},"Forum",{"href":287,"dataGaName":288,"dataGaLocation":43},"https://forum.gitlab.com/","forum",{"text":290,"config":291},"Events",{"href":292,"dataGaName":293,"dataGaLocation":43},"/events/","events",{"text":295,"config":296},"Partners",{"href":297,"dataGaName":298,"dataGaLocation":43},"/partners/","partners",{"backgroundColor":300,"textColor":301,"text":302,"image":303,"link":307},"#2f2a6b","#fff","Insights for the future of software development",{"altText":304,"config":305},"the source promo card",{"src":306},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758208064/dzl0dbift9xdizyelkk4.svg",{"text":308,"config":309},"Read the latest",{"href":310,"dataGaName":311,"dataGaLocation":43},"/the-source/","the source",{"text":313,"config":314,"lists":316},"Company",{"dataNavLevelOne":315},"company",[317],{"items":318},[319,324,330,332,337,342,347,352,357,362,367],{"text":320,"config":321},"About",{"href":322,"dataGaName":323,"dataGaLocation":43},"/company/","about",{"text":325,"config":326,"footerGa":329},"Jobs",{"href":327,"dataGaName":328,"dataGaLocation":43},"/jobs/","jobs",{"dataGaName":328},{"text":290,"config":331},{"href":292,"dataGaName":293,"dataGaLocation":43},{"text":333,"config":334},"Leadership",{"href":335,"dataGaName":336,"dataGaLocation":43},"/company/team/e-group/","leadership",{"text":338,"config":339},"Team",{"href":340,"dataGaName":341,"dataGaLocation":43},"/company/team/","team",{"text":343,"config":344},"Handbook",{"href":345,"dataGaName":346,"dataGaLocation":43},"https://handbook.gitlab.com/","handbook",{"text":348,"config":349},"Investor relations",{"href":350,"dataGaName":351,"dataGaLocation":43},"https://ir.gitlab.com/","investor relations",{"text":353,"config":354},"Trust Center",{"href":355,"dataGaName":356,"dataGaLocation":43},"/security/","trust center",{"text":358,"config":359},"AI Transparency Center",{"href":360,"dataGaName":361,"dataGaLocation":43},"/ai-transparency-center/","ai transparency center",{"text":363,"config":364},"Newsletter",{"href":365,"dataGaName":366,"dataGaLocation":43},"/company/contact/","newsletter",{"text":368,"config":369},"Press",{"href":370,"dataGaName":371,"dataGaLocation":43},"/press/","press",{"text":373,"config":374,"lists":375},"Contact us",{"dataNavLevelOne":315},[376],{"items":377},[378,381,386],{"text":50,"config":379},{"href":52,"dataGaName":380,"dataGaLocation":43},"talk to sales",{"text":382,"config":383},"Get help",{"href":384,"dataGaName":385,"dataGaLocation":43},"/support/","get help",{"text":387,"config":388},"Customer portal",{"href":389,"dataGaName":390,"dataGaLocation":43},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":392,"login":393,"suggestions":400},"Close",{"text":394,"link":395},"To search repositories and projects, login to",{"text":396,"config":397},"gitlab.com",{"href":57,"dataGaName":398,"dataGaLocation":399},"search login","search",{"text":401,"default":402},"Suggestions",[403,405,409,411,415,419],{"text":72,"config":404},{"href":77,"dataGaName":72,"dataGaLocation":399},{"text":406,"config":407},"Code Suggestions (AI)",{"href":408,"dataGaName":406,"dataGaLocation":399},"/solutions/code-suggestions/",{"text":124,"config":410},{"href":126,"dataGaName":124,"dataGaLocation":399},{"text":412,"config":413},"GitLab on AWS",{"href":414,"dataGaName":412,"dataGaLocation":399},"/partners/technology-partners/aws/",{"text":416,"config":417},"GitLab on Google Cloud",{"href":418,"dataGaName":416,"dataGaLocation":399},"/partners/technology-partners/google-cloud-platform/",{"text":420,"config":421},"Why GitLab?",{"href":85,"dataGaName":420,"dataGaLocation":399},{"freeTrial":423,"mobileIcon":428,"desktopIcon":433,"secondaryButton":436},{"text":424,"config":425},"Start free trial",{"href":426,"dataGaName":48,"dataGaLocation":427},"https://gitlab.com/-/trials/new/","nav",{"altText":429,"config":430},"Gitlab Icon",{"src":431,"dataGaName":432,"dataGaLocation":427},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":429,"config":434},{"src":435,"dataGaName":432,"dataGaLocation":427},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":437,"config":438},"Get Started",{"href":439,"dataGaName":440,"dataGaLocation":427},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/compare/gitlab-vs-github/","get started",{"freeTrial":442,"mobileIcon":446,"desktopIcon":448},{"text":443,"config":444},"Learn more about GitLab Duo",{"href":77,"dataGaName":445,"dataGaLocation":427},"gitlab duo",{"altText":429,"config":447},{"src":431,"dataGaName":432,"dataGaLocation":427},{"altText":429,"config":449},{"src":435,"dataGaName":432,"dataGaLocation":427},{"freeTrial":451,"mobileIcon":456,"desktopIcon":458},{"text":452,"config":453},"Back to pricing",{"href":205,"dataGaName":454,"dataGaLocation":427,"icon":455},"back to pricing","GoBack",{"altText":429,"config":457},{"src":431,"dataGaName":432,"dataGaLocation":427},{"altText":429,"config":459},{"src":435,"dataGaName":432,"dataGaLocation":427},"content:shared:en-us:main-navigation.yml","Main Navigation","shared/en-us/main-navigation.yml","shared/en-us/main-navigation",{"_path":465,"_dir":37,"_draft":6,"_partial":6,"_locale":7,"title":466,"button":467,"image":472,"config":476,"_id":478,"_type":29,"_source":31,"_file":479,"_stem":480,"_extension":34},"/shared/en-us/banner","is now in public beta!",{"text":468,"config":469},"Try the Beta",{"href":470,"dataGaName":471,"dataGaLocation":43},"/gitlab-duo/agent-platform/","duo banner",{"altText":473,"config":474},"GitLab Duo Agent Platform",{"src":475},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1753720689/somrf9zaunk0xlt7ne4x.svg",{"layout":477},"release","content:shared:en-us:banner.yml","shared/en-us/banner.yml","shared/en-us/banner",{"_path":482,"_dir":37,"_draft":6,"_partial":6,"_locale":7,"data":483,"_id":686,"_type":29,"title":687,"_source":31,"_file":688,"_stem":689,"_extension":34},"/shared/en-us/main-footer",{"text":484,"source":485,"edit":491,"contribute":496,"config":501,"items":506,"minimal":678},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":486,"config":487},"View page source",{"href":488,"dataGaName":489,"dataGaLocation":490},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":492,"config":493},"Edit this page",{"href":494,"dataGaName":495,"dataGaLocation":490},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":497,"config":498},"Please contribute",{"href":499,"dataGaName":500,"dataGaLocation":490},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":502,"facebook":503,"youtube":504,"linkedin":505},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[507,530,585,614,648],{"title":61,"links":508,"subMenu":513},[509],{"text":510,"config":511},"DevSecOps platform",{"href":70,"dataGaName":512,"dataGaLocation":490},"devsecops platform",[514],{"title":203,"links":515},[516,520,525],{"text":517,"config":518},"View plans",{"href":205,"dataGaName":519,"dataGaLocation":490},"view plans",{"text":521,"config":522},"Why Premium?",{"href":523,"dataGaName":524,"dataGaLocation":490},"/pricing/premium/","why premium",{"text":526,"config":527},"Why Ultimate?",{"href":528,"dataGaName":529,"dataGaLocation":490},"/pricing/ultimate/","why ultimate",{"title":531,"links":532},"Solutions",[533,538,540,542,547,552,556,559,563,567,569,572,575,580],{"text":534,"config":535},"Digital transformation",{"href":536,"dataGaName":537,"dataGaLocation":490},"/topics/digital-transformation/","digital transformation",{"text":149,"config":539},{"href":151,"dataGaName":149,"dataGaLocation":490},{"text":138,"config":541},{"href":120,"dataGaName":121,"dataGaLocation":490},{"text":543,"config":544},"Agile development",{"href":545,"dataGaName":546,"dataGaLocation":490},"/solutions/agile-delivery/","agile delivery",{"text":548,"config":549},"Cloud transformation",{"href":550,"dataGaName":551,"dataGaLocation":490},"/topics/cloud-native/","cloud transformation",{"text":553,"config":554},"SCM",{"href":134,"dataGaName":555,"dataGaLocation":490},"source code management",{"text":124,"config":557},{"href":126,"dataGaName":558,"dataGaLocation":490},"continuous integration & delivery",{"text":560,"config":561},"Value stream management",{"href":178,"dataGaName":562,"dataGaLocation":490},"value stream management",{"text":24,"config":564},{"href":565,"dataGaName":566,"dataGaLocation":490},"/solutions/gitops/","gitops",{"text":188,"config":568},{"href":190,"dataGaName":191,"dataGaLocation":490},{"text":570,"config":571},"Small business",{"href":195,"dataGaName":196,"dataGaLocation":490},{"text":573,"config":574},"Public sector",{"href":200,"dataGaName":201,"dataGaLocation":490},{"text":576,"config":577},"Education",{"href":578,"dataGaName":579,"dataGaLocation":490},"/solutions/education/","education",{"text":581,"config":582},"Financial services",{"href":583,"dataGaName":584,"dataGaLocation":490},"/solutions/finance/","financial services",{"title":208,"links":586},[587,589,591,593,596,598,600,602,604,606,608,610,612],{"text":220,"config":588},{"href":222,"dataGaName":223,"dataGaLocation":490},{"text":225,"config":590},{"href":227,"dataGaName":228,"dataGaLocation":490},{"text":230,"config":592},{"href":232,"dataGaName":233,"dataGaLocation":490},{"text":235,"config":594},{"href":237,"dataGaName":595,"dataGaLocation":490},"docs",{"text":258,"config":597},{"href":260,"dataGaName":5,"dataGaLocation":490},{"text":253,"config":599},{"href":255,"dataGaName":256,"dataGaLocation":490},{"text":262,"config":601},{"href":264,"dataGaName":265,"dataGaLocation":490},{"text":275,"config":603},{"href":277,"dataGaName":278,"dataGaLocation":490},{"text":267,"config":605},{"href":269,"dataGaName":270,"dataGaLocation":490},{"text":280,"config":607},{"href":282,"dataGaName":283,"dataGaLocation":490},{"text":285,"config":609},{"href":287,"dataGaName":288,"dataGaLocation":490},{"text":290,"config":611},{"href":292,"dataGaName":293,"dataGaLocation":490},{"text":295,"config":613},{"href":297,"dataGaName":298,"dataGaLocation":490},{"title":313,"links":615},[616,618,620,622,624,626,628,632,637,639,641,643],{"text":320,"config":617},{"href":322,"dataGaName":315,"dataGaLocation":490},{"text":325,"config":619},{"href":327,"dataGaName":328,"dataGaLocation":490},{"text":333,"config":621},{"href":335,"dataGaName":336,"dataGaLocation":490},{"text":338,"config":623},{"href":340,"dataGaName":341,"dataGaLocation":490},{"text":343,"config":625},{"href":345,"dataGaName":346,"dataGaLocation":490},{"text":348,"config":627},{"href":350,"dataGaName":351,"dataGaLocation":490},{"text":629,"config":630},"Sustainability",{"href":631,"dataGaName":629,"dataGaLocation":490},"/sustainability/",{"text":633,"config":634},"Diversity, inclusion and belonging (DIB)",{"href":635,"dataGaName":636,"dataGaLocation":490},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":353,"config":638},{"href":355,"dataGaName":356,"dataGaLocation":490},{"text":363,"config":640},{"href":365,"dataGaName":366,"dataGaLocation":490},{"text":368,"config":642},{"href":370,"dataGaName":371,"dataGaLocation":490},{"text":644,"config":645},"Modern Slavery Transparency Statement",{"href":646,"dataGaName":647,"dataGaLocation":490},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"title":649,"links":650},"Contact Us",[651,654,656,658,663,668,673],{"text":652,"config":653},"Contact an expert",{"href":52,"dataGaName":53,"dataGaLocation":490},{"text":382,"config":655},{"href":384,"dataGaName":385,"dataGaLocation":490},{"text":387,"config":657},{"href":389,"dataGaName":390,"dataGaLocation":490},{"text":659,"config":660},"Status",{"href":661,"dataGaName":662,"dataGaLocation":490},"https://status.gitlab.com/","status",{"text":664,"config":665},"Terms of use",{"href":666,"dataGaName":667,"dataGaLocation":490},"/terms/","terms of use",{"text":669,"config":670},"Privacy statement",{"href":671,"dataGaName":672,"dataGaLocation":490},"/privacy/","privacy statement",{"text":674,"config":675},"Cookie preferences",{"dataGaName":676,"dataGaLocation":490,"id":677,"isOneTrustButton":106},"cookie preferences","ot-sdk-btn",{"items":679},[680,682,684],{"text":664,"config":681},{"href":666,"dataGaName":667,"dataGaLocation":490},{"text":669,"config":683},{"href":671,"dataGaName":672,"dataGaLocation":490},{"text":674,"config":685},{"dataGaName":676,"dataGaLocation":490,"id":677,"isOneTrustButton":106},"content:shared:en-us:main-footer.yml","Main Footer","shared/en-us/main-footer.yml","shared/en-us/main-footer",[691],{"_path":692,"_dir":693,"_draft":6,"_partial":6,"_locale":7,"content":694,"config":698,"_id":700,"_type":29,"title":18,"_source":31,"_file":701,"_stem":702,"_extension":34},"/en-us/blog/authors/bart-zhang","authors",{"name":18,"config":695},{"headshot":696,"ctfId":697},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749664177/Blog/Author%20Headshots/bartzhang-headshot.jpg","bartzhang",{"template":699},"BlogAuthor","content:en-us:blog:authors:bart-zhang.yml","en-us/blog/authors/bart-zhang.yml","en-us/blog/authors/bart-zhang",{"_path":704,"_dir":37,"_draft":6,"_partial":6,"_locale":7,"header":705,"eyebrow":706,"blurb":707,"button":708,"secondaryButton":712,"_id":714,"_type":29,"title":715,"_source":31,"_file":716,"_stem":717,"_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":709},{"href":710,"dataGaName":48,"dataGaLocation":711},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":50,"config":713},{"href":52,"dataGaName":53,"dataGaLocation":711},"content:shared:en-us:next-steps.yml","Next Steps","shared/en-us/next-steps.yml","shared/en-us/next-steps",1758326264714]