[{"data":1,"prerenderedAt":709},["ShallowReactive",2],{"/en-us/blog/tutorial-install-vs-code-on-a-cloud-provider-vm-and-set-up-remote-access/":3,"navigation-en-us":37,"banner-en-us":455,"footer-en-us":471,"Cesar Saavedra":681,"next-steps-en-us":694},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"seo":8,"content":16,"config":26,"_id":30,"_type":31,"title":32,"_source":33,"_file":34,"_stem":35,"_extension":36},"/en-us/blog/tutorial-install-vs-code-on-a-cloud-provider-vm-and-set-up-remote-access","blog",false,"",{"title":9,"description":10,"ogTitle":9,"ogDescription":10,"noIndex":6,"ogImage":11,"ogUrl":12,"ogSiteName":13,"ogType":14,"canonicalUrls":12,"schema":15},"Tutorial: Install VS Code on a cloud provider VM and set up remote access","Learn how to automate the installation of VS Code on a VM running on a cloud provider and how to access it from your local laptop.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749670563/Blog/Hero%20Images/cloudcomputing.jpg","https://about.gitlab.com/blog/tutorial-install-vs-code-on-a-cloud-provider-vm-and-set-up-remote-access","https://about.gitlab.com","article","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Tutorial: Install VS Code on a cloud provider VM and set up remote access\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Cesar Saavedra\"}],\n        \"datePublished\": \"2024-05-06\",\n      }",{"title":9,"description":10,"authors":17,"heroImage":11,"date":19,"body":20,"category":21,"tags":22},[18],"Cesar Saavedra","2024-05-06","DevSecOps teams can sometimes find they need to run an instance of Visual\nStudio Code (VS Code) remotely for team members to share when they don't\nhave enough local resources. However, installing, running, and using VS Code\non a remote virtual machine (VM) via a cloud provider can be a complex\nprocess full of pitfalls and false starts. This tutorial covers how to\nautomate the installation of VS Code on a VM running on a cloud provider.\n\n\nThis approach involves two separate GitLab projects, each with its own\npipeline. The first one uses Terraform to instantiate a virtual machine in\nGCP running Linux Debian. The second one installs VS Code on the newly\ninstantiated VM. Lastly, we provide a procedure on how to set up your local\nMac laptop to connect and use the VS Code instance installed on the remote\nVM.\n\n\n## Create a Debian Linux distribution VM on GCP\n\n\nHere are the steps to create a Debian Linux distribution VM on GCP.\n\n\n### Prerequisites\n\n\n1. A GCP account. If you don't have one, please [create\none](https://cloud.google.com/free?hl=en).\n\n2. A GitLab account on [gitlab.com](https://gitlab.com/users/sign_in)\n\n\n**Note:** This installation uses:\n\n\n- Debian 5.10.205-2 (2023-12-31) x86_64 GNU/Linux, a.k.a Debian 11\n\n\n### Create a service account and download its key\n\n\nBefore you create the first GitLab project, you need to create a service\naccount in GCP and then generate and download a key. You will need this key\nso that your GitLab pipelines can communicate to GCP and the GitLab API.\n\n\n1. To authenticate GCP with GitLab, sign in to your GCP account and create a\n[GCP service\naccount](https://cloud.google.com/docs/authentication#service-accounts) with\nthe following roles:\n\n- `Compute Network Admin`\n\n- `Compute Admin`\n\n- `Service Account User`\n\n- `Service Account Admin`\n\n- `Security Admin`\n\n\n3. Download the JSON file with the service account key you created in the\nprevious step.\n\n4. On your computer, encode the JSON file to `base64` (replace\n`/path/to/sa-key.json` to the path where your key is located):\n\n   ```shell\n   base64 -i /path/to/sa-key.json | tr -d \\\\n\n   ```\n\n**NOTE:** Save the output of this command. You will use it later as the\nvalue for the `BASE64_GOOGLE_CREDENTIALS` environment variable.\n\n\n### Configure your GitLab project\n\n\nNext, you need to create and configure the first GitLab project.\n\n\n1. Create a group in your GitLab workspace and name it `gcpvmlinuxvscode`.\n\n\n1. Inside your newly created group, clone the following project:\n\n   ```shell\n   git@gitlab.com:tech-marketing/sandbox/gcpvmlinuxvscode/gcpvmlnxsetup.git\n   ```\n\n1. Drill into your newly cloned project, `gcpvmlnxsetup`, and set up the\nfollowing CI/CD variables to configure it:\n   1. On the left sidebar, select **Settings > CI/CD**.\n   1. Expand **Variables**.\n   1. Set the variable `BASE64_GOOGLE_CREDENTIALS` to the `base64` encoded JSON file you created in the previous section.\n   1. Set the variable `TF_VAR_gcp_project` to your GCP `project` ID.\n   1. Set the variable `TF_VAR_gcp_region` to your GCP `region` ID, e.g. us-east1, which is also its default value.\n   1. Set the variable `TF_VAR_gcp_zone` to your GCP `zone` ID, e.g. us-east1-d, which is also its default value.\n   1. Set the variable `TF_VAR_machine_type` to the GCP `machine type` ID, e.g. e2-standard-2, which is also its default value.\n   1. Set the variable `TF_VAR_gcp_vmname` to the GCP `vm name` you want to give the VM, e.g. my-test-vm, which is also its default value.\n\n**Note:** We have followed a minimalist approach to set up this VM. If you\nwould like to customize the VM further, please refer to the [Google\nTerraform\nprovider](https://registry.terraform.io/providers/hashicorp/google/latest/docs/guides/provider_reference)\nand the [Google Compute Instance Terraform\nprovider](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_instance)\ndocumentation for additional resource options.\n\n\n### Provision your VM\n\n\nAfter configuring your project, manually trigger the provisioning of your VM\nas follows:\n\n\n1. On the left sidebar, go to **Build > Pipelines**.\n\n1. Next to **Play** (**{play}**), select the dropdown list icon\n(**{chevron-lg-down}**).\n\n1. Select **Deploy** to manually trigger the deployment job.\n\n\nWhen the pipeline finishes successfully, you can see your new VM on GCP:\n\n\n- Check it on your [GCP console's VM instances\nlist](https://console.cloud.google.com/compute/instances).\n\n\n### Remove the VM\n\n\n**Important note:** Only run the cleanup job when you no longer need the GCP\nVM and/or the VS Code that you installed in it.\n\n\nA manual cleanup job is included in your pipeline by default. To remove all\ncreated resources:\n\n\n1. On the left sidebar, select **Build > Pipelines** and select the most\nrecent pipeline.\n\n1. For the `destroy` job, select **Play** (**{play}**).\n\n\n## Install and set up VS Code on a GCP VM\n\n\nPerform the steps in this section only after you have successfully finished\nthe previous sections above. In this section, you will create the second\nGitLab project that will install VS Code and its dependencies on the running\nVM on GCP.\n\n\n### Prerequisites\n\n\n1. A provisioned GCP VM. We covered this in the previous sections.\n\n\n**Note:** This installation uses:\n\n\n- VS Code Version 1.85.2\n\n\n### Configure your project\n\n\n**Note:** Since you will be using the `ssh` command multiple times on your\nlaptop, we strongly suggest that you make a backup copy of your laptop local\ndirectory `$HOME/.ssh` before continuing.\n\n\nNext, you need to create and configure the second GitLab project.\n\n\n1. Head over to your GitLab group `gcpvmlinuxvscode`, which you created at\nthe beginning of this post.\n\n\n1. Inside group, `gcpvmlinuxvscode`, clone the following project:\n\n   ```shell\n   git@gitlab.com:tech-marketing/sandbox/gcpvmlinuxvscode/vscvmsetup.git\n   ```\n\n1. Drill into your newly cloned project, `vscvmsetup` and set up the\nfollowing CI/CD variables to configure it:\n   1. On the left sidebar, select **Settings > CI/CD**.\n   1. Expand **Variables**.\n   1. Set the variable `BASE64_GOOGLE_CREDENTIALS` to the `base64` encoded JSON file you created in project `gcpvmlnxvsc`. You can copy this value from the variable with the same name in project `gcpvmlnxvsc`.\n   1. Set the variable `gcp_project` to your GCP `project` ID.\n   1. Set the variable `gcp_vmname` to your GCP `region` ID, e.g. us-east1.\n   1. Set the variable `gcp_zone` to your GCP `zone` ID, e.g. us-east1-d.\n   1. Set the variable `vm_pwd` to the password that you will use to ssh to the VM.\n   1. Set the variable `gcp_vm_username` to the first portion (before the \"@\" sign) of the email associated to your GCP account, which should be your GitLab email.\n\n### Run the project pipeline\n\n\nAfter configuring the second GitLab project, manually trigger the\nprovisioning of VS Code and its dependencies to the GCP VM as follows:\n\n\n1. On the left sidebar, select **Build > Pipelines** and click on the button\n**Run Pipeline**. On the next screen, click on the button **Run pipeline**.\n\n    The pipeline will:\n\n    - install `xauth` on the virtual machine. This is needed for effective X11 communication between your local desktop and the VM \n    - install `git` on the VM\n    - install `Visual Studio Code` on the VM.\n\n2. At this point, you can wait until the pipeline successfully completes. If\nyou don't want to wait, you can continue to do the first step of the next\nsection. However, you must ensure the pipeline has successfully completed\nbefore you can perform Step 2 of the next section.\n\n\n### Connect to your VM from your local Mac laptop\n\n\nNow that you have an instance of VS Code running on a Linux VM on GCP, you\nneed to configure your Mac laptop to be able to act as a client to the\nremote VM. Follow these steps:\n\n\n1. To connect to the remote VS Code from your Mac, you must first install\n`XQuartz` on your Mac. You can execute the following command on your Mac to\ninstall it:\n\n\n```\n\nbrew install xquartz\n\n```\n\nOr, you can follow the instructions from the following\n[tutorial](https://und.edu/research/computational-research-center/tutorials/mac-x11.html)\nfrom the University of North Dakota.\n\n\nAfter the pipeline for project `vscvmsetup` successfully executes to\ncompletion (pipeline you manually executed in the previous section), you can\nconnect to the remote VS Code as follows:\n\n\n2. Launch `XQuartz` on your Mac (it should be located in your Applications\nfolder). Its launching should open up an `xterm` on your Mac. If it does\nnot, then you can select **Applications > Terminal** from the `XQuartz` top\nmenu. \n\n3. On the `xterm`, enter the following command:\n\n\n```\n\ngcloud compute ssh --zone \"[GCP zone]\" \"[name of your VM]\" --project \"[GCP\nproject]\" --ssh-flag=\"-Y\"\n\n```\n\nWhere:\n\n\n- `[VM name]` is the name of the VM you created in project `gcpvmlnxvsc`.\nIts value should be the same as the `gcp_project` variable.\n\n- `[GCP zone]` is the zone where the VM is running. Its value should be the\nsame as the `gcp_vmname` variable.\n\n- `[GCP project]` is the name of your GCP project assigned name. Its value\nshould be the same as the `gcp_project` variable.\n\n\n***Note: If you have not installed the Google Cloud CLI, please do so by\nfollowing the [Google\ndocumentation](https://cloud.google.com/sdk/docs/install).***\n\n\n4. If you have not used SSH on your Mac before, you may not have a `.ssh` in\nyour `HOME` directory. If this is the case, you will be asked if you would\nlike to continue with the creation of this directory. Answer **Y**.\n\n\n5. Next, you will be asked to enter the same password twice to generate a\npublic/private key. Enter the same password you used when defining the\nvariable `vm_pwd` in the required configuration above.\n\n\n6. Once the SSH key is done propagating, you will need to enter the password\nagain two times to log in to the VM.\n\n\n7. You should now be logged in to the VM.\n\n\n### Create a personal access token\n\n\nThe assumption here is that you already have a GitLab project that you would\nwant to open from and work on the remote VS Code. To do this, you will need\nto clone your GitLab project from the VM. First, you will be using a\npersonal access token (PAT) to clone your project.\n\n\n1. Head over to your GitLab project (the one that you'd like to open from\nthe remote VS Code).\n\n2. From your GitLab project, create a\n[PAT](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html#create-a-personal-access-token),\nname it `pat-gcpvm` and ensure that it has the following scopes:\n`read_repository`, `write_repository`, `read_registry`, `write_registry`,\nand `ai_features`\n\n3. Save the generated PAT somewhere safe; you will need it later.\n\n\n### Clone the read_repository\n\n\n1. On your local Mac, from the `xterm` where you are logged on to the remote\nVM, enter the following command:\n\n\n```\n\ngit clone https://[your GitLab\nusername]:[personal_access_token]@gitlab.com/[GitLab project name].git \n\n```\n\n\nWhere:\n\n\n- `[your GitLab username]` is your GitLab handle.\n\n- `[personal_access_token]` is the PAT you created in the previous section.\n\n- `[GitLab project name]` is the name of the project that contains the\nGitLab Code Suggestions test cases.\n\n\n## Launch Visual Studio Code\n\n\n1. From the `xterm` where you are logged in to the VM, enter the following\ncommand:\n\n\n```\n\ncode\n\n```\n\n\nWait for a few seconds and Visual Studio Code will appear on your Mac\nscreen.\n\n\n2. From the VS Code menu, select **File > Open Folder...\"\n\n3. In the File chooser, select the top-level directory of the GitLab project\nyou cloned in the previous section\n\n\nThat's it! You're ready to start working on your cloned GitLab project using\nthe VS Code that you installed on a remote Linux-based VM.\n\n\n### Troubleshooting\n\n\nWhile using the remotely installed VS Code from your local Mac, you may\nencounter a few issues. In this section, we provide guidance on how to\nmitigate them.\n\n\n#### Keyboard keys not mapped correctly\n\n\nIf, while running VS Code, you are having issues with your keyboard keys not\nbeing mapped correctly, e.g. letter e is backspace, letter r is tab, letter\ns is clear line, etc., do the following:\n\n\n1. In VS Code, select **File > Preferences > Settings**.\n\n1. Search for \"keyboard\". If having issues with the letter e, then search\nfor \"board\". Click on the \"Keyboard\" entry under \"Application.\"\n\n1. Ensure that the Keyboard Dispatch is set to \"keyCode.\"\n\n1. Restart VS Code.\n\n1. If you need further help, this is a good resource for [keyboard\nproblems](https://github.com/microsoft/vscode/wiki/Keybinding-Issues#troubleshoot-linux-keybindings).\n\n\n#### Error loading webview: Error\n\n\nIf while running VS Code, you get a message saying:\n\n\n\"Error loading webview: Error: Could not register service worker:\nInvalidStateError: Failed to register a ServiceWorker: The document is in an\ninvalid state.\"\n\n\n1. Exit VS Code and then enter this cmd from the `xterm` window:\n\n\n`killall code`\n\n\nYou may need to execute this command two or three times in a row to kill all\nVS Code processes.\n\n\n2. Ensure that all VS Code-related processes are gone by entering the\nfollowing command from the `xterm` window:\n\n\n`ps -ef | grep code`\n\n\n3. Once all the VS Code-related processes are gone, restart VS Code by\nentering the following command from the `xterm` window:\n\n\n`code`\n\n\n#### Some useful commands to debug SSH\n\n\nHere are some useful commands to run on the VM that can help you debug SSH\nissues:\n\n\n1. To get the status, location and latest event of sshd:\n\n\n`sudo systemctl status ssh`\n\n\n2. To see the log of sshd:\n\n\n`journalctl -b -a -u ssh`\n\n\n3. To restart to SSH daemon:\n\n\n`sudo systemctl restart ssh.service`\n\n\nOr\n\n\n`sudo systemctl restart ssh`\n\n\n4. To start a root shell:\n\n\n`sudo -s`\n\n\n## Get started\n\n\nThis article described how to:\n\n- instantiate a Linux-based VM on GCP\n\n- install VS Code and dependencies on the remote VM\n\n- clone an existing GitLab project of yours in the remote VM\n\n- open your remotely cloned project from the remotely installed VS Code\n\n\nAs a result, you can basically use your laptop as a thin client that\naccesses a remote server, where all the work takes place.\n\n\n> The automation to get all these parts in place was done by GitLab. Sign up\nfor a [free GitLab Ultimate\ntrial](https://about.gitlab.com/free-trial/) to get started today!\n","engineering",[23,24,25],"cloud native","tutorial","open source",{"slug":27,"featured":28,"template":29},"tutorial-install-vs-code-on-a-cloud-provider-vm-and-set-up-remote-access",true,"BlogPost","content:en-us:blog:tutorial-install-vs-code-on-a-cloud-provider-vm-and-set-up-remote-access.yml","yaml","Tutorial Install Vs Code On A Cloud Provider Vm And Set Up Remote Access","content","en-us/blog/tutorial-install-vs-code-on-a-cloud-provider-vm-and-set-up-remote-access.yml","en-us/blog/tutorial-install-vs-code-on-a-cloud-provider-vm-and-set-up-remote-access","yml",{"_path":38,"_dir":39,"_draft":6,"_partial":6,"_locale":7,"data":40,"_id":451,"_type":31,"title":452,"_source":33,"_file":453,"_stem":454,"_extension":36},"/shared/en-us/main-navigation","en-us",{"logo":41,"freeTrial":46,"sales":51,"login":56,"items":61,"search":392,"minimal":423,"duo":442},{"config":42},{"href":43,"dataGaName":44,"dataGaLocation":45},"/","gitlab logo","header",{"text":47,"config":48},"Get free trial",{"href":49,"dataGaName":50,"dataGaLocation":45},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":52,"config":53},"Talk to sales",{"href":54,"dataGaName":55,"dataGaLocation":45},"/sales/","sales",{"text":57,"config":58},"Sign in",{"href":59,"dataGaName":60,"dataGaLocation":45},"https://gitlab.com/users/sign_in/","sign in",[62,106,203,208,313,373],{"text":63,"config":64,"cards":66,"footer":89},"Platform",{"dataNavLevelOne":65},"platform",[67,73,81],{"title":63,"description":68,"link":69},"The most comprehensive AI-powered DevSecOps Platform",{"text":70,"config":71},"Explore our Platform",{"href":72,"dataGaName":65,"dataGaLocation":45},"/platform/",{"title":74,"description":75,"link":76},"GitLab Duo (AI)","Build software faster with AI at every stage of development",{"text":77,"config":78},"Meet GitLab Duo",{"href":79,"dataGaName":80,"dataGaLocation":45},"/gitlab-duo/","gitlab duo ai",{"title":82,"description":83,"link":84},"Why GitLab","10 reasons why Enterprises choose GitLab",{"text":85,"config":86},"Learn more",{"href":87,"dataGaName":88,"dataGaLocation":45},"/why-gitlab/","why gitlab",{"title":90,"items":91},"Get started with",[92,97,102],{"text":93,"config":94},"Platform Engineering",{"href":95,"dataGaName":96,"dataGaLocation":45},"/solutions/platform-engineering/","platform engineering",{"text":98,"config":99},"Developer Experience",{"href":100,"dataGaName":101,"dataGaLocation":45},"/developer-experience/","Developer experience",{"text":103,"config":104},"MLOps",{"href":105,"dataGaName":103,"dataGaLocation":45},"/topics/devops/the-role-of-ai-in-devops/",{"text":107,"left":28,"config":108,"link":110,"lists":114,"footer":185},"Product",{"dataNavLevelOne":109},"solutions",{"text":111,"config":112},"View all Solutions",{"href":113,"dataGaName":109,"dataGaLocation":45},"/solutions/",[115,140,164],{"title":116,"description":117,"link":118,"items":123},"Automation","CI/CD and automation to accelerate deployment",{"config":119},{"icon":120,"href":121,"dataGaName":122,"dataGaLocation":45},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[124,128,132,136],{"text":125,"config":126},"CI/CD",{"href":127,"dataGaLocation":45,"dataGaName":125},"/solutions/continuous-integration/",{"text":129,"config":130},"AI-Assisted Development",{"href":79,"dataGaLocation":45,"dataGaName":131},"AI assisted development",{"text":133,"config":134},"Source Code Management",{"href":135,"dataGaLocation":45,"dataGaName":133},"/solutions/source-code-management/",{"text":137,"config":138},"Automated Software Delivery",{"href":121,"dataGaLocation":45,"dataGaName":139},"Automated software delivery",{"title":141,"description":142,"link":143,"items":148},"Security","Deliver code faster without compromising security",{"config":144},{"href":145,"dataGaName":146,"dataGaLocation":45,"icon":147},"/solutions/security-compliance/","security and compliance","ShieldCheckLight",[149,154,159],{"text":150,"config":151},"Application Security Testing",{"href":152,"dataGaName":153,"dataGaLocation":45},"/solutions/application-security-testing/","Application security testing",{"text":155,"config":156},"Software Supply Chain Security",{"href":157,"dataGaLocation":45,"dataGaName":158},"/solutions/supply-chain/","Software supply chain security",{"text":160,"config":161},"Software Compliance",{"href":162,"dataGaName":163,"dataGaLocation":45},"/solutions/software-compliance/","software compliance",{"title":165,"link":166,"items":171},"Measurement",{"config":167},{"icon":168,"href":169,"dataGaName":170,"dataGaLocation":45},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[172,176,180],{"text":173,"config":174},"Visibility & Measurement",{"href":169,"dataGaLocation":45,"dataGaName":175},"Visibility and Measurement",{"text":177,"config":178},"Value Stream Management",{"href":179,"dataGaLocation":45,"dataGaName":177},"/solutions/value-stream-management/",{"text":181,"config":182},"Analytics & Insights",{"href":183,"dataGaLocation":45,"dataGaName":184},"/solutions/analytics-and-insights/","Analytics and insights",{"title":186,"items":187},"GitLab for",[188,193,198],{"text":189,"config":190},"Enterprise",{"href":191,"dataGaLocation":45,"dataGaName":192},"/enterprise/","enterprise",{"text":194,"config":195},"Small Business",{"href":196,"dataGaLocation":45,"dataGaName":197},"/small-business/","small business",{"text":199,"config":200},"Public Sector",{"href":201,"dataGaLocation":45,"dataGaName":202},"/solutions/public-sector/","public sector",{"text":204,"config":205},"Pricing",{"href":206,"dataGaName":207,"dataGaLocation":45,"dataNavLevelOne":207},"/pricing/","pricing",{"text":209,"config":210,"link":212,"lists":216,"feature":300},"Resources",{"dataNavLevelOne":211},"resources",{"text":213,"config":214},"View all resources",{"href":215,"dataGaName":211,"dataGaLocation":45},"/resources/",[217,250,272],{"title":218,"items":219},"Getting started",[220,225,230,235,240,245],{"text":221,"config":222},"Install",{"href":223,"dataGaName":224,"dataGaLocation":45},"/install/","install",{"text":226,"config":227},"Quick start guides",{"href":228,"dataGaName":229,"dataGaLocation":45},"/get-started/","quick setup checklists",{"text":231,"config":232},"Learn",{"href":233,"dataGaLocation":45,"dataGaName":234},"https://university.gitlab.com/","learn",{"text":236,"config":237},"Product documentation",{"href":238,"dataGaName":239,"dataGaLocation":45},"https://docs.gitlab.com/","product documentation",{"text":241,"config":242},"Best practice videos",{"href":243,"dataGaName":244,"dataGaLocation":45},"/getting-started-videos/","best practice videos",{"text":246,"config":247},"Integrations",{"href":248,"dataGaName":249,"dataGaLocation":45},"/integrations/","integrations",{"title":251,"items":252},"Discover",[253,258,262,267],{"text":254,"config":255},"Customer success stories",{"href":256,"dataGaName":257,"dataGaLocation":45},"/customers/","customer success stories",{"text":259,"config":260},"Blog",{"href":261,"dataGaName":5,"dataGaLocation":45},"/blog/",{"text":263,"config":264},"Remote",{"href":265,"dataGaName":266,"dataGaLocation":45},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"text":268,"config":269},"TeamOps",{"href":270,"dataGaName":271,"dataGaLocation":45},"/teamops/","teamops",{"title":273,"items":274},"Connect",[275,280,285,290,295],{"text":276,"config":277},"GitLab Services",{"href":278,"dataGaName":279,"dataGaLocation":45},"/services/","services",{"text":281,"config":282},"Community",{"href":283,"dataGaName":284,"dataGaLocation":45},"/community/","community",{"text":286,"config":287},"Forum",{"href":288,"dataGaName":289,"dataGaLocation":45},"https://forum.gitlab.com/","forum",{"text":291,"config":292},"Events",{"href":293,"dataGaName":294,"dataGaLocation":45},"/events/","events",{"text":296,"config":297},"Partners",{"href":298,"dataGaName":299,"dataGaLocation":45},"/partners/","partners",{"backgroundColor":301,"textColor":302,"text":303,"image":304,"link":308},"#2f2a6b","#fff","Insights for the future of software development",{"altText":305,"config":306},"the source promo card",{"src":307},"/images/navigation/the-source-promo-card.svg",{"text":309,"config":310},"Read the latest",{"href":311,"dataGaName":312,"dataGaLocation":45},"/the-source/","the source",{"text":314,"config":315,"lists":317},"Company",{"dataNavLevelOne":316},"company",[318],{"items":319},[320,325,331,333,338,343,348,353,358,363,368],{"text":321,"config":322},"About",{"href":323,"dataGaName":324,"dataGaLocation":45},"/company/","about",{"text":326,"config":327,"footerGa":330},"Jobs",{"href":328,"dataGaName":329,"dataGaLocation":45},"/jobs/","jobs",{"dataGaName":329},{"text":291,"config":332},{"href":293,"dataGaName":294,"dataGaLocation":45},{"text":334,"config":335},"Leadership",{"href":336,"dataGaName":337,"dataGaLocation":45},"/company/team/e-group/","leadership",{"text":339,"config":340},"Team",{"href":341,"dataGaName":342,"dataGaLocation":45},"/company/team/","team",{"text":344,"config":345},"Handbook",{"href":346,"dataGaName":347,"dataGaLocation":45},"https://handbook.gitlab.com/","handbook",{"text":349,"config":350},"Investor relations",{"href":351,"dataGaName":352,"dataGaLocation":45},"https://ir.gitlab.com/","investor relations",{"text":354,"config":355},"Trust Center",{"href":356,"dataGaName":357,"dataGaLocation":45},"/security/","trust center",{"text":359,"config":360},"AI Transparency Center",{"href":361,"dataGaName":362,"dataGaLocation":45},"/ai-transparency-center/","ai transparency center",{"text":364,"config":365},"Newsletter",{"href":366,"dataGaName":367,"dataGaLocation":45},"/company/contact/","newsletter",{"text":369,"config":370},"Press",{"href":371,"dataGaName":372,"dataGaLocation":45},"/press/","press",{"text":374,"config":375,"lists":376},"Contact us",{"dataNavLevelOne":316},[377],{"items":378},[379,382,387],{"text":52,"config":380},{"href":54,"dataGaName":381,"dataGaLocation":45},"talk to sales",{"text":383,"config":384},"Get help",{"href":385,"dataGaName":386,"dataGaLocation":45},"/support/","get help",{"text":388,"config":389},"Customer portal",{"href":390,"dataGaName":391,"dataGaLocation":45},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":393,"login":394,"suggestions":401},"Close",{"text":395,"link":396},"To search repositories and projects, login to",{"text":397,"config":398},"gitlab.com",{"href":59,"dataGaName":399,"dataGaLocation":400},"search login","search",{"text":402,"default":403},"Suggestions",[404,406,410,412,416,420],{"text":74,"config":405},{"href":79,"dataGaName":74,"dataGaLocation":400},{"text":407,"config":408},"Code Suggestions (AI)",{"href":409,"dataGaName":407,"dataGaLocation":400},"/solutions/code-suggestions/",{"text":125,"config":411},{"href":127,"dataGaName":125,"dataGaLocation":400},{"text":413,"config":414},"GitLab on AWS",{"href":415,"dataGaName":413,"dataGaLocation":400},"/partners/technology-partners/aws/",{"text":417,"config":418},"GitLab on Google Cloud",{"href":419,"dataGaName":417,"dataGaLocation":400},"/partners/technology-partners/google-cloud-platform/",{"text":421,"config":422},"Why GitLab?",{"href":87,"dataGaName":421,"dataGaLocation":400},{"freeTrial":424,"mobileIcon":429,"desktopIcon":434,"secondaryButton":437},{"text":425,"config":426},"Start free trial",{"href":427,"dataGaName":50,"dataGaLocation":428},"https://gitlab.com/-/trials/new/","nav",{"altText":430,"config":431},"Gitlab Icon",{"src":432,"dataGaName":433,"dataGaLocation":428},"/images/brand/gitlab-logo-tanuki.svg","gitlab icon",{"altText":430,"config":435},{"src":436,"dataGaName":433,"dataGaLocation":428},"/images/brand/gitlab-logo-type.svg",{"text":438,"config":439},"Get Started",{"href":440,"dataGaName":441,"dataGaLocation":428},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/compare/gitlab-vs-github/","get started",{"freeTrial":443,"mobileIcon":447,"desktopIcon":449},{"text":444,"config":445},"Learn more about GitLab Duo",{"href":79,"dataGaName":446,"dataGaLocation":428},"gitlab duo",{"altText":430,"config":448},{"src":432,"dataGaName":433,"dataGaLocation":428},{"altText":430,"config":450},{"src":436,"dataGaName":433,"dataGaLocation":428},"content:shared:en-us:main-navigation.yml","Main Navigation","shared/en-us/main-navigation.yml","shared/en-us/main-navigation",{"_path":456,"_dir":39,"_draft":6,"_partial":6,"_locale":7,"title":457,"button":458,"image":462,"config":466,"_id":468,"_type":31,"_source":33,"_file":469,"_stem":470,"_extension":36},"/shared/en-us/banner","is now in public beta!",{"text":85,"config":459},{"href":460,"dataGaName":461,"dataGaLocation":45},"/gitlab-duo/agent-platform/","duo banner",{"altText":463,"config":464},"GitLab Duo Agent Platform",{"src":465},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1753720689/somrf9zaunk0xlt7ne4x.svg",{"layout":467},"release","content:shared:en-us:banner.yml","shared/en-us/banner.yml","shared/en-us/banner",{"_path":472,"_dir":39,"_draft":6,"_partial":6,"_locale":7,"data":473,"_id":677,"_type":31,"title":678,"_source":33,"_file":679,"_stem":680,"_extension":36},"/shared/en-us/main-footer",{"text":474,"source":475,"edit":481,"contribute":486,"config":491,"items":496,"minimal":669},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":476,"config":477},"View page source",{"href":478,"dataGaName":479,"dataGaLocation":480},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":482,"config":483},"Edit this page",{"href":484,"dataGaName":485,"dataGaLocation":480},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":487,"config":488},"Please contribute",{"href":489,"dataGaName":490,"dataGaLocation":480},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":492,"facebook":493,"youtube":494,"linkedin":495},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[497,520,576,605,639],{"title":63,"links":498,"subMenu":503},[499],{"text":500,"config":501},"DevSecOps platform",{"href":72,"dataGaName":502,"dataGaLocation":480},"devsecops platform",[504],{"title":204,"links":505},[506,510,515],{"text":507,"config":508},"View plans",{"href":206,"dataGaName":509,"dataGaLocation":480},"view plans",{"text":511,"config":512},"Why Premium?",{"href":513,"dataGaName":514,"dataGaLocation":480},"/pricing/premium/","why premium",{"text":516,"config":517},"Why Ultimate?",{"href":518,"dataGaName":519,"dataGaLocation":480},"/pricing/ultimate/","why ultimate",{"title":521,"links":522},"Solutions",[523,528,530,532,537,542,546,549,553,558,560,563,566,571],{"text":524,"config":525},"Digital transformation",{"href":526,"dataGaName":527,"dataGaLocation":480},"/topics/digital-transformation/","digital transformation",{"text":150,"config":529},{"href":152,"dataGaName":150,"dataGaLocation":480},{"text":139,"config":531},{"href":121,"dataGaName":122,"dataGaLocation":480},{"text":533,"config":534},"Agile development",{"href":535,"dataGaName":536,"dataGaLocation":480},"/solutions/agile-delivery/","agile delivery",{"text":538,"config":539},"Cloud transformation",{"href":540,"dataGaName":541,"dataGaLocation":480},"/topics/cloud-native/","cloud transformation",{"text":543,"config":544},"SCM",{"href":135,"dataGaName":545,"dataGaLocation":480},"source code management",{"text":125,"config":547},{"href":127,"dataGaName":548,"dataGaLocation":480},"continuous integration & delivery",{"text":550,"config":551},"Value stream management",{"href":179,"dataGaName":552,"dataGaLocation":480},"value stream management",{"text":554,"config":555},"GitOps",{"href":556,"dataGaName":557,"dataGaLocation":480},"/solutions/gitops/","gitops",{"text":189,"config":559},{"href":191,"dataGaName":192,"dataGaLocation":480},{"text":561,"config":562},"Small business",{"href":196,"dataGaName":197,"dataGaLocation":480},{"text":564,"config":565},"Public sector",{"href":201,"dataGaName":202,"dataGaLocation":480},{"text":567,"config":568},"Education",{"href":569,"dataGaName":570,"dataGaLocation":480},"/solutions/education/","education",{"text":572,"config":573},"Financial services",{"href":574,"dataGaName":575,"dataGaLocation":480},"/solutions/finance/","financial services",{"title":209,"links":577},[578,580,582,584,587,589,591,593,595,597,599,601,603],{"text":221,"config":579},{"href":223,"dataGaName":224,"dataGaLocation":480},{"text":226,"config":581},{"href":228,"dataGaName":229,"dataGaLocation":480},{"text":231,"config":583},{"href":233,"dataGaName":234,"dataGaLocation":480},{"text":236,"config":585},{"href":238,"dataGaName":586,"dataGaLocation":480},"docs",{"text":259,"config":588},{"href":261,"dataGaName":5,"dataGaLocation":480},{"text":254,"config":590},{"href":256,"dataGaName":257,"dataGaLocation":480},{"text":263,"config":592},{"href":265,"dataGaName":266,"dataGaLocation":480},{"text":276,"config":594},{"href":278,"dataGaName":279,"dataGaLocation":480},{"text":268,"config":596},{"href":270,"dataGaName":271,"dataGaLocation":480},{"text":281,"config":598},{"href":283,"dataGaName":284,"dataGaLocation":480},{"text":286,"config":600},{"href":288,"dataGaName":289,"dataGaLocation":480},{"text":291,"config":602},{"href":293,"dataGaName":294,"dataGaLocation":480},{"text":296,"config":604},{"href":298,"dataGaName":299,"dataGaLocation":480},{"title":314,"links":606},[607,609,611,613,615,617,619,623,628,630,632,634],{"text":321,"config":608},{"href":323,"dataGaName":316,"dataGaLocation":480},{"text":326,"config":610},{"href":328,"dataGaName":329,"dataGaLocation":480},{"text":334,"config":612},{"href":336,"dataGaName":337,"dataGaLocation":480},{"text":339,"config":614},{"href":341,"dataGaName":342,"dataGaLocation":480},{"text":344,"config":616},{"href":346,"dataGaName":347,"dataGaLocation":480},{"text":349,"config":618},{"href":351,"dataGaName":352,"dataGaLocation":480},{"text":620,"config":621},"Sustainability",{"href":622,"dataGaName":620,"dataGaLocation":480},"/sustainability/",{"text":624,"config":625},"Diversity, inclusion and belonging (DIB)",{"href":626,"dataGaName":627,"dataGaLocation":480},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":354,"config":629},{"href":356,"dataGaName":357,"dataGaLocation":480},{"text":364,"config":631},{"href":366,"dataGaName":367,"dataGaLocation":480},{"text":369,"config":633},{"href":371,"dataGaName":372,"dataGaLocation":480},{"text":635,"config":636},"Modern Slavery Transparency Statement",{"href":637,"dataGaName":638,"dataGaLocation":480},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"title":640,"links":641},"Contact Us",[642,645,647,649,654,659,664],{"text":643,"config":644},"Contact an expert",{"href":54,"dataGaName":55,"dataGaLocation":480},{"text":383,"config":646},{"href":385,"dataGaName":386,"dataGaLocation":480},{"text":388,"config":648},{"href":390,"dataGaName":391,"dataGaLocation":480},{"text":650,"config":651},"Status",{"href":652,"dataGaName":653,"dataGaLocation":480},"https://status.gitlab.com/","status",{"text":655,"config":656},"Terms of use",{"href":657,"dataGaName":658,"dataGaLocation":480},"/terms/","terms of use",{"text":660,"config":661},"Privacy statement",{"href":662,"dataGaName":663,"dataGaLocation":480},"/privacy/","privacy statement",{"text":665,"config":666},"Cookie preferences",{"dataGaName":667,"dataGaLocation":480,"id":668,"isOneTrustButton":28},"cookie preferences","ot-sdk-btn",{"items":670},[671,673,675],{"text":655,"config":672},{"href":657,"dataGaName":658,"dataGaLocation":480},{"text":660,"config":674},{"href":662,"dataGaName":663,"dataGaLocation":480},{"text":665,"config":676},{"dataGaName":667,"dataGaLocation":480,"id":668,"isOneTrustButton":28},"content:shared:en-us:main-footer.yml","Main Footer","shared/en-us/main-footer.yml","shared/en-us/main-footer",[682],{"_path":683,"_dir":684,"_draft":6,"_partial":6,"_locale":7,"content":685,"config":689,"_id":691,"_type":31,"title":18,"_source":33,"_file":692,"_stem":693,"_extension":36},"/en-us/blog/authors/cesar-saavedra","authors",{"name":18,"config":686},{"headshot":687,"ctfId":688},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749659600/Blog/Author%20Headshots/csaavedra1-headshot.jpg","csaavedra1",{"template":690},"BlogAuthor","content:en-us:blog:authors:cesar-saavedra.yml","en-us/blog/authors/cesar-saavedra.yml","en-us/blog/authors/cesar-saavedra",{"_path":695,"_dir":39,"_draft":6,"_partial":6,"_locale":7,"header":696,"eyebrow":697,"blurb":698,"button":699,"secondaryButton":703,"_id":705,"_type":31,"title":706,"_source":33,"_file":707,"_stem":708,"_extension":36},"/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":47,"config":700},{"href":701,"dataGaName":50,"dataGaLocation":702},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":52,"config":704},{"href":54,"dataGaName":55,"dataGaLocation":702},"content:shared:en-us:next-steps.yml","Next Steps","shared/en-us/next-steps.yml","shared/en-us/next-steps",1755803041649]