[{"data":1,"prerenderedAt":2078},["ShallowReactive",2],{"/blog/continuous-delivery-with-gitlab-and-convox":3,"navigation-en-us":1293,"banner-en-us":1719,"footer-en-us":1729,"blog-post-authors-en-us-Noah Zoschke":1974,"blog-related-posts-en-us-continuous-delivery-with-gitlab-and-convox":1989,"blog-promotions-en-us":2014,"next-steps-en-us":2068},{"id":4,"title":5,"authors":6,"body":8,"category":1252,"date":1253,"description":1254,"extension":1255,"externalUrl":1256,"faq":1256,"featured":1257,"heroImage":1258,"meta":1259,"navigation":512,"path":1284,"seo":1285,"slug":1289,"stem":1290,"tags":1256,"template":1291,"updatedDate":1256,"__hash__":1292},"blogPosts/en-us/blog/continuous-delivery-with-gitlab-and-convox.md","Continuous Delivery with GitLab and Convox",[7],"Noah Zoschke",{"type":9,"value":10,"toc":1237},"minimark",[11,21,29,52,55,60,67,69,74,77,91,94,103,107,115,118,162,165,168,171,181,189,193,206,209,232,239,248,252,255,263,271,274,277,280,284,287,290,293,301,304,308,311,320,328,331,334,338,344,1023,1032,1035,1041,1045,1048,1056,1067,1175,1189,1193,1196,1211,1215,1218,1221,1225,1233],[12,13,14,20],"p",{},[15,16,19],"a",{"href":17,"rel":18},"https://convox.com/",[],"Convox"," is an open-source tool for deploying, managing, and monitoring applications on cloud infrastructure. It increases the productivity of your developers, reduces your infrastructure spend, and ensures that your architecture is resilient, consistent, and compliant.",[12,22,23,24,28],{},"Recently, Convox launched a native integration with ",[15,25,27],{"href":26},"/","GitLab"," for Continuous Delivery (CD). This tutorial will show you how to use GitLab and Convox together to ship software quickly and reliably.",[12,30,31,35,36,41,42,47,48,51],{},[32,33,34],"strong",{},"Note:"," For this tutorial we assume you are familiar with Continuous Deployment (CD) and have a GitLab, ",[15,37,40],{"href":38,"rel":39},"https://slack.com/",[],"Slack"," and ",[15,43,46],{"href":44,"rel":45},"https://aws.amazon.com/",[],"Amazon Web Services"," (AWS) account. We also assume you are curious about how ",[15,49,19],{"href":17,"rel":50},[]," utilities make setting up a private, production-ready cloud environment easy.",[53,54],"hr",{},[56,57,59],"h3",{"id":58},"whats-in-this-page","What's in this page?",[61,62,63],"ul",{},[64,65,66],"li",{},"TOC",[53,68],{},[70,71,73],"h2",{"id":72},"continuous-delivery","Continuous Delivery",[12,75,76],{},"Continuous Delivery (CD) is a modern software development best practice. Your team wants and needs the ability to safely push updates to production multiple times a day. With a great CD pipeline you can:",[61,78,79,82,85,88],{},[64,80,81],{},"Ship features faster and more frequently",[64,83,84],{},"Roll out bug fixes and security patches instantly",[64,86,87],{},"Keep your development team in a coding flow",[64,89,90],{},"Eliminate work and interruptions on infrastructure that’s not core to your business",[12,92,93],{},"If you don’t have CD tools, you may be spending too much precious time and budget on infrastructure, servers and bespoke deployment tools.",[12,95,96,97,102],{},"See the ",[15,98,101],{"href":99,"rel":100},"https://en.wikipedia.org/wiki/Continuous_delivery",[],"Wikipedia article on Continuous Delivery"," for more details about the Continuous Delivery approach.",[70,104,106],{"id":105},"cd-with-gitlab-and-convox","CD with GitLab and Convox",[12,108,109,110,114],{},"The best Continuous Delivery workflow offers a way to ",[111,112,113],"code",{},"git push"," code and automatically deploy it to resilient cloud infrastructure.",[12,116,117],{},"Convox and GitLab together represent a modern open-source based Continuous Delivery solution. With both of them your team can:",[61,119,120,129,137,143,150,156],{},[64,121,122,125,126],{},[32,123,124],{},"Set up a private deployment cloud in minutes"," with ",[111,127,128],{},"convox install",[64,130,131,125,134],{},[32,132,133],{},"Create a production-ready application",[111,135,136],{},"convox apps create",[64,138,139,142],{},[32,140,141],{},"Link GitLab.com or GitLab CE/EE and Slack to your deployment cloud"," through the Convox Console",[64,144,145,125,148],{},[32,146,147],{},"Push code to GitLab",[111,149,113],{},[64,151,152,155],{},[32,153,154],{},"Let GitLab webhooks or CI automate builds",", tests and deploys of your code to Convox",[64,157,158,161],{},[32,159,160],{},"Notify your team via Slack"," when the new release is live",[12,163,164],{},"This level of automation enables your team to safely release new code as fast as possible, offering an extremely productive workflow for you and your team.",[12,166,167],{},"All of this is built on open-source software that you are free to read, modify, and work with the OSS communities to improve.",[12,169,170],{},"On top of the open-source projects, both GitLab and Convox offer enterprise-grade options to run this in a totally isolated environment where your code, images and containers never leave your control.",[12,172,173,178],{},[174,175],"img",{"alt":176,"src":177},"Continuous Delivery from GitLab to Convox","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398119/blog/Content%20Images/continuous-delivery-with-gitlab-and-convox/gitlab-integration.png",[179,180,176],"em",{},[12,182,183,187],{},[174,184],{"alt":185,"src":186},"Push Code, Get Service","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398120/blog/Content%20Images/continuous-delivery-with-gitlab-and-convox/slack.png",[179,188,185],{},[56,190,192],{"id":191},"setting-up-a-convox-deployment-environment","Setting up a Convox Deployment Environment",[12,194,195,196,41,198,200,201,205],{},"We first need to configure an isolated environment where we will deploy everything. When deploying to AWS, there is a minimum architecture we want for a production-ready environment. Convox makes this simple with the ",[111,197,128],{},[111,199,136],{}," tools. Click the \"Get Started\" button on ",[15,202,204],{"href":17,"rel":203},[],"convox.com"," to access the web or command line installer.",[12,207,208],{},"Convox expertly integrates the following AWS services:",[61,210,211,214,217,220,223,226,229],{},[64,212,213],{},"Virtual Private Cloud spanning 3 availability zones for network isolation",[64,215,216],{},"EC2 and an AutoScale Group (ASG) with at least 3 instances for redundancy",[64,218,219],{},"CloudFormation stacks for safe, automated updates for new AMIs or to scale up instance type and count",[64,221,222],{},"EC2 Container Service (ECS) for container-based zero downtime deploys",[64,224,225],{},"EC2 Container Registry (ECR) for storing build artifacts",[64,227,228],{},"Elastic Load Balancer (ELB) for SSL, websockets and load balancing",[64,230,231],{},"CloudWatch Logs for log tailing, archiving and search",[12,233,234,235,238],{},"With this consistent, batteries-included cluster setup with the ",[111,236,237],{},"convox"," tools we can now relibly deploy, configure and scale our applications.",[12,240,241,242,247],{},"You can read the ",[15,243,246],{"href":244,"rel":245},"https://convox.com/docs/getting-started/",[],"Getting Started on Convox"," guide for more detailed instructions about setting everything up.",[56,249,251],{"id":250},"granting-gitlab-and-slack-auth-to-convox","Granting GitLab and Slack Auth to Convox",[12,253,254],{},"Every service integration begins with authorizing two services to talk to each other. For the first iteration of GitLab and Convox, we opted for a simple token-based solution.",[12,256,257,261],{},[174,258],{"alt":259,"src":260},"Get your GitLab Private Token","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398118/blog/Content%20Images/continuous-delivery-with-gitlab-and-convox/gitlab-account.png",[179,262,259],{},[12,264,265,269],{},[174,266],{"alt":267,"src":268},"Give Convox your GitLab Endpoint and Token","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398119/blog/Content%20Images/continuous-delivery-with-gitlab-and-convox/gitlab-setup.png",[179,270,267],{},[12,272,273],{},"Convox encrypts this token, and decrypts it when it needs to perform actions on your GitLab instance like creating a webhook and deploy key.",[12,275,276],{},"Similarly, you integrate Convox and Slack with an OAuth flow.",[12,278,279],{},"Now Convox has access tokens to get and send information to GitLab and Slack.",[56,281,283],{"id":282},"git-push-webhooks","Git Push Webhooks",[12,285,286],{},"Webhooks — user-defined HTTP callbacks — are the fabric on which Continuous Deployment systems are built.",[12,288,289],{},"GitLab has tremendous webhook support, allowing you to configure how it will make an HTTPS request to an external system on events like every comment, code push and code merge.",[12,291,292],{},"When you integrate GitLab with a Convox app, the first thing Convox does is add a new Push Event webhook to your project pointing to a secure and secret Convox URL.",[12,294,295,299],{},[174,296],{"alt":297,"src":298},"Tell Convox About the Push","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398120/blog/Content%20Images/continuous-delivery-with-gitlab-and-convox/gitlab-webhooks.png",[179,300,297],{},[12,302,303],{},"When this is configured, Convox will get a notification every time your team pushes new code.",[56,305,307],{"id":306},"gitlab-deploy-keys","GitLab Deploy Keys",[12,309,310],{},"GitLab has an impeccable security model. If a system like Convox happens to learn the URL for a private repo via a webhook, we still want to control its ability to read or write to this private repo.",[12,312,313,314,319],{},"To grant Convox limited, read-only access to your private repo, GitLab offers “",[15,315,318],{"href":316,"rel":317},"https://docs.gitlab.com/user/project/deploy_keys/",[],"Deploy Keys",".” These are SSH keys that have read-only access to a repo, guaranteeing that a third-party system can clone code, but can not push any code back.",[12,321,322,326],{},[174,323],{"alt":324,"src":325},"Read-only SSH key","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398119/blog/Content%20Images/continuous-delivery-with-gitlab-and-convox/gitlab-deploy-key.png",[179,327,324],{},[12,329,330],{},"When you integrate GitLab with a Convox app, the next thing Convox does is generate a new SSH keypair, encrypt and save the private key, and set up a new Deploy Key with the public key.",[12,332,333],{},"With a webhook and deploy key, Convox can dutifully perform an automatic build and/or deploy.",[56,335,337],{"id":336},"delivering-code-to-production","Delivering Code to Production",[12,339,340,341,343],{},"Now that a Convox environment is running and it is authorized to get webhooks and pull code from GitLab, and send notifications to Slack, we can do our first ",[111,342,113],{}," deploy that rolls out new containers:",[345,346,351],"pre",{"className":347,"code":348,"language":349,"meta":350,"style":350},"language-shell shiki shiki-themes github-light","$ git push gitlab master\nCounting objects: 8, done.\nDelta compression using up to 4 threads.\nCompressing objects: 100% (8/8), done.\nWriting objects: 100% (8/8), 758 bytes | 0 bytes/s, done.\nTotal 8 (delta 7), reused 0 (delta 0)\nTo https://gitlab.com/nzoschke/httpd.git\n   176d4d2..896d06b  master -> master\n\n$ convox builds\nID           STATUS    RELEASE      STARTED         ELAPSED DESC\nBCPSBDTVSVB  complete  RQYRSVEXGLD  56 seconds ago  52s      push nzoschke/httpd refs/heads/master 896d06b2a72e702c3c2efe8fae9670bd19f5f255\nBSZIBYZFDDU  complete  RVUEQWAOHTN  5 days ago      60s      push nzoschke/httpd refs/heads/master 176d4d22d0631c1223ea7ba31d80f837e4a24390\n\n$ convox builds info BCPSBDTVSVB\nRUNNING: git clone --progress git@gitlab.com:nzoschke/httpd.git src\nRUNNING: git checkout 896d06b2a72e702c3c2efe8fae9670bd19f5f255\nRUNNING: /usr/local/bin/git-restore-mtime .\nRUNNING: docker pull httpd\n...\ncb604ab7d359: Pull complete\nDigest: sha256:3eae43b977887f7f660c640ba8477dc1af1626d757ff1a7ddba050418429f2f6\nStatus: Downloaded newer image for httpd:latest\nRUNNING: docker tag -f httpd httpd/web\nRUNNING: docker tag -f httpd/web 132866487567.dkr.ecr.us-east-1.amazonaws.com/convox-httpd-owdnefujkr:web.BCPSBDTVSVB\nRUNNING: docker push 132866487567.dkr.ecr.us-east-1.amazonaws.com/convox-httpd-owdnefujkr:web.BCPSBDTVSVB\nThe push refers to a repository [132866487567.dkr.ecr.us-east-1.amazonaws.com/convox-httpd-owdnefujkr] (len: 1)\n...\nweb.BCPSBDTVSVB: digest: sha256:943ca8f7dbbbfa99f761fae8f8f8d57fa99b6ac7b939ce787ec33735ec68edcb size: 23914\n\n$ convox releases\nID           CREATED       STATUS\nRQYRSVEXGLD  1 minute ago  active\nRVUEQWAOHTN  5 days ago    active\n\n$ convox ps\nID            NAME  RELEASE      SIZE  STARTED         COMMAND\n1bac0db9b7b5  web   RQYRSVEXGLD  256   25 seconds ago  httpd-foreground\n47542b8458a8  web   RVUEQWAOHTN  256   5 days ago      httpd-foreground\nd29eb239fda9  web   RQYRSVEXGLD  256   25 seconds ago  httpd-foreground\nef1d2825f528  web   RVUEQWAOHTN  256   1 day ago       httpd-foreground\n","shell","",[111,352,353,375,390,415,430,455,481,490,507,514,525,546,582,613,618,634,654,666,677,691,697,709,718,739,758,775,786,816,821,839,844,854,865,882,897,902,912,932,957,980,1000],{"__ignoreMap":350},[354,355,358,362,366,369,372],"span",{"class":356,"line":357},"line",1,[354,359,361],{"class":360},"s7eDp","$",[354,363,365],{"class":364},"sYBdl"," git",[354,367,368],{"class":364}," push",[354,370,371],{"class":364}," gitlab",[354,373,374],{"class":364}," master\n",[354,376,378,381,384,387],{"class":356,"line":377},2,[354,379,380],{"class":360},"Counting",[354,382,383],{"class":364}," objects:",[354,385,386],{"class":364}," 8,",[354,388,389],{"class":364}," done.\n",[354,391,393,396,399,402,405,408,412],{"class":356,"line":392},3,[354,394,395],{"class":360},"Delta",[354,397,398],{"class":364}," compression",[354,400,401],{"class":364}," using",[354,403,404],{"class":364}," up",[354,406,407],{"class":364}," to",[354,409,411],{"class":410},"sYu0t"," 4",[354,413,414],{"class":364}," threads.\n",[354,416,418,421,423,426],{"class":356,"line":417},4,[354,419,420],{"class":360},"Compressing",[354,422,383],{"class":364},[354,424,425],{"class":364}," 100%",[354,427,429],{"class":428},"sgsFI"," (8/8), done.\n",[354,431,433,436,438,440,443,447,450,453],{"class":356,"line":432},5,[354,434,435],{"class":360},"Writing",[354,437,383],{"class":364},[354,439,425],{"class":364},[354,441,442],{"class":428}," (8/8), 758 bytes ",[354,444,446],{"class":445},"sD7c4","|",[354,448,449],{"class":360}," 0",[354,451,452],{"class":364}," bytes/s,",[354,454,389],{"class":364},[354,456,458,461,464,467,470,473,476,478],{"class":356,"line":457},6,[354,459,460],{"class":360},"Total",[354,462,463],{"class":410}," 8",[354,465,466],{"class":428}," (delta ",[354,468,469],{"class":410},"7",[354,471,472],{"class":428},"), reused 0 (",[354,474,475],{"class":360},"delta",[354,477,449],{"class":410},[354,479,480],{"class":428},")\n",[354,482,484,487],{"class":356,"line":483},7,[354,485,486],{"class":360},"To",[354,488,489],{"class":364}," https://gitlab.com/nzoschke/httpd.git\n",[354,491,493,496,499,502,505],{"class":356,"line":492},8,[354,494,495],{"class":360},"   176d4d2..896d06b",[354,497,498],{"class":364},"  master",[354,500,501],{"class":428}," -",[354,503,504],{"class":445},">",[354,506,374],{"class":364},[354,508,510],{"class":356,"line":509},9,[354,511,513],{"emptyLinePlaceholder":512},true,"\n",[354,515,517,519,522],{"class":356,"line":516},10,[354,518,361],{"class":360},[354,520,521],{"class":364}," convox",[354,523,524],{"class":364}," builds\n",[354,526,528,531,534,537,540,543],{"class":356,"line":527},11,[354,529,530],{"class":360},"ID",[354,532,533],{"class":364},"           STATUS",[354,535,536],{"class":364},"    RELEASE",[354,538,539],{"class":364},"      STARTED",[354,541,542],{"class":364},"         ELAPSED",[354,544,545],{"class":364}," DESC\n",[354,547,549,552,555,558,561,564,567,570,573,576,579],{"class":356,"line":548},12,[354,550,551],{"class":360},"BCPSBDTVSVB",[354,553,554],{"class":364},"  complete",[354,556,557],{"class":364},"  RQYRSVEXGLD",[354,559,560],{"class":410},"  56",[354,562,563],{"class":364}," seconds",[354,565,566],{"class":364}," ago",[354,568,569],{"class":364},"  52s",[354,571,572],{"class":364},"      push",[354,574,575],{"class":364}," nzoschke/httpd",[354,577,578],{"class":364}," refs/heads/master",[354,580,581],{"class":364}," 896d06b2a72e702c3c2efe8fae9670bd19f5f255\n",[354,583,585,588,590,593,596,599,601,604,606,608,610],{"class":356,"line":584},13,[354,586,587],{"class":360},"BSZIBYZFDDU",[354,589,554],{"class":364},[354,591,592],{"class":364},"  RVUEQWAOHTN",[354,594,595],{"class":410},"  5",[354,597,598],{"class":364}," days",[354,600,566],{"class":364},[354,602,603],{"class":364},"      60s",[354,605,572],{"class":364},[354,607,575],{"class":364},[354,609,578],{"class":364},[354,611,612],{"class":364}," 176d4d22d0631c1223ea7ba31d80f837e4a24390\n",[354,614,616],{"class":356,"line":615},14,[354,617,513],{"emptyLinePlaceholder":512},[354,619,621,623,625,628,631],{"class":356,"line":620},15,[354,622,361],{"class":360},[354,624,521],{"class":364},[354,626,627],{"class":364}," builds",[354,629,630],{"class":364}," info",[354,632,633],{"class":364}," BCPSBDTVSVB\n",[354,635,637,640,642,645,648,651],{"class":356,"line":636},16,[354,638,639],{"class":360},"RUNNING:",[354,641,365],{"class":364},[354,643,644],{"class":364}," clone",[354,646,647],{"class":410}," --progress",[354,649,650],{"class":364}," git@gitlab.com:nzoschke/httpd.git",[354,652,653],{"class":364}," src\n",[354,655,657,659,661,664],{"class":356,"line":656},17,[354,658,639],{"class":360},[354,660,365],{"class":364},[354,662,663],{"class":364}," checkout",[354,665,581],{"class":364},[354,667,669,671,674],{"class":356,"line":668},18,[354,670,639],{"class":360},[354,672,673],{"class":364}," /usr/local/bin/git-restore-mtime",[354,675,676],{"class":364}," .\n",[354,678,680,682,685,688],{"class":356,"line":679},19,[354,681,639],{"class":360},[354,683,684],{"class":364}," docker",[354,686,687],{"class":364}," pull",[354,689,690],{"class":364}," httpd\n",[354,692,694],{"class":356,"line":693},20,[354,695,696],{"class":410},"...\n",[354,698,700,703,706],{"class":356,"line":699},21,[354,701,702],{"class":360},"cb604ab7d359:",[354,704,705],{"class":364}," Pull",[354,707,708],{"class":364}," complete\n",[354,710,712,715],{"class":356,"line":711},22,[354,713,714],{"class":360},"Digest:",[354,716,717],{"class":364}," sha256:3eae43b977887f7f660c640ba8477dc1af1626d757ff1a7ddba050418429f2f6\n",[354,719,721,724,727,730,733,736],{"class":356,"line":720},23,[354,722,723],{"class":360},"Status:",[354,725,726],{"class":364}," Downloaded",[354,728,729],{"class":364}," newer",[354,731,732],{"class":364}," image",[354,734,735],{"class":364}," for",[354,737,738],{"class":364}," httpd:latest\n",[354,740,742,744,746,749,752,755],{"class":356,"line":741},24,[354,743,639],{"class":360},[354,745,684],{"class":364},[354,747,748],{"class":364}," tag",[354,750,751],{"class":410}," -f",[354,753,754],{"class":364}," httpd",[354,756,757],{"class":364}," httpd/web\n",[354,759,761,763,765,767,769,772],{"class":356,"line":760},25,[354,762,639],{"class":360},[354,764,684],{"class":364},[354,766,748],{"class":364},[354,768,751],{"class":410},[354,770,771],{"class":364}," httpd/web",[354,773,774],{"class":364}," 132866487567.dkr.ecr.us-east-1.amazonaws.com/convox-httpd-owdnefujkr:web.BCPSBDTVSVB\n",[354,776,778,780,782,784],{"class":356,"line":777},26,[354,779,639],{"class":360},[354,781,684],{"class":364},[354,783,368],{"class":364},[354,785,774],{"class":364},[354,787,789,792,794,797,799,802,805,808,811,814],{"class":356,"line":788},27,[354,790,791],{"class":360},"The",[354,793,368],{"class":364},[354,795,796],{"class":364}," refers",[354,798,407],{"class":364},[354,800,801],{"class":364}," a",[354,803,804],{"class":364}," repository",[354,806,807],{"class":428}," [132866487567.dkr.ecr.us-east-1.amazonaws.com/convox-httpd-owdnefujkr] (",[354,809,810],{"class":360},"len:",[354,812,813],{"class":410}," 1",[354,815,480],{"class":428},[354,817,819],{"class":356,"line":818},28,[354,820,696],{"class":410},[354,822,824,827,830,833,836],{"class":356,"line":823},29,[354,825,826],{"class":360},"web.BCPSBDTVSVB:",[354,828,829],{"class":364}," digest:",[354,831,832],{"class":364}," sha256:943ca8f7dbbbfa99f761fae8f8f8d57fa99b6ac7b939ce787ec33735ec68edcb",[354,834,835],{"class":364}," size:",[354,837,838],{"class":410}," 23914\n",[354,840,842],{"class":356,"line":841},30,[354,843,513],{"emptyLinePlaceholder":512},[354,845,847,849,851],{"class":356,"line":846},31,[354,848,361],{"class":360},[354,850,521],{"class":364},[354,852,853],{"class":364}," releases\n",[354,855,857,859,862],{"class":356,"line":856},32,[354,858,530],{"class":360},[354,860,861],{"class":364},"           CREATED",[354,863,864],{"class":364},"       STATUS\n",[354,866,868,871,874,877,879],{"class":356,"line":867},33,[354,869,870],{"class":360},"RQYRSVEXGLD",[354,872,873],{"class":410},"  1",[354,875,876],{"class":364}," minute",[354,878,566],{"class":364},[354,880,881],{"class":364},"  active\n",[354,883,885,888,890,892,894],{"class":356,"line":884},34,[354,886,887],{"class":360},"RVUEQWAOHTN",[354,889,595],{"class":410},[354,891,598],{"class":364},[354,893,566],{"class":364},[354,895,896],{"class":364},"    active\n",[354,898,900],{"class":356,"line":899},35,[354,901,513],{"emptyLinePlaceholder":512},[354,903,905,907,909],{"class":356,"line":904},36,[354,906,361],{"class":360},[354,908,521],{"class":364},[354,910,911],{"class":364}," ps\n",[354,913,915,917,920,923,926,929],{"class":356,"line":914},37,[354,916,530],{"class":360},[354,918,919],{"class":364},"            NAME",[354,921,922],{"class":364},"  RELEASE",[354,924,925],{"class":364},"      SIZE",[354,927,928],{"class":364},"  STARTED",[354,930,931],{"class":364},"         COMMAND\n",[354,933,935,938,941,944,947,950,952,954],{"class":356,"line":934},38,[354,936,937],{"class":360},"1bac0db9b7b5",[354,939,940],{"class":364},"  web",[354,942,943],{"class":364},"   RQYRSVEXGLD",[354,945,946],{"class":410},"  256",[354,948,949],{"class":410},"   25",[354,951,563],{"class":364},[354,953,566],{"class":364},[354,955,956],{"class":364},"  httpd-foreground\n",[354,958,960,963,965,968,970,973,975,977],{"class":356,"line":959},39,[354,961,962],{"class":360},"47542b8458a8",[354,964,940],{"class":364},[354,966,967],{"class":364},"   RVUEQWAOHTN",[354,969,946],{"class":410},[354,971,972],{"class":410},"   5",[354,974,598],{"class":364},[354,976,566],{"class":364},[354,978,979],{"class":364},"      httpd-foreground\n",[354,981,983,986,988,990,992,994,996,998],{"class":356,"line":982},40,[354,984,985],{"class":360},"d29eb239fda9",[354,987,940],{"class":364},[354,989,943],{"class":364},[354,991,946],{"class":410},[354,993,949],{"class":410},[354,995,563],{"class":364},[354,997,566],{"class":364},[354,999,956],{"class":364},[354,1001,1003,1006,1008,1010,1012,1015,1018,1020],{"class":356,"line":1002},41,[354,1004,1005],{"class":360},"ef1d2825f528",[354,1007,940],{"class":364},[354,1009,967],{"class":364},[354,1011,946],{"class":410},[354,1013,1014],{"class":410},"   1",[354,1016,1017],{"class":364}," day",[354,1019,566],{"class":364},[354,1021,1022],{"class":364},"       httpd-foreground\n",[12,1024,1025,1026,1028,1029,1031],{},"You can see that release ",[111,1027,870],{}," is rolling out and replacing an older release ",[111,1030,887],{},". In a few more seconds the new code will be up and running. The build and zero-downtime deploy is fully automated by Convox and GitLab.",[12,1033,1034],{},"The final icing on the cake is that your whole team is notified about the new release on Slack:",[12,1036,1037,1039],{},[174,1038],{"alt":185,"src":186},[179,1040,185],{},[56,1042,1044],{"id":1043},"automated-testing","Automated Testing",[12,1046,1047],{},"I'm sure you noticed that we went directly from a code push to production. This demonstrates all the heavy lifting, and may be suitable for QA or staging workflows, but for anything going out to production we almost certainly want to run some tests too.",[12,1049,1050,1051,1055],{},"This is possible to set up with a few changes. ",[15,1052,1054],{"href":1053},"/solutions/continuous-integration/","GitLab CI"," is an excellent tool and service for automating tests.",[12,1057,1058,1059,1062,1063,1066],{},"You can tell GitLab to deploy to Convox by setting ",[111,1060,1061],{},"CONVOX_PASSWORD"," as a User-defined variable, then adding a ",[111,1064,1065],{},".gitlab-ci.yml"," file similar to:",[345,1068,1072],{"className":1069,"code":1070,"language":1071,"meta":350,"style":350},"language-yaml shiki shiki-themes github-light","test:\n  script:\n  - make test\n\nproduction:\n  type: deploy\n  script:\n  - curl -Ls https://install.convox.com/linux.zip > convox.zip\n  - unzip convox.zip\n  - convox login\n  - convox switch org/rack\n  - convox deploy --app app\n  only:\n  - tags\n\n","yaml",[111,1073,1074,1083,1090,1098,1102,1109,1120,1126,1133,1140,1147,1154,1161,1168],{"__ignoreMap":350},[354,1075,1076,1080],{"class":356,"line":357},[354,1077,1079],{"class":1078},"shJU0","test",[354,1081,1082],{"class":428},":\n",[354,1084,1085,1088],{"class":356,"line":377},[354,1086,1087],{"class":1078},"  script",[354,1089,1082],{"class":428},[354,1091,1092,1095],{"class":356,"line":392},[354,1093,1094],{"class":428},"  - ",[354,1096,1097],{"class":364},"make test\n",[354,1099,1100],{"class":356,"line":417},[354,1101,513],{"emptyLinePlaceholder":512},[354,1103,1104,1107],{"class":356,"line":432},[354,1105,1106],{"class":1078},"production",[354,1108,1082],{"class":428},[354,1110,1111,1114,1117],{"class":356,"line":457},[354,1112,1113],{"class":1078},"  type",[354,1115,1116],{"class":428},": ",[354,1118,1119],{"class":364},"deploy\n",[354,1121,1122,1124],{"class":356,"line":483},[354,1123,1087],{"class":1078},[354,1125,1082],{"class":428},[354,1127,1128,1130],{"class":356,"line":492},[354,1129,1094],{"class":428},[354,1131,1132],{"class":364},"curl -Ls https://install.convox.com/linux.zip > convox.zip\n",[354,1134,1135,1137],{"class":356,"line":509},[354,1136,1094],{"class":428},[354,1138,1139],{"class":364},"unzip convox.zip\n",[354,1141,1142,1144],{"class":356,"line":516},[354,1143,1094],{"class":428},[354,1145,1146],{"class":364},"convox login\n",[354,1148,1149,1151],{"class":356,"line":527},[354,1150,1094],{"class":428},[354,1152,1153],{"class":364},"convox switch org/rack\n",[354,1155,1156,1158],{"class":356,"line":548},[354,1157,1094],{"class":428},[354,1159,1160],{"class":364},"convox deploy --app app\n",[354,1162,1163,1166],{"class":356,"line":584},[354,1164,1165],{"class":1078},"  only",[354,1167,1082],{"class":428},[354,1169,1170,1172],{"class":356,"line":615},[354,1171,1094],{"class":428},[354,1173,1174],{"class":364},"tags\n",[12,1176,96,1177,1182,1183,1188],{},[15,1178,1181],{"href":1179,"rel":1180},"https://docs.gitlab.com/ci/variables/",[],"CI Variables"," doc and ",[15,1184,1187],{"href":1185,"rel":1186},"https://docs.gitlab.com/ci/examples/",[],"GitLab CI Examples"," doc for more information.",[70,1190,1192],{"id":1191},"open-source-evolution","Open Source Evolution",[12,1194,1195],{},"Both GitLab and Convox are always working hard to improve APIs, integrations and tools for automating continuous delivery as open-source projects.",[12,1197,1198,1199,1204,1205,1210],{},"We encourage you to participate in the open-source projects future enhancements in this space such as a more formal ",[15,1200,1203],{"href":1201,"rel":1202},"https://gitlab.com/gitlab-org/gitlab-ce/issues/3286#note_4141009",[],"GitLab Deploy"," enhancement and the ",[15,1206,1209],{"href":1207,"rel":1208},"https://github.com/convox/rack/milestones/Build%20/%20Deploy%20/%20Release%20Pipeline",[],"Convox Build / Deploy / Release Pipeline"," milestone.",[70,1212,1214],{"id":1213},"conclusion","Conclusion",[12,1216,1217],{},"As you can tell, there are a lot of details to coordinate between your team pushing code and delivering it as a production service in the cloud.",[12,1219,1220],{},"GitLab and Convox understand how important Continuous Delivery is and have gone to great lengths to make this process available to everyone with free and open-source software.",[70,1222,1224],{"id":1223},"about-guest-author-noah-zoschke","About guest author Noah Zoschke",[12,1226,1227,1232],{},[15,1228,1231],{"href":1229,"rel":1230},"https://medium.com/@nzoschke",[],"Noah"," is CTO at Convox. Previously he was Platform Architect at Heroku. He believes that the cloud should be easy to use, secure, reliable and cost effective for teams and systems of all sizes. He believes that simple, open-source tools will unlock this true utility of the cloud.",[1234,1235,1236],"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 .sgsFI, html code.shiki .sgsFI{--shiki-default:#24292E}html pre.shiki code .sD7c4, html code.shiki .sD7c4{--shiki-default:#D73A49}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 .shJU0, html code.shiki .shJU0{--shiki-default:#22863A}",{"title":350,"searchDepth":377,"depth":377,"links":1238},[1239,1240,1241,1249,1250,1251],{"id":58,"depth":392,"text":59},{"id":72,"depth":377,"text":73},{"id":105,"depth":377,"text":106,"children":1242},[1243,1244,1245,1246,1247,1248],{"id":191,"depth":392,"text":192},{"id":250,"depth":392,"text":251},{"id":282,"depth":392,"text":283},{"id":306,"depth":392,"text":307},{"id":336,"depth":392,"text":337},{"id":1043,"depth":392,"text":1044},{"id":1191,"depth":377,"text":1192},{"id":1213,"depth":377,"text":1214},{"id":1223,"depth":377,"text":1224},"open-source","2016-06-09","This tutorial will show you how to use GitLab and Convox together to ship software quickly and reliably.","md",null,false,"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749684833/Blog/Hero%20Images/gitlab-convox-cover.jpg",{"excerpt":1260},{"type":9,"value":1261},[1262,1267,1271],[12,1263,1264,20],{},[15,1265,19],{"href":17,"rel":1266},[],[12,1268,23,1269,28],{},[15,1270,27],{"href":26},[12,1272,1273,35,1275,41,1278,47,1281,51],{},[32,1274,34],{},[15,1276,40],{"href":38,"rel":1277},[],[15,1279,46],{"href":44,"rel":1280},[],[15,1282,19],{"href":17,"rel":1283},[],"/en-us/blog/continuous-delivery-with-gitlab-and-convox",{"title":5,"description":1254,"ogTitle":5,"ogDescription":1254,"noIndex":1257,"ogImage":1258,"ogUrl":1286,"ogSiteName":1287,"ogType":1288,"canonicalUrls":1286},"https://about.gitlab.com/blog/continuous-delivery-with-gitlab-and-convox","https://about.gitlab.com","article","continuous-delivery-with-gitlab-and-convox","en-us/blog/continuous-delivery-with-gitlab-and-convox","BlogPost","1a8LuK8YnU8Khw5xZUOncjKcBIVF41k855VvsxON5Vw",{"logo":1294,"freeTrial":1298,"sales":1303,"login":1308,"items":1313,"search":1639,"minimal":1670,"duo":1689,"switchNav":1698,"pricingDeployment":1709},{"config":1295},{"href":26,"dataGaName":1296,"dataGaLocation":1297},"gitlab logo","header",{"text":1299,"config":1300},"Get free trial",{"href":1301,"dataGaName":1302,"dataGaLocation":1297},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":1304,"config":1305},"Request a demo",{"href":1306,"dataGaName":1307,"dataGaLocation":1297},"/sales/?contact-topic=request-demo","sales",{"text":1309,"config":1310},"Sign in",{"href":1311,"dataGaName":1312,"dataGaLocation":1297},"https://gitlab.com/users/sign_in/","sign in",[1314,1343,1442,1447,1561,1617],{"text":1315,"config":1316,"menu":1318},"Platform",{"dataNavLevelOne":1317},"platform",{"type":1319,"columns":1320},"cards",[1321,1327,1335],{"title":1315,"description":1322,"link":1323},"The intelligent orchestration platform for DevSecOps",{"text":1324,"config":1325},"Explore our Platform",{"href":1326,"dataGaName":1317,"dataGaLocation":1297},"/platform/",{"title":1328,"description":1329,"link":1330},"GitLab Duo Agent Platform","Agentic AI for the entire software lifecycle",{"text":1331,"config":1332},"Meet GitLab Duo",{"href":1333,"dataGaName":1334,"dataGaLocation":1297},"/gitlab-duo-agent-platform/","gitlab duo agent platform",{"title":1336,"description":1337,"link":1338},"Why GitLab","See the top reasons enterprises choose GitLab",{"text":1339,"config":1340},"Learn more",{"href":1341,"dataGaName":1342,"dataGaLocation":1297},"/why-gitlab/","why gitlab",{"text":1344,"left":512,"config":1345,"menu":1347},"Product",{"dataNavLevelOne":1346},"solutions",{"type":1348,"link":1349,"columns":1353,"feature":1421},"lists",{"text":1350,"config":1351},"View all Solutions",{"href":1352,"dataGaName":1346,"dataGaLocation":1297},"/solutions/",[1354,1377,1400],{"title":1355,"description":1356,"link":1357,"items":1362},"Automation","CI/CD and automation to accelerate deployment",{"config":1358},{"icon":1359,"href":1360,"dataGaName":1361,"dataGaLocation":1297},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[1363,1366,1369,1373],{"text":1364,"config":1365},"CI/CD",{"href":1053,"dataGaLocation":1297,"dataGaName":1364},{"text":1328,"config":1367},{"href":1333,"dataGaLocation":1297,"dataGaName":1368},"gitlab duo agent platform - product menu",{"text":1370,"config":1371},"Source Code Management",{"href":1372,"dataGaLocation":1297,"dataGaName":1370},"/solutions/source-code-management/",{"text":1374,"config":1375},"Automated Software Delivery",{"href":1360,"dataGaLocation":1297,"dataGaName":1376},"Automated software delivery",{"title":1378,"description":1379,"link":1380,"items":1385},"Security","Deliver code faster without compromising security",{"config":1381},{"href":1382,"dataGaName":1383,"dataGaLocation":1297,"icon":1384},"/solutions/application-security-testing/","security and compliance","ShieldCheckLight",[1386,1390,1395],{"text":1387,"config":1388},"Application Security Testing",{"href":1382,"dataGaName":1389,"dataGaLocation":1297},"Application security testing",{"text":1391,"config":1392},"Software Supply Chain Security",{"href":1393,"dataGaLocation":1297,"dataGaName":1394},"/solutions/supply-chain/","Software supply chain security",{"text":1396,"config":1397},"Software Compliance",{"href":1398,"dataGaName":1399,"dataGaLocation":1297},"/solutions/software-compliance/","software compliance",{"title":1401,"link":1402,"items":1407},"Measurement",{"config":1403},{"icon":1404,"href":1405,"dataGaName":1406,"dataGaLocation":1297},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[1408,1412,1416],{"text":1409,"config":1410},"Visibility & Measurement",{"href":1405,"dataGaLocation":1297,"dataGaName":1411},"Visibility and Measurement",{"text":1413,"config":1414},"Value Stream Management",{"href":1415,"dataGaLocation":1297,"dataGaName":1413},"/solutions/value-stream-management/",{"text":1417,"config":1418},"Analytics & Insights",{"href":1419,"dataGaLocation":1297,"dataGaName":1420},"/solutions/analytics-and-insights/","Analytics and insights",{"title":1422,"type":1348,"items":1423},"GitLab for",[1424,1430,1436],{"text":1425,"config":1426},"Enterprise",{"icon":1427,"href":1428,"dataGaLocation":1297,"dataGaName":1429},"Building","/enterprise/","enterprise",{"text":1431,"config":1432},"Small Business",{"icon":1433,"href":1434,"dataGaLocation":1297,"dataGaName":1435},"Work","/small-business/","small business",{"text":1437,"config":1438},"Public Sector",{"icon":1439,"href":1440,"dataGaLocation":1297,"dataGaName":1441},"Organization","/solutions/public-sector/","public sector",{"text":1443,"config":1444},"Pricing",{"href":1445,"dataGaName":1446,"dataGaLocation":1297,"dataNavLevelOne":1446},"/pricing/","pricing",{"text":1448,"config":1449,"menu":1451},"Resources",{"dataNavLevelOne":1450},"resources",{"type":1348,"link":1452,"columns":1456,"feature":1550},{"text":1453,"config":1454},"View all resources",{"href":1455,"dataGaName":1450,"dataGaLocation":1297},"/resources/",[1457,1490,1517],{"title":1458,"items":1459},"Getting started",[1460,1465,1470,1475,1480,1485],{"text":1461,"config":1462},"Install",{"href":1463,"dataGaName":1464,"dataGaLocation":1297},"/install/","install",{"text":1466,"config":1467},"Quick start guides",{"href":1468,"dataGaName":1469,"dataGaLocation":1297},"/get-started/","quick setup checklists",{"text":1471,"config":1472},"Learn",{"href":1473,"dataGaLocation":1297,"dataGaName":1474},"https://university.gitlab.com/","learn",{"text":1476,"config":1477},"Product documentation",{"href":1478,"dataGaName":1479,"dataGaLocation":1297},"https://docs.gitlab.com/","product documentation",{"text":1481,"config":1482},"Best practice videos",{"href":1483,"dataGaName":1484,"dataGaLocation":1297},"/getting-started-videos/","best practice videos",{"text":1486,"config":1487},"Integrations",{"href":1488,"dataGaName":1489,"dataGaLocation":1297},"/integrations/","integrations",{"title":1491,"items":1492},"Discover",[1493,1498,1503,1508,1512],{"text":1494,"config":1495},"Customer success stories",{"href":1496,"dataGaName":1497,"dataGaLocation":1297},"/customers/","customer success stories",{"text":1499,"config":1500},"Blog",{"href":1501,"dataGaName":1502,"dataGaLocation":1297},"/blog/","blog",{"text":1504,"config":1505},"Demo Hub",{"href":1506,"dataGaName":1507,"dataGaLocation":1297},"/demo-hub/","demo hub",{"text":1509,"config":1510},"The Source",{"href":1511,"dataGaName":1502,"dataGaLocation":1297},"/the-source/",{"text":1513,"config":1514},"Remote",{"href":1515,"dataGaName":1516,"dataGaLocation":1297},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"title":1518,"items":1519},"Connect",[1520,1525,1530,1535,1540,1545],{"text":1521,"config":1522},"GitLab Services",{"href":1523,"dataGaName":1524,"dataGaLocation":1297},"/services/","services",{"text":1526,"config":1527},"Contribute",{"href":1528,"dataGaName":1529,"dataGaLocation":1297},"https://contributors.gitlab.com","contribute",{"text":1531,"config":1532},"Community",{"href":1533,"dataGaName":1534,"dataGaLocation":1297},"/community/","community",{"text":1536,"config":1537},"Forum",{"href":1538,"dataGaName":1539,"dataGaLocation":1297},"https://forum.gitlab.com/","forum",{"text":1541,"config":1542},"Events",{"href":1543,"dataGaName":1544,"dataGaLocation":1297},"/events/","events",{"text":1546,"config":1547},"Partners",{"href":1548,"dataGaName":1549,"dataGaLocation":1297},"/partners/","partners",{"config":1551,"title":1554,"text":1555,"link":1556},{"background":1552,"textColor":1553},"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":1557,"config":1558},"Read the latest",{"href":1559,"dataGaName":1560,"dataGaLocation":1297},"/whats-new/","whats new",{"text":1562,"config":1563,"menu":1565},"Company",{"dataNavLevelOne":1564},"company",{"type":1348,"columns":1566},[1567],{"items":1568},[1569,1574,1580,1582,1587,1592,1597,1602,1607,1612],{"text":1570,"config":1571},"About",{"href":1572,"dataGaName":1573,"dataGaLocation":1297},"/company/","about",{"text":1575,"config":1576,"footerGa":1579},"Jobs",{"href":1577,"dataGaName":1578,"dataGaLocation":1297},"/jobs/","jobs",{"dataGaName":1578},{"text":1541,"config":1581},{"href":1543,"dataGaName":1544,"dataGaLocation":1297},{"text":1583,"config":1584},"Leadership",{"href":1585,"dataGaName":1586,"dataGaLocation":1297},"/company/team/e-group/","leadership",{"text":1588,"config":1589},"Handbook",{"href":1590,"dataGaName":1591,"dataGaLocation":1297},"https://handbook.gitlab.com/","handbook",{"text":1593,"config":1594},"Investor relations",{"href":1595,"dataGaName":1596,"dataGaLocation":1297},"https://ir.gitlab.com/overview/default.aspx","investor relations",{"text":1598,"config":1599},"Trust Center",{"href":1600,"dataGaName":1601,"dataGaLocation":1297},"/security/","trust center",{"text":1603,"config":1604},"AI Transparency Center",{"href":1605,"dataGaName":1606,"dataGaLocation":1297},"/ai-transparency-center/","ai transparency center",{"text":1608,"config":1609},"Newsletter",{"href":1610,"dataGaName":1611,"dataGaLocation":1297},"/company/contact/#contact-forms","newsletter",{"text":1613,"config":1614},"Press",{"href":1615,"dataGaName":1616,"dataGaLocation":1297},"/press/","press",{"text":1618,"config":1619,"menu":1620},"Contact us",{"dataNavLevelOne":1564},{"type":1348,"columns":1621},[1622],{"items":1623},[1624,1629,1634],{"text":1625,"config":1626},"Talk to sales",{"href":1627,"dataGaName":1628,"dataGaLocation":1297},"/sales/","talk to sales",{"text":1630,"config":1631},"Support portal",{"href":1632,"dataGaName":1633,"dataGaLocation":1297},"https://support.gitlab.com/hc/en-us","support portal",{"text":1635,"config":1636},"Customer portal",{"href":1637,"dataGaName":1638,"dataGaLocation":1297},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":1640,"login":1641,"suggestions":1648},"Close",{"text":1642,"link":1643},"To search repositories and projects, login to",{"text":1644,"config":1645},"gitlab.com",{"href":1311,"dataGaName":1646,"dataGaLocation":1647},"search login","search",{"text":1649,"default":1650},"Suggestions",[1651,1653,1657,1659,1663,1667],{"text":1328,"config":1652},{"href":1333,"dataGaName":1328,"dataGaLocation":1647},{"text":1654,"config":1655},"Code Suggestions (AI)",{"href":1656,"dataGaName":1654,"dataGaLocation":1647},"/solutions/code-suggestions/",{"text":1364,"config":1658},{"href":1053,"dataGaName":1364,"dataGaLocation":1647},{"text":1660,"config":1661},"GitLab on AWS",{"href":1662,"dataGaName":1660,"dataGaLocation":1647},"/partners/technology-partners/aws/",{"text":1664,"config":1665},"GitLab on Google Cloud",{"href":1666,"dataGaName":1664,"dataGaLocation":1647},"/partners/technology-partners/google-cloud-platform/",{"text":1668,"config":1669},"Why GitLab?",{"href":1341,"dataGaName":1668,"dataGaLocation":1647},{"freeTrial":1671,"mobileIcon":1676,"desktopIcon":1681,"secondaryButton":1684},{"text":1672,"config":1673},"Start free trial",{"href":1674,"dataGaName":1302,"dataGaLocation":1675},"https://gitlab.com/-/trials/new/","nav",{"altText":1677,"config":1678},"Gitlab Icon",{"src":1679,"dataGaName":1680,"dataGaLocation":1675},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":1677,"config":1682},{"src":1683,"dataGaName":1680,"dataGaLocation":1675},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":1685,"config":1686},"Get Started",{"href":1687,"dataGaName":1688,"dataGaLocation":1675},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/get-started/","get started",{"freeTrial":1690,"mobileIcon":1694,"desktopIcon":1696},{"text":1691,"config":1692},"Learn more about GitLab Duo",{"href":1333,"dataGaName":1693,"dataGaLocation":1675},"gitlab duo",{"altText":1677,"config":1695},{"src":1679,"dataGaName":1680,"dataGaLocation":1675},{"altText":1677,"config":1697},{"src":1683,"dataGaName":1680,"dataGaLocation":1675},{"button":1699,"mobileIcon":1704,"desktopIcon":1706},{"text":1700,"config":1701},"/switch",{"href":1702,"dataGaName":1703,"dataGaLocation":1675},"#contact","switch",{"altText":1677,"config":1705},{"src":1679,"dataGaName":1680,"dataGaLocation":1675},{"altText":1677,"config":1707},{"src":1708,"dataGaName":1680,"dataGaLocation":1675},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1773335277/ohhpiuoxoldryzrnhfrh.png",{"freeTrial":1710,"mobileIcon":1715,"desktopIcon":1717},{"text":1711,"config":1712},"Back to pricing",{"href":1445,"dataGaName":1713,"dataGaLocation":1675,"icon":1714},"back to pricing","GoBack",{"altText":1677,"config":1716},{"src":1679,"dataGaName":1680,"dataGaLocation":1675},{"altText":1677,"config":1718},{"src":1683,"dataGaName":1680,"dataGaLocation":1675},{"title":1720,"titleMobile":1721,"button":1722,"config":1727},"Duo Agent Platform delivers 400% ROI, per new Forrester Consulting study.","400% ROI: Forrester TEI for GitLab Duo",{"text":1339,"config":1723},{"href":1724,"dataGaName":1725,"dataGaLocation":1726},"https://about.gitlab.com/blog/gitlab-duo-agent-platform-delivers-400-percent-roi/","forrester-tei-dap-banner","global-banner",{"layout":1728,"disabled":1257},"release",{"data":1730},{"text":1731,"source":1732,"edit":1738,"contribute":1743,"config":1748,"items":1753,"minimal":1963},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":1733,"config":1734},"View page source",{"href":1735,"dataGaName":1736,"dataGaLocation":1737},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":1739,"config":1740},"Edit this page",{"href":1741,"dataGaName":1742,"dataGaLocation":1737},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":1744,"config":1745},"Please contribute",{"href":1746,"dataGaName":1747,"dataGaLocation":1737},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":1749,"facebook":1750,"youtube":1751,"linkedin":1752},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[1754,1801,1855,1899,1931],{"title":1443,"links":1755,"subMenu":1770},[1756,1760,1765],{"text":1757,"config":1758},"View plans",{"href":1445,"dataGaName":1759,"dataGaLocation":1737},"view plans",{"text":1761,"config":1762},"Why Premium?",{"href":1763,"dataGaName":1764,"dataGaLocation":1737},"/pricing/premium/","why premium",{"text":1766,"config":1767},"Why Ultimate?",{"href":1768,"dataGaName":1769,"dataGaLocation":1737},"/pricing/ultimate/","why ultimate",[1771],{"title":1772,"links":1773},"Contact Us",[1774,1777,1779,1781,1786,1791,1796],{"text":1775,"config":1776},"Contact sales",{"href":1627,"dataGaName":1307,"dataGaLocation":1737},{"text":1630,"config":1778},{"href":1632,"dataGaName":1633,"dataGaLocation":1737},{"text":1635,"config":1780},{"href":1637,"dataGaName":1638,"dataGaLocation":1737},{"text":1782,"config":1783},"Status",{"href":1784,"dataGaName":1785,"dataGaLocation":1737},"https://status.gitlab.com/","status",{"text":1787,"config":1788},"Terms of use",{"href":1789,"dataGaName":1790,"dataGaLocation":1737},"/terms/","terms of use",{"text":1792,"config":1793},"Privacy statement",{"href":1794,"dataGaName":1795,"dataGaLocation":1737},"/privacy/","privacy statement",{"text":1797,"config":1798},"Cookie preferences",{"dataGaName":1799,"dataGaLocation":1737,"id":1800,"isOneTrustButton":512},"cookie preferences","ot-sdk-btn",{"title":1344,"links":1802,"subMenu":1811},[1803,1807],{"text":1804,"config":1805},"DevSecOps platform",{"href":1326,"dataGaName":1806,"dataGaLocation":1737},"devsecops platform",{"text":1808,"config":1809},"AI-Assisted Development",{"href":1333,"dataGaName":1810,"dataGaLocation":1737},"ai-assisted development",[1812],{"title":1813,"links":1814},"Topics",[1815,1820,1825,1830,1835,1840,1845,1850],{"text":1816,"config":1817},"CICD",{"href":1818,"dataGaName":1819,"dataGaLocation":1737},"/topics/ci-cd/","cicd",{"text":1821,"config":1822},"GitOps",{"href":1823,"dataGaName":1824,"dataGaLocation":1737},"/topics/gitops/","gitops",{"text":1826,"config":1827},"DevOps",{"href":1828,"dataGaName":1829,"dataGaLocation":1737},"/topics/devops/","devops",{"text":1831,"config":1832},"Version Control",{"href":1833,"dataGaName":1834,"dataGaLocation":1737},"/topics/version-control/","version control",{"text":1836,"config":1837},"DevSecOps",{"href":1838,"dataGaName":1839,"dataGaLocation":1737},"/topics/devsecops/","devsecops",{"text":1841,"config":1842},"Cloud Native",{"href":1843,"dataGaName":1844,"dataGaLocation":1737},"/topics/cloud-native/","cloud native",{"text":1846,"config":1847},"AI for Coding",{"href":1848,"dataGaName":1849,"dataGaLocation":1737},"/topics/devops/ai-for-coding/","ai for coding",{"text":1851,"config":1852},"Agentic AI",{"href":1853,"dataGaName":1854,"dataGaLocation":1737},"/topics/agentic-ai/","agentic ai",{"title":1856,"links":1857},"Solutions",[1858,1860,1862,1867,1871,1874,1878,1881,1883,1886,1889,1894],{"text":1387,"config":1859},{"href":1382,"dataGaName":1387,"dataGaLocation":1737},{"text":1376,"config":1861},{"href":1360,"dataGaName":1361,"dataGaLocation":1737},{"text":1863,"config":1864},"Agile development",{"href":1865,"dataGaName":1866,"dataGaLocation":1737},"/solutions/agile-delivery/","agile delivery",{"text":1868,"config":1869},"SCM",{"href":1372,"dataGaName":1870,"dataGaLocation":1737},"source code management",{"text":1816,"config":1872},{"href":1053,"dataGaName":1873,"dataGaLocation":1737},"continuous integration & delivery",{"text":1875,"config":1876},"Value stream management",{"href":1415,"dataGaName":1877,"dataGaLocation":1737},"value stream management",{"text":1821,"config":1879},{"href":1880,"dataGaName":1824,"dataGaLocation":1737},"/solutions/gitops/",{"text":1425,"config":1882},{"href":1428,"dataGaName":1429,"dataGaLocation":1737},{"text":1884,"config":1885},"Small business",{"href":1434,"dataGaName":1435,"dataGaLocation":1737},{"text":1887,"config":1888},"Public sector",{"href":1440,"dataGaName":1441,"dataGaLocation":1737},{"text":1890,"config":1891},"Education",{"href":1892,"dataGaName":1893,"dataGaLocation":1737},"/solutions/education/","education",{"text":1895,"config":1896},"Financial services",{"href":1897,"dataGaName":1898,"dataGaLocation":1737},"/solutions/finance/","financial services",{"title":1448,"links":1900},[1901,1903,1905,1907,1910,1912,1915,1917,1919,1921,1923,1925,1927,1929],{"text":1461,"config":1902},{"href":1463,"dataGaName":1464,"dataGaLocation":1737},{"text":1466,"config":1904},{"href":1468,"dataGaName":1469,"dataGaLocation":1737},{"text":1471,"config":1906},{"href":1473,"dataGaName":1474,"dataGaLocation":1737},{"text":1476,"config":1908},{"href":1478,"dataGaName":1909,"dataGaLocation":1737},"docs",{"text":1499,"config":1911},{"href":1501,"dataGaName":1502,"dataGaLocation":1737},{"text":1913,"config":1914},"What's new",{"href":1559,"dataGaName":1560,"dataGaLocation":1737},{"text":1494,"config":1916},{"href":1496,"dataGaName":1497,"dataGaLocation":1737},{"text":1513,"config":1918},{"href":1515,"dataGaName":1516,"dataGaLocation":1737},{"text":1521,"config":1920},{"href":1523,"dataGaName":1524,"dataGaLocation":1737},{"text":1526,"config":1922},{"href":1528,"dataGaName":1529,"dataGaLocation":1737},{"text":1531,"config":1924},{"href":1533,"dataGaName":1534,"dataGaLocation":1737},{"text":1536,"config":1926},{"href":1538,"dataGaName":1539,"dataGaLocation":1737},{"text":1541,"config":1928},{"href":1543,"dataGaName":1544,"dataGaLocation":1737},{"text":1546,"config":1930},{"href":1548,"dataGaName":1549,"dataGaLocation":1737},{"title":1562,"links":1932},[1933,1935,1937,1939,1941,1943,1947,1952,1954,1956,1958],{"text":1570,"config":1934},{"href":1572,"dataGaName":1564,"dataGaLocation":1737},{"text":1575,"config":1936},{"href":1577,"dataGaName":1578,"dataGaLocation":1737},{"text":1583,"config":1938},{"href":1585,"dataGaName":1586,"dataGaLocation":1737},{"text":1588,"config":1940},{"href":1590,"dataGaName":1591,"dataGaLocation":1737},{"text":1593,"config":1942},{"href":1595,"dataGaName":1596,"dataGaLocation":1737},{"text":1944,"config":1945},"Sustainability",{"href":1946,"dataGaName":1944,"dataGaLocation":1737},"/sustainability/",{"text":1948,"config":1949},"Diversity, inclusion and belonging (DIB)",{"href":1950,"dataGaName":1951,"dataGaLocation":1737},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":1598,"config":1953},{"href":1600,"dataGaName":1601,"dataGaLocation":1737},{"text":1608,"config":1955},{"href":1610,"dataGaName":1611,"dataGaLocation":1737},{"text":1613,"config":1957},{"href":1615,"dataGaName":1616,"dataGaLocation":1737},{"text":1959,"config":1960},"Modern Slavery Transparency Statement",{"href":1961,"dataGaName":1962,"dataGaLocation":1737},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"items":1964},[1965,1968,1971],{"text":1966,"config":1967},"Terms",{"href":1789,"dataGaName":1790,"dataGaLocation":1737},{"text":1969,"config":1970},"Cookies",{"dataGaName":1799,"dataGaLocation":1737,"id":1800,"isOneTrustButton":512},{"text":1972,"config":1973},"Privacy",{"href":1794,"dataGaName":1795,"dataGaLocation":1737},[1975],{"id":1976,"title":7,"body":1256,"config":1977,"content":1979,"description":1256,"extension":1983,"meta":1984,"navigation":512,"path":1985,"seo":1986,"stem":1987,"__hash__":1988},"blogAuthors/en-us/blog/authors/noah-zoschke.yml",{"template":1978},"BlogAuthor",{"name":7,"config":1980},{"headshot":1981,"ctfId":1982},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749659488/Blog/Author%20Headshots/gitlab-logo-extra-whitespace.png","Noah-Zoschke","yml",{},"/en-us/blog/authors/noah-zoschke",{},"en-us/blog/authors/noah-zoschke","FgRDr89QzUNgig1BbKwD9mIMQYZCo9r28cE3sqSj_z4",[1990,1998,2006],{"title":1991,"description":1992,"heroImage":1993,"category":1252,"date":1994,"authors":1995,"slug":1997,"externalUrl":1256},"What's new in Git 2.55.0?","Learn about the new features and changes in Git 2.55, including a new git-history(1) fixup command, an fsmonitor daemon for Linux, pushing to remote groups, and more.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782732487/ztwgrvlolpifo01vj8qc.png","2026-06-29",[1996],"Toon Claes","whats-new-in-git-2-55-0",{"title":1999,"description":2000,"heroImage":2001,"category":1252,"date":2002,"authors":2003,"slug":2005,"externalUrl":1256},"GitLab AI Hackathon 2026: Meet the winners","Nearly 7,000 developers built 600+ AI agents and flows on GitLab Duo Agent Platform. Find out who won and what they created.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1776457632/llddiylsgwuze0u1rjks.png","2026-04-22",[2004],"Nick Veenhof","gitlab-ai-hackathon-2026-meet-the-winners",{"title":2007,"description":2008,"heroImage":2009,"category":1252,"date":2010,"authors":2011,"slug":2013,"externalUrl":1256},"What’s new in Git 2.54.0?","Learn about release contributions, including new repository maintenance, a new command to edit commit history, a replacement for git-sizer(1), and more.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782734716/ztwgrvlolpifo01vj8qc.png","2026-04-20",[2012],"Patrick Steinhardt","whats-new-in-git-2-54-0",{"promotions":2015},[2016,2030,2042,2054],{"id":2017,"categories":2018,"header":2020,"text":2021,"button":2022,"image":2027},"ai-modernization",[2019],"ai","Is AI achieving its promise at scale?","Quiz will take 5 minutes or less",{"text":2023,"config":2024},"Get your AI maturity score",{"href":2025,"dataGaName":2026,"dataGaLocation":1502},"/assessments/ai-modernization-assessment/","modernization assessment",{"config":2028},{"src":2029},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/qix0m7kwnd8x2fh1zq49.png",{"id":2031,"categories":2032,"header":2034,"text":2021,"button":2035,"image":2039},"devops-modernization",[2033,1839],"product","Are you just managing tools or shipping innovation?",{"text":2036,"config":2037},"Get your DevOps maturity score",{"href":2038,"dataGaName":2026,"dataGaLocation":1502},"/assessments/devops-modernization-assessment/",{"config":2040},{"src":2041},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138785/eg818fmakweyuznttgid.png",{"id":2043,"categories":2044,"header":2046,"text":2021,"button":2047,"image":2051},"security-modernization",[2045],"security","Are you trading speed for security?",{"text":2048,"config":2049},"Get your security maturity score",{"href":2050,"dataGaName":2026,"dataGaLocation":1502},"/assessments/security-modernization-assessment/",{"config":2052},{"src":2053},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/p4pbqd9nnjejg5ds6mdk.png",{"id":2055,"paths":2056,"header":2059,"text":2060,"button":2061,"image":2066},"github-azure-migration",[2057,2058],"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":2062,"config":2063},"See how GitLab compares to GitHub",{"href":2064,"dataGaName":2065,"dataGaLocation":1502},"/compare/gitlab-vs-github/github-azure-migration/","github azure migration",{"config":2067},{"src":2041},{"header":2069,"blurb":2070,"button":2071,"secondaryButton":2076},"Start building faster today","See what your team can do with the intelligent orchestration platform for DevSecOps.\n",{"text":2072,"config":2073},"Get your free trial",{"href":2074,"dataGaName":1302,"dataGaLocation":2075},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":1775,"config":2077},{"href":1627,"dataGaName":1307,"dataGaLocation":2075},1786803767614]