[{"data":1,"prerenderedAt":2183},["ShallowReactive",2],{"/blog/build-and-run-containers-in-remote-development-workspaces":3,"navigation-en-us":1405,"banner-en-us":1832,"footer-en-us":1842,"blog-post-authors-en-us-Vishal Tak":2086,"blog-related-posts-en-us-build-and-run-containers-in-remote-development-workspaces":2101,"blog-promotions-en-us":2120,"next-steps-en-us":2173},{"id":4,"title":5,"authors":6,"body":8,"category":1384,"date":1385,"description":1386,"extension":1387,"externalUrl":1388,"faq":1388,"featured":178,"heroImage":1389,"meta":1390,"navigation":178,"path":1391,"seo":1392,"slug":1397,"stem":1398,"tags":1399,"template":1403,"updatedDate":1388,"__hash__":1404},"blogPosts/en-us/blog/build-and-run-containers-in-remote-development-workspaces.md","Build and run containers in Remote Development workspaces",[7],"Vishal Tak",{"type":9,"value":10,"toc":1373},"minimark",[11,15,18,71,75,95,140,157,295,304,331,340,424,427,541,549,558,583,586,594,606,625,641,649,652,696,699,865,868,877,880,888,891,899,1011,1014,1028,1242,1245,1269,1272,1275,1298,1311,1324,1327,1335,1339,1369],[12,13,14],"p",{},"Development environments often require the ability to build and run containers as part of their local development. Securely running containers within containers can be challenging. This article will provide a step-by-step guide to securely build and run containers in a workspace.",[12,16,17],{},"You will learn how to:",[19,20,21,29,35,41,47,53,59,65],"ul",{},[22,23,24],"li",{},[25,26,28],"a",{"href":27},"#create-a-kubernetes-cluster-on-aws-eks","Create a Kubernetes cluster on AWS EKS",[22,30,31],{},[25,32,34],{"href":33},"#configure-sysbox","Configure Sysbox",[22,36,37],{},[25,38,40],{"href":39},"#configure-gitlab-agent-for-kubernetes-and-gitlab-workspaces-proxy","Configure GitLab agent for Kubernetes and GitLab Workspaces Proxy",[22,42,43],{},[25,44,46],{"href":45},"#configure-sudo-access-for-a-workspace-with-sysbox","Configure sudo access for a workspace with Sysbox",[22,48,49],{},[25,50,52],{"href":51},"#configure-ingress-controller","Configure Ingress Controller",[22,54,55],{},[25,56,58],{"href":57},"#build-containers-inside-a-workspace","Build containers inside a workspace",[22,60,61],{},[25,62,64],{"href":63},"#run-containers-inside-a-workspace","Run containers inside a workspace",[22,66,67],{},[25,68,70],{"href":69},"#get-started-today","Get started today",[72,73,28],"h2",{"id":74},"create-a-kubernetes-cluster-on-aws-eks",[12,76,77,78,83,84,89,90,94],{},"Install the ",[25,79,82],{"href":80,"rel":81},"https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html",[],"AWS CLI"," on your local machine. Next, configure a ",[25,85,88],{"href":86,"rel":87},"https://docs.aws.amazon.com/cli/latest/reference/configure/",[],"named profile"," and export it to ensure all the following ",[91,92,93],"code",{},"aws"," commands use the set credentials.",[96,97,102],"pre",{"className":98,"code":99,"language":100,"meta":101,"style":101},"language-shell shiki shiki-themes github-light","aws configure --profile gitlab-workspaces-container-demo\nexport AWS_PROFILE=gitlab-workspaces-container-demo\n","shell","",[91,103,104,123],{"__ignoreMap":101},[105,106,109,112,116,120],"span",{"class":107,"line":108},"line",1,[105,110,93],{"class":111},"s7eDp",[105,113,115],{"class":114},"sYBdl"," configure",[105,117,119],{"class":118},"sYu0t"," --profile",[105,121,122],{"class":114}," gitlab-workspaces-container-demo\n",[105,124,126,130,134,137],{"class":107,"line":125},2,[105,127,129],{"class":128},"sD7c4","export",[105,131,133],{"class":132},"sgsFI"," AWS_PROFILE",[105,135,136],{"class":128},"=",[105,138,139],{"class":132},"gitlab-workspaces-container-demo\n",[12,141,142,143,148,149,152,153,156],{},"Install ",[25,144,147],{"href":145,"rel":146},"https://eksctl.io/installation/",[],"eksctl",", a CLI to interact with AWS EKS. Let’s now create a Kubernetes 1.31 cluster on AWS EKS with 1 node of Ubuntu 22.04 of ",[91,150,151],{},"c5.2xlarge"," instance type. The nodes can autoscale from 0-20 nodes and each node will have a label ",[91,154,155],{},"sysbox-install: yes"," . This will be explained later in the article.",[96,158,160],{"className":98,"code":159,"language":100,"meta":101,"style":101},"export CLUSTER_NAME=\"gitlab-workspaces-container-demo-eks-sysbox\"\n\neksctl create cluster \\\n  --name \"${CLUSTER_NAME}\" \\\n  --version 1.31 \\\n  --node-ami-family=Ubuntu2204 \\\n  --nodes=1 \\\n  --nodes-min=0 \\\n  --nodes-max=20 \\\n  --instance-types=c5.2xlarge \\\n  --node-labels \"sysbox-install=yes\" \\\n  --asg-access \\\n  --external-dns-access \\\n  --full-ecr-access\n\n",[91,161,162,174,180,194,211,222,230,238,246,254,262,273,281,289],{"__ignoreMap":101},[105,163,164,166,169,171],{"class":107,"line":108},[105,165,129],{"class":128},[105,167,168],{"class":132}," CLUSTER_NAME",[105,170,136],{"class":128},[105,172,173],{"class":114},"\"gitlab-workspaces-container-demo-eks-sysbox\"\n",[105,175,176],{"class":107,"line":125},[105,177,179],{"emptyLinePlaceholder":178},true,"\n",[105,181,183,185,188,191],{"class":107,"line":182},3,[105,184,147],{"class":111},[105,186,187],{"class":114}," create",[105,189,190],{"class":114}," cluster",[105,192,193],{"class":118}," \\\n",[105,195,197,200,203,206,209],{"class":107,"line":196},4,[105,198,199],{"class":118},"  --name",[105,201,202],{"class":114}," \"${",[105,204,205],{"class":132},"CLUSTER_NAME",[105,207,208],{"class":114},"}\"",[105,210,193],{"class":118},[105,212,214,217,220],{"class":107,"line":213},5,[105,215,216],{"class":118},"  --version",[105,218,219],{"class":118}," 1.31",[105,221,193],{"class":118},[105,223,225,228],{"class":107,"line":224},6,[105,226,227],{"class":118},"  --node-ami-family=Ubuntu2204",[105,229,193],{"class":118},[105,231,233,236],{"class":107,"line":232},7,[105,234,235],{"class":118},"  --nodes=1",[105,237,193],{"class":118},[105,239,241,244],{"class":107,"line":240},8,[105,242,243],{"class":118},"  --nodes-min=0",[105,245,193],{"class":118},[105,247,249,252],{"class":107,"line":248},9,[105,250,251],{"class":118},"  --nodes-max=20",[105,253,193],{"class":118},[105,255,257,260],{"class":107,"line":256},10,[105,258,259],{"class":118},"  --instance-types=c5.2xlarge",[105,261,193],{"class":118},[105,263,265,268,271],{"class":107,"line":264},11,[105,266,267],{"class":118},"  --node-labels",[105,269,270],{"class":114}," \"sysbox-install=yes\"",[105,272,193],{"class":118},[105,274,276,279],{"class":107,"line":275},12,[105,277,278],{"class":118},"  --asg-access",[105,280,193],{"class":118},[105,282,284,287],{"class":107,"line":283},13,[105,285,286],{"class":118},"  --external-dns-access",[105,288,193],{"class":118},[105,290,292],{"class":107,"line":291},14,[105,293,294],{"class":118},"  --full-ecr-access\n",[12,296,297,298,303],{},"Create an ",[25,299,302],{"href":300,"rel":301},"https://docs.aws.amazon.com/eks/latest/userguide/associate-service-account-role.html",[],"IAM OIDC"," provider for your cluster.",[96,305,307],{"className":98,"code":306,"language":100,"meta":101,"style":101},"eksctl utils associate-iam-oidc-provider --cluster \"${CLUSTER_NAME}\" --approve\n",[91,308,309],{"__ignoreMap":101},[105,310,311,313,316,319,322,324,326,328],{"class":107,"line":108},[105,312,147],{"class":111},[105,314,315],{"class":114}," utils",[105,317,318],{"class":114}," associate-iam-oidc-provider",[105,320,321],{"class":118}," --cluster",[105,323,202],{"class":114},[105,325,205],{"class":132},[105,327,208],{"class":114},[105,329,330],{"class":118}," --approve\n",[12,332,333,334,339],{},"Create IAM role for ",[25,335,338],{"href":336,"rel":337},"https://docs.aws.amazon.com/eks/latest/userguide/ebs-csi.html",[],"EBS add-on"," for EKS.",[96,341,343],{"className":98,"code":342,"language":100,"meta":101,"style":101},"eksctl create iamserviceaccount \\\n  --name ebs-csi-controller-sa \\\n  --namespace kube-system \\\n  --cluster \"${CLUSTER_NAME}\" \\\n  --role-name \"AmazonEKS_EBS_CSI_DriverRole_${CLUSTER_NAME}\" \\\n  --role-only \\\n  --attach-policy-arn arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy \\\n  --approve\n\n",[91,344,345,356,365,375,388,402,409,419],{"__ignoreMap":101},[105,346,347,349,351,354],{"class":107,"line":108},[105,348,147],{"class":111},[105,350,187],{"class":114},[105,352,353],{"class":114}," iamserviceaccount",[105,355,193],{"class":118},[105,357,358,360,363],{"class":107,"line":125},[105,359,199],{"class":118},[105,361,362],{"class":114}," ebs-csi-controller-sa",[105,364,193],{"class":118},[105,366,367,370,373],{"class":107,"line":182},[105,368,369],{"class":118},"  --namespace",[105,371,372],{"class":114}," kube-system",[105,374,193],{"class":118},[105,376,377,380,382,384,386],{"class":107,"line":196},[105,378,379],{"class":118},"  --cluster",[105,381,202],{"class":114},[105,383,205],{"class":132},[105,385,208],{"class":114},[105,387,193],{"class":118},[105,389,390,393,396,398,400],{"class":107,"line":213},[105,391,392],{"class":118},"  --role-name",[105,394,395],{"class":114}," \"AmazonEKS_EBS_CSI_DriverRole_${",[105,397,205],{"class":132},[105,399,208],{"class":114},[105,401,193],{"class":118},[105,403,404,407],{"class":107,"line":224},[105,405,406],{"class":118},"  --role-only",[105,408,193],{"class":118},[105,410,411,414,417],{"class":107,"line":232},[105,412,413],{"class":118},"  --attach-policy-arn",[105,415,416],{"class":114}," arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy",[105,418,193],{"class":118},[105,420,421],{"class":107,"line":240},[105,422,423],{"class":118},"  --approve\n",[12,425,426],{},"Create Amazon EBS CSI driver add-on for Amazon EKS cluster.",[96,428,430],{"className":98,"code":429,"language":100,"meta":101,"style":101},"eksctl utils describe-addon-versions --kubernetes-version 1.31 | grep aws-ebs-csi-driver\n\nexport AWS_ACCOUNT_ID=\"UPDATE_ME\"\n\neksctl create addon \\\n  --cluster \"${CLUSTER_NAME}\" \\\n  --name aws-ebs-csi-driver \\\n  --version latest \\\n  --service-account-role-arn \"arn:aws:iam::${AWS_ACCOUNT_ID}:role/AmazonEKS_EBS_CSI_DriverRole_${CLUSTER_NAME}\" \\\n  --force\n\n",[91,431,432,455,459,471,475,486,498,507,516,536],{"__ignoreMap":101},[105,433,434,436,438,441,444,446,449,452],{"class":107,"line":108},[105,435,147],{"class":111},[105,437,315],{"class":114},[105,439,440],{"class":114}," describe-addon-versions",[105,442,443],{"class":118}," --kubernetes-version",[105,445,219],{"class":118},[105,447,448],{"class":128}," |",[105,450,451],{"class":111}," grep",[105,453,454],{"class":114}," aws-ebs-csi-driver\n",[105,456,457],{"class":107,"line":125},[105,458,179],{"emptyLinePlaceholder":178},[105,460,461,463,466,468],{"class":107,"line":182},[105,462,129],{"class":128},[105,464,465],{"class":132}," AWS_ACCOUNT_ID",[105,467,136],{"class":128},[105,469,470],{"class":114},"\"UPDATE_ME\"\n",[105,472,473],{"class":107,"line":196},[105,474,179],{"emptyLinePlaceholder":178},[105,476,477,479,481,484],{"class":107,"line":213},[105,478,147],{"class":111},[105,480,187],{"class":114},[105,482,483],{"class":114}," addon",[105,485,193],{"class":118},[105,487,488,490,492,494,496],{"class":107,"line":224},[105,489,379],{"class":118},[105,491,202],{"class":114},[105,493,205],{"class":132},[105,495,208],{"class":114},[105,497,193],{"class":118},[105,499,500,502,505],{"class":107,"line":232},[105,501,199],{"class":118},[105,503,504],{"class":114}," aws-ebs-csi-driver",[105,506,193],{"class":118},[105,508,509,511,514],{"class":107,"line":240},[105,510,216],{"class":118},[105,512,513],{"class":114}," latest",[105,515,193],{"class":118},[105,517,518,521,524,527,530,532,534],{"class":107,"line":248},[105,519,520],{"class":118},"  --service-account-role-arn",[105,522,523],{"class":114}," \"arn:aws:iam::${",[105,525,526],{"class":132},"AWS_ACCOUNT_ID",[105,528,529],{"class":114},"}:role/AmazonEKS_EBS_CSI_DriverRole_${",[105,531,205],{"class":132},[105,533,208],{"class":114},[105,535,193],{"class":118},[105,537,538],{"class":107,"line":256},[105,539,540],{"class":118},"  --force\n",[12,542,142,543,548],{},[25,544,547],{"href":545,"rel":546},"https://kubernetes.io/docs/reference/kubectl/",[],"kubectl",", a command line tool for communicating with a Kubernetes cluster's control plane, using the Kubernetes API.",[12,550,551,552,557],{},"Let’s get the ",[25,553,556],{"href":554,"rel":555},"https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/",[],"kubeconfig"," of the created cluster.",[96,559,561],{"className":98,"code":560,"language":100,"meta":101,"style":101},"aws eks update-kubeconfig --name \"${CLUSTER_NAME}\"\n",[91,562,563],{"__ignoreMap":101},[105,564,565,567,570,573,576,578,580],{"class":107,"line":108},[105,566,93],{"class":111},[105,568,569],{"class":114}," eks",[105,571,572],{"class":114}," update-kubeconfig",[105,574,575],{"class":118}," --name",[105,577,202],{"class":114},[105,579,205],{"class":132},[105,581,582],{"class":114},"}\"\n",[72,584,34],{"id":585},"configure-sysbox",[12,587,588,593],{},[25,589,592],{"href":590,"rel":591},"https://github.com/nestybox/sysbox",[],"Sysbox"," is a container runtime that improves container isolation and enables containers to run the same workloads as virtual machines.",[12,595,596,601,602,605],{},[25,597,600],{"href":598,"rel":599},"https://github.com/nestybox/sysbox#installation",[],"Install"," Sysbox on the Kubernetes cluster using the ",[91,603,604],{},"sysbox-deploy-k8s daemonset",".",[96,607,609],{"className":98,"code":608,"language":100,"meta":101,"style":101},"curl https://raw.githubusercontent.com/nestybox/sysbox/refs/tags/v0.6.6/sysbox-k8s-manifests/sysbox-install.yaml -o sysbox-install.yaml\n",[91,610,611],{"__ignoreMap":101},[105,612,613,616,619,622],{"class":107,"line":108},[105,614,615],{"class":111},"curl",[105,617,618],{"class":114}," https://raw.githubusercontent.com/nestybox/sysbox/refs/tags/v0.6.6/sysbox-k8s-manifests/sysbox-install.yaml",[105,620,621],{"class":118}," -o",[105,623,624],{"class":114}," sysbox-install.yaml\n",[12,626,627,628,630,631,634,635,640],{},"Because of how Sysbox releases itself, it first created a git tag, which runs a pipeline to build assets after which the YAML files for the ",[91,629,604],{}," are updated. Thus, we need to update the DaemonSet's ",[91,632,633],{},"spec.template.soec.containers[0].image"," to ",[25,636,639],{"href":637,"rel":638},"https://github.com/nestybox/sysbox/blob/46ba726e8e894aa22e20465a32d22dfa2863ec12/sysbox-k8s-manifests/sysbox-install.yaml#L66",[],"registry.nestybox.com/nestybox/sysbox-deploy-k8s:v0.6.6-0"," .",[96,642,647],{"className":643,"code":645,"language":646,"meta":101},[644],"language-text","new_image_value=\"registry.nestybox.com/nestybox/sysbox-deploy-k8s:v0.6.6-0\"\ntemp_file=$(mktemp)\nsed -E \"s|^([[:space:]]*image:)[[:space:]]*.*|\\1 $new_image_value|\" \"sysbox-install.yaml\" > \"$temp_file\"\nmv \"$temp_file\" \"sysbox-install.yaml\"\n","text",[91,648,645],{"__ignoreMap":101},[12,650,651],{},"Apply the YAML file to Kubernetes and ensure all the pods of the DaemonSet are running.",[96,653,655],{"className":98,"code":654,"language":100,"meta":101,"style":101},"kubectl apply -f sysbox-install.yaml\nkubectl get pod -A\nkubectl -n kube-system get daemonset\n",[91,656,657,669,682],{"__ignoreMap":101},[105,658,659,661,664,667],{"class":107,"line":108},[105,660,547],{"class":111},[105,662,663],{"class":114}," apply",[105,665,666],{"class":118}," -f",[105,668,624],{"class":114},[105,670,671,673,676,679],{"class":107,"line":125},[105,672,547],{"class":111},[105,674,675],{"class":114}," get",[105,677,678],{"class":114}," pod",[105,680,681],{"class":118}," -A\n",[105,683,684,686,689,691,693],{"class":107,"line":182},[105,685,547],{"class":111},[105,687,688],{"class":118}," -n",[105,690,372],{"class":114},[105,692,675],{"class":114},[105,694,695],{"class":114}," daemonset\n",[12,697,698],{},"Verify the installation by creating a pod which uses Sysbox container runtime.",[96,700,702],{"className":98,"code":701,"language":100,"meta":101,"style":101},"cat \u003C\u003CEOF | kubectl apply -f -\napiVersion: v1\nkind: Pod\nmetadata:\n  name: sysbox-verification-pod\n  namespace: default\n  annotations:\n    io.kubernetes.cri-o.userns-mode: \"auto:size=65536\"\nspec:\n  runtimeClassName: sysbox-runc\n  containers:\n  - image: \"hello-world\"\n    imagePullPolicy: Always\n    name: main\n  restartPolicy: Always\nEOF\n\nkubectl -n default get pod sysbox-verification-pod\nkubectl exec -it sysbox-verification-pod -- echo \"Pod is running successfully on a Kubernetes cluster configured with Sysbox.\"\nkubectl -n default delete pod sysbox-verification-pod\n",[91,703,704,727,732,737,742,747,752,757,762,767,772,777,782,787,792,798,804,809,826,849],{"__ignoreMap":101},[105,705,706,709,712,715,717,720,722,724],{"class":107,"line":108},[105,707,708],{"class":111},"cat",[105,710,711],{"class":128}," \u003C\u003C",[105,713,714],{"class":114},"EOF",[105,716,448],{"class":128},[105,718,719],{"class":111}," kubectl",[105,721,663],{"class":114},[105,723,666],{"class":118},[105,725,726],{"class":114}," -\n",[105,728,729],{"class":107,"line":125},[105,730,731],{"class":114},"apiVersion: v1\n",[105,733,734],{"class":107,"line":182},[105,735,736],{"class":114},"kind: Pod\n",[105,738,739],{"class":107,"line":196},[105,740,741],{"class":114},"metadata:\n",[105,743,744],{"class":107,"line":213},[105,745,746],{"class":114},"  name: sysbox-verification-pod\n",[105,748,749],{"class":107,"line":224},[105,750,751],{"class":114},"  namespace: default\n",[105,753,754],{"class":107,"line":232},[105,755,756],{"class":114},"  annotations:\n",[105,758,759],{"class":107,"line":240},[105,760,761],{"class":114},"    io.kubernetes.cri-o.userns-mode: \"auto:size=65536\"\n",[105,763,764],{"class":107,"line":248},[105,765,766],{"class":114},"spec:\n",[105,768,769],{"class":107,"line":256},[105,770,771],{"class":114},"  runtimeClassName: sysbox-runc\n",[105,773,774],{"class":107,"line":264},[105,775,776],{"class":114},"  containers:\n",[105,778,779],{"class":107,"line":275},[105,780,781],{"class":114},"  - image: \"hello-world\"\n",[105,783,784],{"class":107,"line":283},[105,785,786],{"class":114},"    imagePullPolicy: Always\n",[105,788,789],{"class":107,"line":291},[105,790,791],{"class":114},"    name: main\n",[105,793,795],{"class":107,"line":794},15,[105,796,797],{"class":114},"  restartPolicy: Always\n",[105,799,801],{"class":107,"line":800},16,[105,802,803],{"class":114},"EOF\n",[105,805,807],{"class":107,"line":806},17,[105,808,179],{"emptyLinePlaceholder":178},[105,810,812,814,816,819,821,823],{"class":107,"line":811},18,[105,813,547],{"class":111},[105,815,688],{"class":118},[105,817,818],{"class":114}," default",[105,820,675],{"class":114},[105,822,678],{"class":114},[105,824,825],{"class":114}," sysbox-verification-pod\n",[105,827,829,831,834,837,840,843,846],{"class":107,"line":828},19,[105,830,547],{"class":111},[105,832,833],{"class":114}," exec",[105,835,836],{"class":118}," -it",[105,838,839],{"class":114}," sysbox-verification-pod",[105,841,842],{"class":118}," --",[105,844,845],{"class":114}," echo",[105,847,848],{"class":114}," \"Pod is running successfully on a Kubernetes cluster configured with Sysbox.\"\n",[105,850,852,854,856,858,861,863],{"class":107,"line":851},20,[105,853,547],{"class":111},[105,855,688],{"class":118},[105,857,818],{"class":114},[105,859,860],{"class":114}," delete",[105,862,678],{"class":114},[105,864,825],{"class":114},[72,866,40],{"id":867},"configure-gitlab-agent-for-kubernetes-and-gitlab-workspaces-proxy",[12,869,870,871,876],{},"Follow our ",[25,872,875],{"href":873,"rel":874},"https://docs.gitlab.com/user/workspace/set_up_gitlab_agent_and_proxies/",[],"documentation tutorial"," to set up GitLab agent and GitLab Workspaces Proxy.",[72,878,46],{"id":879},"configure-sudo-access-for-a-workspace-with-sysbox",[12,881,870,882,887],{},[25,883,886],{"href":884,"rel":885},"https://docs.gitlab.com/user/workspace/configuration/#with-sysbox",[],"documentation"," to configure sudo access for a workspace with Sysbox.",[72,889,52],{"id":890},"configure-ingress-controller",[12,892,893,894],{},"Setup ",[25,895,898],{"href":896,"rel":897},"https://github.com/kubernetes/ingress-nginx",[],"Ingress NGINX Controller for Kubernetes",[96,900,902],{"className":98,"code":901,"language":100,"meta":101,"style":101},"helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx --force-update\nhelm repo update\n\nhelm upgrade --install \\\n  ingress-nginx ingress-nginx/ingress-nginx \\\n  --namespace ingress-nginx \\\n  --create-namespace \\\n  --version 4.11.1 \\\n  --timeout=600s --wait --wait-for-jobs\n\nkubectl -n ingress-nginx get pod\n",[91,903,904,924,933,937,949,959,967,974,983,994,998],{"__ignoreMap":101},[105,905,906,909,912,915,918,921],{"class":107,"line":108},[105,907,908],{"class":111},"helm",[105,910,911],{"class":114}," repo",[105,913,914],{"class":114}," add",[105,916,917],{"class":114}," ingress-nginx",[105,919,920],{"class":114}," https://kubernetes.github.io/ingress-nginx",[105,922,923],{"class":118}," --force-update\n",[105,925,926,928,930],{"class":107,"line":125},[105,927,908],{"class":111},[105,929,911],{"class":114},[105,931,932],{"class":114}," update\n",[105,934,935],{"class":107,"line":182},[105,936,179],{"emptyLinePlaceholder":178},[105,938,939,941,944,947],{"class":107,"line":196},[105,940,908],{"class":111},[105,942,943],{"class":114}," upgrade",[105,945,946],{"class":118}," --install",[105,948,193],{"class":118},[105,950,951,954,957],{"class":107,"line":213},[105,952,953],{"class":114},"  ingress-nginx",[105,955,956],{"class":114}," ingress-nginx/ingress-nginx",[105,958,193],{"class":118},[105,960,961,963,965],{"class":107,"line":224},[105,962,369],{"class":118},[105,964,917],{"class":114},[105,966,193],{"class":118},[105,968,969,972],{"class":107,"line":232},[105,970,971],{"class":118},"  --create-namespace",[105,973,193],{"class":118},[105,975,976,978,981],{"class":107,"line":240},[105,977,216],{"class":118},[105,979,980],{"class":118}," 4.11.1",[105,982,193],{"class":118},[105,984,985,988,991],{"class":107,"line":248},[105,986,987],{"class":118},"  --timeout=600s",[105,989,990],{"class":118}," --wait",[105,992,993],{"class":118}," --wait-for-jobs\n",[105,995,996],{"class":107,"line":256},[105,997,179],{"emptyLinePlaceholder":178},[105,999,1000,1002,1004,1006,1008],{"class":107,"line":264},[105,1001,547],{"class":111},[105,1003,688],{"class":118},[105,1005,917],{"class":114},[105,1007,675],{"class":114},[105,1009,1010],{"class":114}," pod\n",[72,1012,58],{"id":1013},"build-containers-inside-a-workspace",[12,1015,1016,1017,1022,1023,605],{},"We’ll use ",[25,1018,1021],{"href":1019,"rel":1020},"https://gitlab.com/gitlab-org/workspaces/examples/example-go-http-app",[],"example-go-http-app"," as the project to create a workspace from. Open the workspace, start a terminal, and install ",[25,1024,1027],{"href":1025,"rel":1026},"https://docs.docker.com/engine/install/",[],"Docker",[96,1029,1031],{"className":98,"code":1030,"language":100,"meta":101,"style":101},"# Add Docker's official GPG key:\nsudo apt-get update\nsudo apt-get install ca-certificates curl\nsudo install -m 0755 -d /etc/apt/keyrings\nsudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc\nsudo chmod a+r /etc/apt/keyrings/docker.asc\n\n# Add the repository to Apt sources:\necho \\\n  \"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \\\n  $(. /etc/os-release && echo \"${UBUNTU_CODENAME:-$VERSION_CODENAME}\") stable\" | \\\n  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null\nsudo apt-get update\nsudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin\n\n# Start the Docker Daemon\nsudo dockerd\n",[91,1032,1033,1039,1049,1064,1082,1100,1112,1116,1121,1128,1145,1175,1192,1200,1226,1230,1235],{"__ignoreMap":101},[105,1034,1035],{"class":107,"line":108},[105,1036,1038],{"class":1037},"sAwPA","# Add Docker's official GPG key:\n",[105,1040,1041,1044,1047],{"class":107,"line":125},[105,1042,1043],{"class":111},"sudo",[105,1045,1046],{"class":114}," apt-get",[105,1048,932],{"class":114},[105,1050,1051,1053,1055,1058,1061],{"class":107,"line":182},[105,1052,1043],{"class":111},[105,1054,1046],{"class":114},[105,1056,1057],{"class":114}," install",[105,1059,1060],{"class":114}," ca-certificates",[105,1062,1063],{"class":114}," curl\n",[105,1065,1066,1068,1070,1073,1076,1079],{"class":107,"line":196},[105,1067,1043],{"class":111},[105,1069,1057],{"class":114},[105,1071,1072],{"class":118}," -m",[105,1074,1075],{"class":118}," 0755",[105,1077,1078],{"class":118}," -d",[105,1080,1081],{"class":114}," /etc/apt/keyrings\n",[105,1083,1084,1086,1089,1092,1095,1097],{"class":107,"line":213},[105,1085,1043],{"class":111},[105,1087,1088],{"class":114}," curl",[105,1090,1091],{"class":118}," -fsSL",[105,1093,1094],{"class":114}," https://download.docker.com/linux/ubuntu/gpg",[105,1096,621],{"class":118},[105,1098,1099],{"class":114}," /etc/apt/keyrings/docker.asc\n",[105,1101,1102,1104,1107,1110],{"class":107,"line":224},[105,1103,1043],{"class":111},[105,1105,1106],{"class":114}," chmod",[105,1108,1109],{"class":114}," a+r",[105,1111,1099],{"class":114},[105,1113,1114],{"class":107,"line":232},[105,1115,179],{"emptyLinePlaceholder":178},[105,1117,1118],{"class":107,"line":240},[105,1119,1120],{"class":1037},"# Add the repository to Apt sources:\n",[105,1122,1123,1126],{"class":107,"line":248},[105,1124,1125],{"class":118},"echo",[105,1127,193],{"class":118},[105,1129,1130,1133,1136,1139,1142],{"class":107,"line":256},[105,1131,1132],{"class":114},"  \"deb [arch=$(",[105,1134,1135],{"class":111},"dpkg",[105,1137,1138],{"class":118}," --print-architecture",[105,1140,1141],{"class":114},") signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu ",[105,1143,1144],{"class":118},"\\\n",[105,1146,1147,1150,1152,1155,1157,1159,1162,1165,1168,1171,1173],{"class":107,"line":264},[105,1148,1149],{"class":114},"  $(",[105,1151,605],{"class":118},[105,1153,1154],{"class":114}," /etc/os-release && ",[105,1156,1125],{"class":118},[105,1158,202],{"class":114},[105,1160,1161],{"class":132},"UBUNTU_CODENAME",[105,1163,1164],{"class":128},":-",[105,1166,1167],{"class":132},"$VERSION_CODENAME",[105,1169,1170],{"class":114},"}\") stable\"",[105,1172,448],{"class":128},[105,1174,193],{"class":118},[105,1176,1177,1180,1183,1186,1189],{"class":107,"line":275},[105,1178,1179],{"class":111},"  sudo",[105,1181,1182],{"class":114}," tee",[105,1184,1185],{"class":114}," /etc/apt/sources.list.d/docker.list",[105,1187,1188],{"class":128}," >",[105,1190,1191],{"class":114}," /dev/null\n",[105,1193,1194,1196,1198],{"class":107,"line":283},[105,1195,1043],{"class":111},[105,1197,1046],{"class":114},[105,1199,932],{"class":114},[105,1201,1202,1204,1206,1208,1211,1214,1217,1220,1223],{"class":107,"line":291},[105,1203,1043],{"class":111},[105,1205,1046],{"class":114},[105,1207,1057],{"class":114},[105,1209,1210],{"class":118}," -y",[105,1212,1213],{"class":114}," docker-ce",[105,1215,1216],{"class":114}," docker-ce-cli",[105,1218,1219],{"class":114}," containerd.io",[105,1221,1222],{"class":114}," docker-buildx-plugin",[105,1224,1225],{"class":114}," docker-compose-plugin\n",[105,1227,1228],{"class":107,"line":794},[105,1229,179],{"emptyLinePlaceholder":178},[105,1231,1232],{"class":107,"line":800},[105,1233,1234],{"class":1037},"# Start the Docker Daemon\n",[105,1236,1237,1239],{"class":107,"line":806},[105,1238,1043],{"class":111},[105,1240,1241],{"class":114}," dockerd\n",[12,1243,1244],{},"Build the container image.",[96,1246,1248],{"className":98,"code":1247,"language":100,"meta":101,"style":101},"sudo docker build -t workspaces-golang-server .\n",[91,1249,1250],{"__ignoreMap":101},[105,1251,1252,1254,1257,1260,1263,1266],{"class":107,"line":108},[105,1253,1043],{"class":111},[105,1255,1256],{"class":114}," docker",[105,1258,1259],{"class":114}," build",[105,1261,1262],{"class":118}," -t",[105,1264,1265],{"class":114}," workspaces-golang-server",[105,1267,1268],{"class":114}," .\n",[72,1270,64],{"id":1271},"run-containers-inside-a-workspace",[12,1273,1274],{},"Let’s run the container built above and expose port 3000 from the container onto the host (workspace).",[96,1276,1278],{"className":98,"code":1277,"language":100,"meta":101,"style":101},"sudo docker run -p 3000:3000 workspaces-golang-server\n",[91,1279,1280],{"__ignoreMap":101},[105,1281,1282,1284,1286,1289,1292,1295],{"class":107,"line":108},[105,1283,1043],{"class":111},[105,1285,1256],{"class":114},[105,1287,1288],{"class":114}," run",[105,1290,1291],{"class":118}," -p",[105,1293,1294],{"class":114}," 3000:3000",[105,1296,1297],{"class":114}," workspaces-golang-server\n",[12,1299,1300,1301,1304,1305,1310],{},"The port ",[91,1302,1303],{},"3000"," is exposed in the ",[25,1306,1309],{"href":1307,"rel":1308},"https://gitlab.com/gitlab-org/workspaces/examples/example-go-http-app/-/blob/dd3dbb38cdce1143f7ed023980f34630cea991a5/.devfile.yaml#L15",[],".devfile.yaml"," used to create the workspace. Access the server running inside the container from the browser. Here is a video clip.",[1312,1313,1316,1317],"figure",{"className":1314},[1315],"video_container","\n  ",[1318,1319,1323],"iframe",{"src":1320,"frameBorder":1321,"allowFullScreen":1322},"https://www.youtube.com/embed/JQErF0U6oFk?si=6oiK48q5ghZq312g","0","true"," ",[72,1325,70],{"id":1326},"get-started-today",[12,1328,1329,1330,1334],{},"From GitLab 17.4, you can build and run containers securely in GitLab Workspaces. See our ",[25,1331,886],{"href":1332,"rel":1333},"https://docs.gitlab.com/user/workspace/configuration/#build-and-run-containers-in-a-workspace",[]," for more information. Replace your local development environments to GitLab Workspaces for a secure, ephemeral, reproducible development environment.",[72,1336,1338],{"id":1337},"read-more","Read more",[19,1340,1341,1348,1355,1362],{},[22,1342,1343],{},[25,1344,1347],{"href":1345,"rel":1346},"https://about.gitlab.com/blog/enable-secure-sudo-access-for-gitlab-remote-development-workspaces/",[],"Enable secure sudo access for GitLab Remote Development workspaces",[22,1349,1350],{},[25,1351,1354],{"href":1352,"rel":1353},"https://about.gitlab.com/blog/quick-start-guide-for-gitlab-workspaces/",[],"Quickstart guide for GitLab Remote Development workspaces",[22,1356,1357],{},[25,1358,1361],{"href":1359,"rel":1360},"https://about.gitlab.com/blog/create-a-workspace-quickly-with-the-gitlab-default-devfile/",[],"Create a workspace quickly with the GitLab default devfile",[22,1363,1364],{},[25,1365,1368],{"href":1366,"rel":1367},"https://about.gitlab.com/blog/gitlab-gdk-remote-development/",[],"Contributor how-to: Remote Development workspaces and GitLab Developer Kit",[1370,1371,1372],"style",{},"html pre.shiki code .s7eDp, html code.shiki .s7eDp{--shiki-default:#6F42C1}html pre.shiki code .sYBdl, html code.shiki .sYBdl{--shiki-default:#032F62}html pre.shiki code .sYu0t, html code.shiki .sYu0t{--shiki-default:#005CC5}html pre.shiki code .sD7c4, html code.shiki .sD7c4{--shiki-default:#D73A49}html pre.shiki code .sgsFI, html code.shiki .sgsFI{--shiki-default:#24292E}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}",{"title":101,"searchDepth":125,"depth":125,"links":1374},[1375,1376,1377,1378,1379,1380,1381,1382,1383],{"id":74,"depth":125,"text":28},{"id":585,"depth":125,"text":34},{"id":867,"depth":125,"text":40},{"id":879,"depth":125,"text":46},{"id":890,"depth":125,"text":52},{"id":1013,"depth":125,"text":58},{"id":1271,"depth":125,"text":64},{"id":1326,"depth":125,"text":70},{"id":1337,"depth":125,"text":1338},"product","2025-03-03","Use this easy-to-follow tutorial to create a secure, ephemeral, reproducible development environment in GitLab that can replace your local environments.","md",null,"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749663857/Blog/Hero%20Images/blog-image-template-1800x945__12_.png",{},"/en-us/blog/build-and-run-containers-in-remote-development-workspaces",{"title":5,"description":1386,"ogTitle":5,"ogDescription":1386,"noIndex":1393,"ogImage":1389,"ogUrl":1394,"ogSiteName":1395,"ogType":1396,"canonicalUrls":1394},false,"https://about.gitlab.com/blog/build-and-run-containers-in-remote-development-workspaces","https://about.gitlab.com","article","build-and-run-containers-in-remote-development-workspaces","en-us/blog/build-and-run-containers-in-remote-development-workspaces",[1400,1401,1402,1384],"tutorial","DevSecOps platform","features","BlogPost","toQdLYckIk5iCHSi3tMuvn-gP-aYzvjM-JDWqKrkREM",{"logo":1406,"freeTrial":1411,"sales":1416,"login":1421,"items":1426,"search":1752,"minimal":1783,"duo":1802,"switchNav":1811,"pricingDeployment":1822},{"config":1407},{"href":1408,"dataGaName":1409,"dataGaLocation":1410},"/","gitlab logo","header",{"text":1412,"config":1413},"Get free trial",{"href":1414,"dataGaName":1415,"dataGaLocation":1410},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":1417,"config":1418},"Request a demo",{"href":1419,"dataGaName":1420,"dataGaLocation":1410},"/sales/?contact-topic=request-demo","sales",{"text":1422,"config":1423},"Sign in",{"href":1424,"dataGaName":1425,"dataGaLocation":1410},"https://gitlab.com/users/sign_in/","sign in",[1427,1456,1556,1561,1674,1730],{"text":1428,"config":1429,"menu":1431},"Platform",{"dataNavLevelOne":1430},"platform",{"type":1432,"columns":1433},"cards",[1434,1440,1448],{"title":1428,"description":1435,"link":1436},"The intelligent orchestration platform for DevSecOps",{"text":1437,"config":1438},"Explore our Platform",{"href":1439,"dataGaName":1430,"dataGaLocation":1410},"/platform/",{"title":1441,"description":1442,"link":1443},"GitLab Duo Agent Platform","Agentic AI for the entire software lifecycle",{"text":1444,"config":1445},"Meet GitLab Duo",{"href":1446,"dataGaName":1447,"dataGaLocation":1410},"/gitlab-duo-agent-platform/","gitlab duo agent platform",{"title":1449,"description":1450,"link":1451},"Why GitLab","See the top reasons enterprises choose GitLab",{"text":1452,"config":1453},"Learn more",{"href":1454,"dataGaName":1455,"dataGaLocation":1410},"/why-gitlab/","why gitlab",{"text":1457,"left":178,"config":1458,"menu":1460},"Product",{"dataNavLevelOne":1459},"solutions",{"type":1461,"link":1462,"columns":1466,"feature":1535},"lists",{"text":1463,"config":1464},"View all Solutions",{"href":1465,"dataGaName":1459,"dataGaLocation":1410},"/solutions/",[1467,1491,1514],{"title":1468,"description":1469,"link":1470,"items":1475},"Automation","CI/CD and automation to accelerate deployment",{"config":1471},{"icon":1472,"href":1473,"dataGaName":1474,"dataGaLocation":1410},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[1476,1480,1483,1487],{"text":1477,"config":1478},"CI/CD",{"href":1479,"dataGaLocation":1410,"dataGaName":1477},"/solutions/continuous-integration/",{"text":1441,"config":1481},{"href":1446,"dataGaLocation":1410,"dataGaName":1482},"gitlab duo agent platform - product menu",{"text":1484,"config":1485},"Source Code Management",{"href":1486,"dataGaLocation":1410,"dataGaName":1484},"/solutions/source-code-management/",{"text":1488,"config":1489},"Automated Software Delivery",{"href":1473,"dataGaLocation":1410,"dataGaName":1490},"Automated software delivery",{"title":1492,"description":1493,"link":1494,"items":1499},"Security","Deliver code faster without compromising security",{"config":1495},{"href":1496,"dataGaName":1497,"dataGaLocation":1410,"icon":1498},"/solutions/application-security-testing/","security and compliance","ShieldCheckLight",[1500,1504,1509],{"text":1501,"config":1502},"Application Security Testing",{"href":1496,"dataGaName":1503,"dataGaLocation":1410},"Application security testing",{"text":1505,"config":1506},"Software Supply Chain Security",{"href":1507,"dataGaLocation":1410,"dataGaName":1508},"/solutions/supply-chain/","Software supply chain security",{"text":1510,"config":1511},"Software Compliance",{"href":1512,"dataGaName":1513,"dataGaLocation":1410},"/solutions/software-compliance/","software compliance",{"title":1515,"link":1516,"items":1521},"Measurement",{"config":1517},{"icon":1518,"href":1519,"dataGaName":1520,"dataGaLocation":1410},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[1522,1526,1530],{"text":1523,"config":1524},"Visibility & Measurement",{"href":1519,"dataGaLocation":1410,"dataGaName":1525},"Visibility and Measurement",{"text":1527,"config":1528},"Value Stream Management",{"href":1529,"dataGaLocation":1410,"dataGaName":1527},"/solutions/value-stream-management/",{"text":1531,"config":1532},"Analytics & Insights",{"href":1533,"dataGaLocation":1410,"dataGaName":1534},"/solutions/analytics-and-insights/","Analytics and insights",{"title":1536,"type":1461,"items":1537},"GitLab for",[1538,1544,1550],{"text":1539,"config":1540},"Enterprise",{"icon":1541,"href":1542,"dataGaLocation":1410,"dataGaName":1543},"Building","/enterprise/","enterprise",{"text":1545,"config":1546},"Small Business",{"icon":1547,"href":1548,"dataGaLocation":1410,"dataGaName":1549},"Work","/small-business/","small business",{"text":1551,"config":1552},"Public Sector",{"icon":1553,"href":1554,"dataGaLocation":1410,"dataGaName":1555},"Organization","/solutions/public-sector/","public sector",{"text":1557,"config":1558},"Pricing",{"href":1559,"dataGaName":1560,"dataGaLocation":1410,"dataNavLevelOne":1560},"/pricing/","pricing",{"text":1562,"config":1563,"menu":1565},"Resources",{"dataNavLevelOne":1564},"resources",{"type":1461,"link":1566,"columns":1570,"feature":1663},{"text":1567,"config":1568},"View all resources",{"href":1569,"dataGaName":1564,"dataGaLocation":1410},"/resources/",[1571,1603,1630],{"title":1572,"items":1573},"Getting started",[1574,1578,1583,1588,1593,1598],{"text":600,"config":1575},{"href":1576,"dataGaName":1577,"dataGaLocation":1410},"/install/","install",{"text":1579,"config":1580},"Quick start guides",{"href":1581,"dataGaName":1582,"dataGaLocation":1410},"/get-started/","quick setup checklists",{"text":1584,"config":1585},"Learn",{"href":1586,"dataGaLocation":1410,"dataGaName":1587},"https://university.gitlab.com/","learn",{"text":1589,"config":1590},"Product documentation",{"href":1591,"dataGaName":1592,"dataGaLocation":1410},"https://docs.gitlab.com/","product documentation",{"text":1594,"config":1595},"Best practice videos",{"href":1596,"dataGaName":1597,"dataGaLocation":1410},"/getting-started-videos/","best practice videos",{"text":1599,"config":1600},"Integrations",{"href":1601,"dataGaName":1602,"dataGaLocation":1410},"/integrations/","integrations",{"title":1604,"items":1605},"Discover",[1606,1611,1616,1621,1625],{"text":1607,"config":1608},"Customer success stories",{"href":1609,"dataGaName":1610,"dataGaLocation":1410},"/customers/","customer success stories",{"text":1612,"config":1613},"Blog",{"href":1614,"dataGaName":1615,"dataGaLocation":1410},"/blog/","blog",{"text":1617,"config":1618},"Demo Hub",{"href":1619,"dataGaName":1620,"dataGaLocation":1410},"/demo-hub/","demo hub",{"text":1622,"config":1623},"The Source",{"href":1624,"dataGaName":1615,"dataGaLocation":1410},"/the-source/",{"text":1626,"config":1627},"Remote",{"href":1628,"dataGaName":1629,"dataGaLocation":1410},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"title":1631,"items":1632},"Connect",[1633,1638,1643,1648,1653,1658],{"text":1634,"config":1635},"GitLab Services",{"href":1636,"dataGaName":1637,"dataGaLocation":1410},"/services/","services",{"text":1639,"config":1640},"Contribute",{"href":1641,"dataGaName":1642,"dataGaLocation":1410},"https://contributors.gitlab.com","contribute",{"text":1644,"config":1645},"Community",{"href":1646,"dataGaName":1647,"dataGaLocation":1410},"/community/","community",{"text":1649,"config":1650},"Forum",{"href":1651,"dataGaName":1652,"dataGaLocation":1410},"https://forum.gitlab.com/","forum",{"text":1654,"config":1655},"Events",{"href":1656,"dataGaName":1657,"dataGaLocation":1410},"/events/","events",{"text":1659,"config":1660},"Partners",{"href":1661,"dataGaName":1662,"dataGaLocation":1410},"/partners/","partners",{"config":1664,"title":1667,"text":1668,"link":1669},{"background":1665,"textColor":1666},"url('https://res.cloudinary.com/about-gitlab-com/image/upload/v1777322348/qpq8yrgn8knii57omj0c.png')","#000","What’s new in GitLab","Stay updated with our latest features and improvements.",{"text":1670,"config":1671},"Read the latest",{"href":1672,"dataGaName":1673,"dataGaLocation":1410},"/whats-new/","whats new",{"text":1675,"config":1676,"menu":1678},"Company",{"dataNavLevelOne":1677},"company",{"type":1461,"columns":1679},[1680],{"items":1681},[1682,1687,1693,1695,1700,1705,1710,1715,1720,1725],{"text":1683,"config":1684},"About",{"href":1685,"dataGaName":1686,"dataGaLocation":1410},"/company/","about",{"text":1688,"config":1689,"footerGa":1692},"Jobs",{"href":1690,"dataGaName":1691,"dataGaLocation":1410},"/jobs/","jobs",{"dataGaName":1691},{"text":1654,"config":1694},{"href":1656,"dataGaName":1657,"dataGaLocation":1410},{"text":1696,"config":1697},"Leadership",{"href":1698,"dataGaName":1699,"dataGaLocation":1410},"/company/team/e-group/","leadership",{"text":1701,"config":1702},"Handbook",{"href":1703,"dataGaName":1704,"dataGaLocation":1410},"https://handbook.gitlab.com/","handbook",{"text":1706,"config":1707},"Investor relations",{"href":1708,"dataGaName":1709,"dataGaLocation":1410},"https://ir.gitlab.com/overview/default.aspx","investor relations",{"text":1711,"config":1712},"Trust Center",{"href":1713,"dataGaName":1714,"dataGaLocation":1410},"/security/","trust center",{"text":1716,"config":1717},"AI Transparency Center",{"href":1718,"dataGaName":1719,"dataGaLocation":1410},"/ai-transparency-center/","ai transparency center",{"text":1721,"config":1722},"Newsletter",{"href":1723,"dataGaName":1724,"dataGaLocation":1410},"/company/contact/#contact-forms","newsletter",{"text":1726,"config":1727},"Press",{"href":1728,"dataGaName":1729,"dataGaLocation":1410},"/press/","press",{"text":1731,"config":1732,"menu":1733},"Contact us",{"dataNavLevelOne":1677},{"type":1461,"columns":1734},[1735],{"items":1736},[1737,1742,1747],{"text":1738,"config":1739},"Talk to sales",{"href":1740,"dataGaName":1741,"dataGaLocation":1410},"/sales/","talk to sales",{"text":1743,"config":1744},"Support portal",{"href":1745,"dataGaName":1746,"dataGaLocation":1410},"https://support.gitlab.com/hc/en-us","support portal",{"text":1748,"config":1749},"Customer portal",{"href":1750,"dataGaName":1751,"dataGaLocation":1410},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":1753,"login":1754,"suggestions":1761},"Close",{"text":1755,"link":1756},"To search repositories and projects, login to",{"text":1757,"config":1758},"gitlab.com",{"href":1424,"dataGaName":1759,"dataGaLocation":1760},"search login","search",{"text":1762,"default":1763},"Suggestions",[1764,1766,1770,1772,1776,1780],{"text":1441,"config":1765},{"href":1446,"dataGaName":1441,"dataGaLocation":1760},{"text":1767,"config":1768},"Code Suggestions (AI)",{"href":1769,"dataGaName":1767,"dataGaLocation":1760},"/solutions/code-suggestions/",{"text":1477,"config":1771},{"href":1479,"dataGaName":1477,"dataGaLocation":1760},{"text":1773,"config":1774},"GitLab on AWS",{"href":1775,"dataGaName":1773,"dataGaLocation":1760},"/partners/technology-partners/aws/",{"text":1777,"config":1778},"GitLab on Google Cloud",{"href":1779,"dataGaName":1777,"dataGaLocation":1760},"/partners/technology-partners/google-cloud-platform/",{"text":1781,"config":1782},"Why GitLab?",{"href":1454,"dataGaName":1781,"dataGaLocation":1760},{"freeTrial":1784,"mobileIcon":1789,"desktopIcon":1794,"secondaryButton":1797},{"text":1785,"config":1786},"Start free trial",{"href":1787,"dataGaName":1415,"dataGaLocation":1788},"https://gitlab.com/-/trials/new/","nav",{"altText":1790,"config":1791},"Gitlab Icon",{"src":1792,"dataGaName":1793,"dataGaLocation":1788},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":1790,"config":1795},{"src":1796,"dataGaName":1793,"dataGaLocation":1788},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":1798,"config":1799},"Get Started",{"href":1800,"dataGaName":1801,"dataGaLocation":1788},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/get-started/","get started",{"freeTrial":1803,"mobileIcon":1807,"desktopIcon":1809},{"text":1804,"config":1805},"Learn more about GitLab Duo",{"href":1446,"dataGaName":1806,"dataGaLocation":1788},"gitlab duo",{"altText":1790,"config":1808},{"src":1792,"dataGaName":1793,"dataGaLocation":1788},{"altText":1790,"config":1810},{"src":1796,"dataGaName":1793,"dataGaLocation":1788},{"button":1812,"mobileIcon":1817,"desktopIcon":1819},{"text":1813,"config":1814},"/switch",{"href":1815,"dataGaName":1816,"dataGaLocation":1788},"#contact","switch",{"altText":1790,"config":1818},{"src":1792,"dataGaName":1793,"dataGaLocation":1788},{"altText":1790,"config":1820},{"src":1821,"dataGaName":1793,"dataGaLocation":1788},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1773335277/ohhpiuoxoldryzrnhfrh.png",{"freeTrial":1823,"mobileIcon":1828,"desktopIcon":1830},{"text":1824,"config":1825},"Back to pricing",{"href":1559,"dataGaName":1826,"dataGaLocation":1788,"icon":1827},"back to pricing","GoBack",{"altText":1790,"config":1829},{"src":1792,"dataGaName":1793,"dataGaLocation":1788},{"altText":1790,"config":1831},{"src":1796,"dataGaName":1793,"dataGaLocation":1788},{"title":1833,"titleMobile":1834,"button":1835,"config":1840},"Duo Agent Platform delivers 400% ROI, per new Forrester Consulting study.","400% ROI: Forrester TEI for GitLab Duo",{"text":1452,"config":1836},{"href":1837,"dataGaName":1838,"dataGaLocation":1839},"https://about.gitlab.com/blog/gitlab-duo-agent-platform-delivers-400-percent-roi/","forrester-tei-dap-banner","global-banner",{"layout":1841,"disabled":1393},"release",{"data":1843},{"text":1844,"source":1845,"edit":1851,"contribute":1856,"config":1861,"items":1866,"minimal":2075},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":1846,"config":1847},"View page source",{"href":1848,"dataGaName":1849,"dataGaLocation":1850},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":1852,"config":1853},"Edit this page",{"href":1854,"dataGaName":1855,"dataGaLocation":1850},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":1857,"config":1858},"Please contribute",{"href":1859,"dataGaName":1860,"dataGaLocation":1850},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":1862,"facebook":1863,"youtube":1864,"linkedin":1865},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[1867,1914,1967,2011,2043],{"title":1557,"links":1868,"subMenu":1883},[1869,1873,1878],{"text":1870,"config":1871},"View plans",{"href":1559,"dataGaName":1872,"dataGaLocation":1850},"view plans",{"text":1874,"config":1875},"Why Premium?",{"href":1876,"dataGaName":1877,"dataGaLocation":1850},"/pricing/premium/","why premium",{"text":1879,"config":1880},"Why Ultimate?",{"href":1881,"dataGaName":1882,"dataGaLocation":1850},"/pricing/ultimate/","why ultimate",[1884],{"title":1885,"links":1886},"Contact Us",[1887,1890,1892,1894,1899,1904,1909],{"text":1888,"config":1889},"Contact sales",{"href":1740,"dataGaName":1420,"dataGaLocation":1850},{"text":1743,"config":1891},{"href":1745,"dataGaName":1746,"dataGaLocation":1850},{"text":1748,"config":1893},{"href":1750,"dataGaName":1751,"dataGaLocation":1850},{"text":1895,"config":1896},"Status",{"href":1897,"dataGaName":1898,"dataGaLocation":1850},"https://status.gitlab.com/","status",{"text":1900,"config":1901},"Terms of use",{"href":1902,"dataGaName":1903,"dataGaLocation":1850},"/terms/","terms of use",{"text":1905,"config":1906},"Privacy statement",{"href":1907,"dataGaName":1908,"dataGaLocation":1850},"/privacy/","privacy statement",{"text":1910,"config":1911},"Cookie preferences",{"dataGaName":1912,"dataGaLocation":1850,"id":1913,"isOneTrustButton":178},"cookie preferences","ot-sdk-btn",{"title":1457,"links":1915,"subMenu":1923},[1916,1919],{"text":1401,"config":1917},{"href":1439,"dataGaName":1918,"dataGaLocation":1850},"devsecops platform",{"text":1920,"config":1921},"AI-Assisted Development",{"href":1446,"dataGaName":1922,"dataGaLocation":1850},"ai-assisted development",[1924],{"title":1925,"links":1926},"Topics",[1927,1932,1937,1942,1947,1952,1957,1962],{"text":1928,"config":1929},"CICD",{"href":1930,"dataGaName":1931,"dataGaLocation":1850},"/topics/ci-cd/","cicd",{"text":1933,"config":1934},"GitOps",{"href":1935,"dataGaName":1936,"dataGaLocation":1850},"/topics/gitops/","gitops",{"text":1938,"config":1939},"DevOps",{"href":1940,"dataGaName":1941,"dataGaLocation":1850},"/topics/devops/","devops",{"text":1943,"config":1944},"Version Control",{"href":1945,"dataGaName":1946,"dataGaLocation":1850},"/topics/version-control/","version control",{"text":1948,"config":1949},"DevSecOps",{"href":1950,"dataGaName":1951,"dataGaLocation":1850},"/topics/devsecops/","devsecops",{"text":1953,"config":1954},"Cloud Native",{"href":1955,"dataGaName":1956,"dataGaLocation":1850},"/topics/cloud-native/","cloud native",{"text":1958,"config":1959},"AI for Coding",{"href":1960,"dataGaName":1961,"dataGaLocation":1850},"/topics/devops/ai-for-coding/","ai for coding",{"text":1963,"config":1964},"Agentic AI",{"href":1965,"dataGaName":1966,"dataGaLocation":1850},"/topics/agentic-ai/","agentic ai",{"title":1968,"links":1969},"Solutions",[1970,1972,1974,1979,1983,1986,1990,1993,1995,1998,2001,2006],{"text":1501,"config":1971},{"href":1496,"dataGaName":1501,"dataGaLocation":1850},{"text":1490,"config":1973},{"href":1473,"dataGaName":1474,"dataGaLocation":1850},{"text":1975,"config":1976},"Agile development",{"href":1977,"dataGaName":1978,"dataGaLocation":1850},"/solutions/agile-delivery/","agile delivery",{"text":1980,"config":1981},"SCM",{"href":1486,"dataGaName":1982,"dataGaLocation":1850},"source code management",{"text":1928,"config":1984},{"href":1479,"dataGaName":1985,"dataGaLocation":1850},"continuous integration & delivery",{"text":1987,"config":1988},"Value stream management",{"href":1529,"dataGaName":1989,"dataGaLocation":1850},"value stream management",{"text":1933,"config":1991},{"href":1992,"dataGaName":1936,"dataGaLocation":1850},"/solutions/gitops/",{"text":1539,"config":1994},{"href":1542,"dataGaName":1543,"dataGaLocation":1850},{"text":1996,"config":1997},"Small business",{"href":1548,"dataGaName":1549,"dataGaLocation":1850},{"text":1999,"config":2000},"Public sector",{"href":1554,"dataGaName":1555,"dataGaLocation":1850},{"text":2002,"config":2003},"Education",{"href":2004,"dataGaName":2005,"dataGaLocation":1850},"/solutions/education/","education",{"text":2007,"config":2008},"Financial services",{"href":2009,"dataGaName":2010,"dataGaLocation":1850},"/solutions/finance/","financial services",{"title":1562,"links":2012},[2013,2015,2017,2019,2022,2024,2027,2029,2031,2033,2035,2037,2039,2041],{"text":600,"config":2014},{"href":1576,"dataGaName":1577,"dataGaLocation":1850},{"text":1579,"config":2016},{"href":1581,"dataGaName":1582,"dataGaLocation":1850},{"text":1584,"config":2018},{"href":1586,"dataGaName":1587,"dataGaLocation":1850},{"text":1589,"config":2020},{"href":1591,"dataGaName":2021,"dataGaLocation":1850},"docs",{"text":1612,"config":2023},{"href":1614,"dataGaName":1615,"dataGaLocation":1850},{"text":2025,"config":2026},"What's new",{"href":1672,"dataGaName":1673,"dataGaLocation":1850},{"text":1607,"config":2028},{"href":1609,"dataGaName":1610,"dataGaLocation":1850},{"text":1626,"config":2030},{"href":1628,"dataGaName":1629,"dataGaLocation":1850},{"text":1634,"config":2032},{"href":1636,"dataGaName":1637,"dataGaLocation":1850},{"text":1639,"config":2034},{"href":1641,"dataGaName":1642,"dataGaLocation":1850},{"text":1644,"config":2036},{"href":1646,"dataGaName":1647,"dataGaLocation":1850},{"text":1649,"config":2038},{"href":1651,"dataGaName":1652,"dataGaLocation":1850},{"text":1654,"config":2040},{"href":1656,"dataGaName":1657,"dataGaLocation":1850},{"text":1659,"config":2042},{"href":1661,"dataGaName":1662,"dataGaLocation":1850},{"title":1675,"links":2044},[2045,2047,2049,2051,2053,2055,2059,2064,2066,2068,2070],{"text":1683,"config":2046},{"href":1685,"dataGaName":1677,"dataGaLocation":1850},{"text":1688,"config":2048},{"href":1690,"dataGaName":1691,"dataGaLocation":1850},{"text":1696,"config":2050},{"href":1698,"dataGaName":1699,"dataGaLocation":1850},{"text":1701,"config":2052},{"href":1703,"dataGaName":1704,"dataGaLocation":1850},{"text":1706,"config":2054},{"href":1708,"dataGaName":1709,"dataGaLocation":1850},{"text":2056,"config":2057},"Sustainability",{"href":2058,"dataGaName":2056,"dataGaLocation":1850},"/sustainability/",{"text":2060,"config":2061},"Diversity, inclusion and belonging (DIB)",{"href":2062,"dataGaName":2063,"dataGaLocation":1850},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":1711,"config":2065},{"href":1713,"dataGaName":1714,"dataGaLocation":1850},{"text":1721,"config":2067},{"href":1723,"dataGaName":1724,"dataGaLocation":1850},{"text":1726,"config":2069},{"href":1728,"dataGaName":1729,"dataGaLocation":1850},{"text":2071,"config":2072},"Modern Slavery Transparency Statement",{"href":2073,"dataGaName":2074,"dataGaLocation":1850},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"items":2076},[2077,2080,2083],{"text":2078,"config":2079},"Terms",{"href":1902,"dataGaName":1903,"dataGaLocation":1850},{"text":2081,"config":2082},"Cookies",{"dataGaName":1912,"dataGaLocation":1850,"id":1913,"isOneTrustButton":178},{"text":2084,"config":2085},"Privacy",{"href":1907,"dataGaName":1908,"dataGaLocation":1850},[2087],{"id":2088,"title":7,"body":1388,"config":2089,"content":2091,"description":1388,"extension":2095,"meta":2096,"navigation":178,"path":2097,"seo":2098,"stem":2099,"__hash__":2100},"blogAuthors/en-us/blog/authors/vishal-tak.yml",{"template":2090},"BlogAuthor",{"name":7,"config":2092},{"headshot":2093,"ctfId":2094},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749663854/Blog/Author%20Headshots/vishal_tak_headshot.png","6BalO1YQUIuDdhUP80bFra","yml",{},"/en-us/blog/authors/vishal-tak",{},"en-us/blog/authors/vishal-tak","WQVjyh5oeihTVp9uFThfEtK2F54wNmeVU5OzhSx42vc",[2102,2108,2112],{"title":2103,"description":2104,"heroImage":2105,"category":1384,"date":2106,"authors":1388,"slug":1388,"externalUrl":2107},"GitLab Patch Release: 19.2.2, 19.1.4, 19.0.6","Learn about this latest patch release for Community Edition and Enterprise Edition.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749661926/Blog/Hero%20Images/security-patch-blog-image-r2-0506-700x400-fy25_2x.jpg","2026-08-12","https://docs.gitlab.com/releases/patches/patch-release-gitlab-19-2-2-released/",{"title":2109,"description":2104,"heroImage":2105,"category":1384,"date":2110,"authors":1388,"slug":1388,"externalUrl":2111}," GitLab Patch Release: 19.2.1, 19.1.3, 19.0.5","2026-07-29","https://docs.gitlab.com/releases/patches/patch-release-gitlab-19-2-1-released/",{"title":2113,"description":2114,"heroImage":2115,"category":1384,"date":2116,"authors":2117,"slug":2119,"externalUrl":1388},"Automate work item assignment with a \"Work item created\" trigger","Our step-by-step guide walks through this AI capability, which enables instant, scalable triage without manual intervention.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1773866173/vte9qh8rriznvyclhkes.png","2026-07-20",[2118],"Cesar Saavedra","how-to-use-a-work-item-created-trigger",{"promotions":2121},[2122,2136,2147,2159],{"id":2123,"categories":2124,"header":2126,"text":2127,"button":2128,"image":2133},"ai-modernization",[2125],"ai","Is AI achieving its promise at scale?","Quiz will take 5 minutes or less",{"text":2129,"config":2130},"Get your AI maturity score",{"href":2131,"dataGaName":2132,"dataGaLocation":1615},"/assessments/ai-modernization-assessment/","modernization assessment",{"config":2134},{"src":2135},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/qix0m7kwnd8x2fh1zq49.png",{"id":2137,"categories":2138,"header":2139,"text":2127,"button":2140,"image":2144},"devops-modernization",[1384,1951],"Are you just managing tools or shipping innovation?",{"text":2141,"config":2142},"Get your DevOps maturity score",{"href":2143,"dataGaName":2132,"dataGaLocation":1615},"/assessments/devops-modernization-assessment/",{"config":2145},{"src":2146},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138785/eg818fmakweyuznttgid.png",{"id":2148,"categories":2149,"header":2151,"text":2127,"button":2152,"image":2156},"security-modernization",[2150],"security","Are you trading speed for security?",{"text":2153,"config":2154},"Get your security maturity score",{"href":2155,"dataGaName":2132,"dataGaLocation":1615},"/assessments/security-modernization-assessment/",{"config":2157},{"src":2158},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/p4pbqd9nnjejg5ds6mdk.png",{"id":2160,"paths":2161,"header":2164,"text":2165,"button":2166,"image":2171},"github-azure-migration",[2162,2163],"migration-from-azure-devops-to-gitlab","integrating-azure-devops-scm-and-gitlab","Is your team ready for GitHub's Azure move?","GitHub is already rebuilding around Azure. Find out what it means for you.",{"text":2167,"config":2168},"See how GitLab compares to GitHub",{"href":2169,"dataGaName":2170,"dataGaLocation":1615},"/compare/gitlab-vs-github/github-azure-migration/","github azure migration",{"config":2172},{"src":2146},{"header":2174,"blurb":2175,"button":2176,"secondaryButton":2181},"Start building faster today","See what your team can do with the intelligent orchestration platform for DevSecOps.\n",{"text":2177,"config":2178},"Get your free trial",{"href":2179,"dataGaName":1415,"dataGaLocation":2180},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":1888,"config":2182},{"href":1740,"dataGaName":1420,"dataGaLocation":2180},1786803766858]