[{"data":1,"prerenderedAt":2761},["ShallowReactive",2],{"/de-de/blog/from-code-to-production-a-guide-to-continuous-deployment-with-gitlab":3,"navigation-de-de":1969,"banner-de-de":2400,"footer-de-de":2407,"blog-post-authors-de-de-Benjamin Skierlak|James Wormwell":2648,"blog-related-posts-de-de-from-code-to-production-a-guide-to-continuous-deployment-with-gitlab":2675,"blog-promotions-de-de":2698,"next-steps-de-de":2751},{"id":4,"title":5,"authors":6,"body":9,"category":1945,"date":1946,"description":1947,"extension":1948,"externalUrl":1949,"faq":1949,"featured":1950,"heroImage":1951,"meta":1952,"navigation":716,"path":1953,"seo":1954,"slug":1959,"stem":1960,"tags":1961,"template":1966,"updatedDate":1967,"__hash__":1968},"blogPosts/de-de/blog/from-code-to-production-a-guide-to-continuous-deployment-with-gitlab.md","Vom Code bis zur Produktion: Ein Leitfaden für die kontinuierliche Bereitstellung mit GitLab",[7,8],"Benjamin Skierlak","James Wormwell",{"type":10,"value":11,"toc":1926},"minimark",[12,16,19,24,141,144,147,151,154,177,180,194,197,201,204,261,264,267,278,281,284,295,298,301,315,318,321,335,338,341,344,347,350,353,358,369,373,400,404,423,427,432,436,475,513,517,520,639,643,646,654,657,665,669,676,740,743,749,757,763,771,781,789,799,815,823,832,836,839,920,923,937,940,944,951,985,988,991,1070,1072,1086,1090,1093,1131,1138,1149,1152,1156,1159,1344,1347,1358,1369,1373,1379,1429,1432,1548,1551,1646,1649,1706,1709,1720,1723,1729,1736,1740,1743,1749,1752,1769,1772,1786,1789,1792,1809,1825,1828,1831,1834,1837,1854,1857,1860,1877,1880,1883,1900,1903,1906,1909,1912,1923],[13,14,15],"p",{},"Die kontinuierliche Bereitstellung ist eine bahnbrechende Praxis, die es Teams ermöglicht, schneller und mit höherem Vertrauen Werte zu schaffen. Das Eintauchen in erweiterte Bereitstellungs-Workflows – wie GitOps, Container-Orchestrierung mit Kubernetes oder dynamische Umgebungen – kann jedoch für Teams, die gerade erst anfangen, einschüchternd sein.",[13,17,18],{},"GitLab setzt sich dafür ein, die Bereitstellung nahtlos und skalierbar zu gestalten. Indem wir es den Teams ermöglichen, sich auf die Grundlagen zu konzentrieren, befähigen wir sie, eine starke Basis zu schaffen, die das Wachstum komplexerer Strategien im Laufe der Zeit unterstützt. Dieser Leitfaden enthält wichtige Schritte, um mit der Implementierung der kontinuierlichen Bereitstellung mit GitLab zu beginnen und die Grundlage für deinen langfristigen Erfolg zu schaffen.",[20,21,23],"h2",{"id":22},"inhaltsverzeichnis","Inhaltsverzeichnis",[25,26,27,75,103,129,135],"ul",{},[28,29,30,35],"li",{},[31,32,34],"a",{"href":33},"#beginne-mit-einem-workflow-plan","Beginne mit einem Workflow-Plan",[25,36,37,63,69],{},[28,38,39,43],{},[31,40,42],{"href":41},"#artefakt-management-strategie","Artefakt-Management-Strategie",[25,44,45,51,57],{},[28,46,47],{},[31,48,50],{"href":49},"#artefakte-und-versionsstrategien","Artefakte und Versionsstrategien",[28,52,53],{},[31,54,56],{"href":55},"#artefaktaufbewahrung-erstellen","Artefaktaufbewahrung erstellen",[28,58,59],{},[31,60,62],{"href":61},"#registrierungszugriff-und-authentifizierung","Registrierungszugriff und Authentifizierung",[28,64,65],{},[31,66,68],{"href":67},"#umgebungsstrategie","Umgebungsstrategie",[28,70,71],{},[31,72,74],{"href":73},"#bereitstellungsziele","Bereitstellungsziele",[28,76,77,81],{},[31,78,80],{"href":79},"#deine-cd-pipeline-implementieren","Deine CD-Pipeline implementieren",[25,82,83,97],{},[28,84,85,89],{},[31,86,88],{"href":87},"#ein-schritt-f%C3%BCr-schritt-beispiel","Ein Schritt-für-Schritt-Beispiel",[25,90,91],{},[28,92,93],{},[31,94,96],{"href":95},"#voraussetzungen","Voraussetzungen",[28,98,99],{},[31,100,102],{"href":101},"#best-practices","Best Practices",[28,104,105,109],{},[31,106,108],{"href":107},"#skaliere-deine-bereitstellungsstrategie","Skaliere deine Bereitstellungsstrategie",[25,110,111,117,123],{},[28,112,113],{},[31,114,116],{"href":115},"#erweiterte-sicherheitsma%C3%9Fnahmen","Erweiterte Sicherheitsmaßnahmen",[28,118,119],{},[31,120,122],{"href":121},"#progressive-bereitstellungsstrategien","Progressive Bereitstellungsstrategien",[28,124,125],{},[31,126,128],{"href":127},"#%C3%BCberwachung-und-optimierung","Überwachung und Optimierung",[28,130,131],{},[31,132,134],{"href":133},"#warum-gitlab","Warum GitLab",[28,136,137],{},[31,138,140],{"href":139},"#noch-heute-starten","Noch heute starten",[20,142,34],{"id":143},"beginne-mit-einem-workflow-plan",[13,145,146],{},"Bevor du dich mit der technischen Implementierung befasst, nimm dir Zeit, um deinen Bereitstellungs-Workflow zu planen. Der Erfolg liegt in der sorgfältigen Planung und dem methodischen Vorgehen.",[148,149,42],"h3",{"id":150},"artefakt-management-strategie",[13,152,153],{},"Im Zusammenhang mit der kontinuierlichen Bereitstellung sind Artefakte die Paket-Ausgaben deines Build-Prozesses, die gespeichert, als Versionen verwaltet und bereitgestellt werden müssen. Darunter fallen:",[25,155,156,159,162,165,168,171,174],{},[28,157,158],{},"Container-Images für deine Anwendungen",[28,160,161],{},"Pakete",[28,163,164],{},"kompilierte Binärdateien oder ausführbare Dateien",[28,166,167],{},"Bibliotheken",[28,169,170],{},"Konfigurationsdateien",[28,172,173],{},"Dokumentationspakete",[28,175,176],{},"andere Artefakte",[13,178,179],{},"Jede Art von Artefakt spielt eine bestimmte Rolle in deinem Bereitstellungsprozess. Zum Beispiel könnte eine typische Webanwendung Folgendes generieren:",[25,181,182,185,188,191],{},[28,183,184],{},"ein Container-Image für den Backend-Service",[28,186,187],{},"ein ZIP-Archiv mit kompilierten Frontend-Assets",[28,189,190],{},"SQL-Dateien für Datenbankänderungen",[28,192,193],{},"umweltspezifische Konfigurationsdateien",[13,195,196],{},"Die effektive Verwaltung dieser Artefakte ist für erfolgreiche Bereitstellungen von entscheidender Bedeutung. Hier erfährst du, wie du das Artefakt-Management angehen kannst.",[198,199,50],"h4",{"id":200},"artefakte-und-versionsstrategien",[13,202,203],{},"Eine Best Practice, um mit einer sauberen Struktur zu beginnen, besteht darin, eine klare Versionsstrategie für deine Artefakte festzulegen. Bei der Erstellung von Releases gilt:",[25,205,206,228,239,250],{},[28,207,208,209],{},"Verwende eine semantische Versionsverwaltung (major.minor.patch) für Release-Tags",[25,210,211,219,222,225],{},[28,212,213,214,218],{},"Beispiel: ",[215,216,217],"code",{},"myapp:1.2.3"," für ein stabiles Release",[28,220,221],{},"Wichtige Versionsänderungen (2.0.0) für Breaking Changes",[28,223,224],{},"Geringfügige Versionsänderungen (1.3.0) für neue Funktionen",[28,226,227],{},"Patch-Versionsänderungen (1.2.4) für Fehlerbehebungen",[28,229,230,231],{},"Pflege einen „neuesten“ Tag für die neueste stabile Version",[25,232,233],{},[28,234,213,235,238],{},[215,236,237],{},"myapp:latest"," für automatisierte Bereitstellungen",[28,240,241,242],{},"Beziehe Commit-SHA für präzises Versions-Tracking ein",[25,243,244],{},[28,245,213,246,249],{},[215,247,248],{},"myapp:1.2.3-abc123f"," zum Debuggen",[28,251,252,253],{},"Berücksichtige Branch-basierte Tags für Entwicklungsumgebungen",[25,254,255],{},[28,256,213,257,260],{},[215,258,259],{},"myapp: feature-user-auth"," für Funktionstests",[198,262,56],{"id":263},"artefaktaufbewahrung-erstellen",[13,265,266],{},"Implementiere definierte Aufbewahrungsregeln:",[25,268,269,272,275],{},[28,270,271],{},"Lege explizite Ablaufzeitrahmen für temporäre Artefakte fest",[28,273,274],{},"Definiere, welche Artefakte dauerhaft aufbewahrt werden müssen",[28,276,277],{},"Konfiguriere Bereinigungsrichtlinien zur Verwaltung des Speichers",[198,279,62],{"id":280},"registrierungszugriff-und-authentifizierung",[13,282,283],{},"Schütze deine Artefakte mit den richtigen Zugangskontrollen:",[25,285,286,289,292],{},[28,287,288],{},"Implementiere persönliche Zugriffstoken für den Entwicklerzugriff",[28,290,291],{},"Konfiguriere CI/CD-Variablen für die Pipeline-Authentifizierung",[28,293,294],{},"Richte ordnungsgemäße Zugangsumfänge ein",[148,296,68],{"id":297},"umgebungsstrategie",[13,299,300],{},"Betrachte deine Umgebungen frühzeitig, da sie deine gesamte Bereitstellungspipeline prägen:",[25,302,303,306,309,312],{},[28,304,305],{},"Konfigurationen der Entwicklungs-, Staging- und Produktionsumgebung",[28,307,308],{},"Umgebungsspezifische Variablen und Geheimnisse",[28,310,311],{},"Zugangskontrollen und Schutzregeln",[28,313,314],{},"Ansatz zur Nachverfolgung und Überwachung der Bereitstellung",[148,316,74],{"id":317},"bereitstellungsziele",[13,319,320],{},"Sei dir bewusst, wo und wie du bereitstellen wirst. Diese Entscheidungen sind wichtig und die jeweiligen Vor- und Nachteile sollten berücksichtigt werden:",[25,322,323,326,329,332],{},[28,324,325],{},"Infrastrukturanforderungen (VMs, Container, Cloud-Services)",[28,327,328],{},"Netzwerkzugriff und Sicherheitskonfigurationen",[28,330,331],{},"Authentifizierungsmechanismen (SSH-Schlüssel, Zugriffstoken)",[28,333,334],{},"Überlegungen zur Ressourcenzuweisung und Skalierung",[13,336,337],{},"Nachdem wir unsere Strategie definiert und grundlegende Entscheidungen getroffen haben, können wir diese Pläne jetzt in eine funktionierende Pipeline umsetzen. Wir werden ein praktisches Beispiel erstellen, das diese Konzepte demonstriert, beginnend mit einer einfachen Anwendung und dem schrittweisen Hinzufügen von Bereitstellungsfunktionen.",[20,339,80],{"id":340},"deine-cd-pipeline-implementieren",[148,342,88],{"id":343},"ein-schritt-für-schritt-beispiel",[13,345,346],{},"Sehen wir uns nun die Implementierung einer grundlegenden Pipeline für die kontinuierliche Bereitstellung für eine Webanwendung an. Wir werden eine einfache HTML-Anwendung als Beispiel verwenden, aber diese Prinzipien gelten für jede Art von Anwendung. Wir werden unsere Anwendung auch als Docker Image auf einer einfachen virtuellen Maschine bereitstellen. Somit können wir uns auf ein kuratiertes Bild mit minimalen Abhängigkeiten stützen und sicherstellen, dass keine umgebungsspezifischen Anforderungen unbeabsichtigt eingeführt werden. Wenn wir an einer virtuellen Maschine arbeiten, werden wir die nativen Integrationen von GitLab nicht nutzen, sodass wir zunächst an einem einfacheren, aber weniger skalierbaren Setup arbeiten können.",[198,348,96],{"id":349},"voraussetzungen",[13,351,352],{},"In diesem Beispiel zielen wir darauf ab, eine Anwendung zu containerisieren, die wir auf einer virtuellen Maschine ausführen, die auf einem Cloud-Anbieter gehostet wird. Wir werden diese Anwendung auch lokal auf unserem Computer testen. Diese Liste der Voraussetzungen wird nur für dieses Szenario benötigt.",[354,355,357],"h5",{"id":356},"einrichtung-der-virtuellen-maschine","Einrichtung der virtuellen Maschine",[25,359,360,363,366],{},[28,361,362],{},"Stelle eine VM in deinem bevorzugten Cloud-Provider (z. B. GCP, AWS, Azure) bereit",[28,364,365],{},"Konfiguriere die Netzwerkregeln, um den Zugriff auf die Ports 22, 80 und 443 zu ermöglichen",[28,367,368],{},"Zeichne die öffentliche IP-Adresse des Computers für die Bereitstellung auf",[354,370,372],{"id":371},"ssh-authentifizierung-einrichten","SSH-Authentifizierung einrichten:",[25,374,375,378,385,391,394,397],{},[28,376,377],{},"Generiere ein öffentliches/privates Schlüsselpaar für die Maschine",[28,379,380,381],{},"Gehe in GitLab zu ",[382,383,384],"strong",{},"Einstellungen > CI/CD > Variablen",[28,386,387,388],{},"Erstelle eine Variable mit dem Namen ",[215,389,390],{},"GITLAB_KEY",[28,392,393],{},"Wähle als Typ „Datei“ (für SSH-Authentifizierung erforderlich)",[28,395,396],{},"Füge den privaten Schlüssel in das Feld „Wert“ ein",[28,398,399],{},"Definiere eine BENUTZERVARIABLE; dies ist der Benutzer, der sich anmeldet und die Skripte auf deiner VM ausführt",[354,401,403],{"id":402},"bereitstellungsvariablen-konfigurieren","Bereitstellungsvariablen konfigurieren",[25,405,406],{},[28,407,408,409],{},"Erstelle Variablen für deine Bereitstellungsziele:",[25,410,411,417],{},[28,412,413,416],{},[215,414,415],{},"STAGING_TARGET",": deine Staging-Server-IP/-Domäne",[28,418,419,422],{},[215,420,421],{},"PRODUCTION_TARGET",": deine Produktionsserver-IP/-Domäne",[354,424,426],{"id":425},"lokales-entwicklungs-setup","Lokales Entwicklungs-Setup",[25,428,429],{},[28,430,431],{},"Installiere Docker auf deinem lokalen Computer, um Bereitstellungen zu testen",[354,433,435],{"id":434},"gitlab-container-registry-zugriff","GitLab-Container-Registry-Zugriff",[25,437,438,452,472],{},[28,439,440,441],{},"Finde deinen Registry-Pfad:",[25,442,443,449],{},[28,444,445,446],{},"Navigiere zu ",[382,447,448],{},"Bereitstellen > Container-Registry",[28,450,451],{},"Kopiere den Registry-Pfad (z. B. registry.gitlab.com/group/project)",[28,453,454,455],{},"Authentifizierung einrichten:",[25,456,457,463,466,469],{},[28,458,459,460],{},"Gehe zu ",[382,461,462],{},"Einstellungen > Zugriffstoken",[28,464,465],{},"Erstelle ein neues Token mit Registry-Zugriff",[28,467,468],{},"Token-Ablauf: max. 1 Jahr",[28,470,471],{},"Speichere das Token sicher",[28,473,474],{},"Lokalen Registry-Zugriff konfigurieren:",[476,477,482],"pre",{"className":478,"code":479,"language":480,"meta":481,"style":481},"language-shell shiki shiki-themes github-light","docker login registry.gitlab.com\n# Der Benutzername, wenn du einen PAT verwendest, ist gitlab-ci-token\n# Passwort: your-access-token\n","shell","",[215,483,484,500,507],{"__ignoreMap":481},[485,486,489,493,497],"span",{"class":487,"line":488},"line",1,[485,490,492],{"class":491},"s7eDp","docker",[485,494,496],{"class":495},"sYBdl"," login",[485,498,499],{"class":495}," registry.gitlab.com\n",[485,501,503],{"class":487,"line":502},2,[485,504,506],{"class":505},"sAwPA","# Der Benutzername, wenn du einen PAT verwendest, ist gitlab-ci-token\n",[485,508,510],{"class":487,"line":509},3,[485,511,512],{"class":505},"# Passwort: your-access-token\n",[198,514,516],{"id":515},"_1-erstelle-deine-anwendung","1. Erstelle deine Anwendung",[13,518,519],{},"Beginne mit einer grundlegenden Webanwendung. In unserem Beispiel verwenden wir eine einfache HTML-Seite:",[476,521,525],{"className":522,"code":523,"language":524,"meta":481,"style":481},"language-xml shiki shiki-themes github-light","\u003C!|||UNTRANSLATED_CONTENT_START|||-- index.html -->\n\u003Chtml>\n  \u003Chead>\n    \u003Cstyle>\n      body {\n        background-color: #171321; /* GitLab dark */\n      }\n    \u003C/style>\n  \u003C/head>\n  \u003Cbody>\n    \u003C!|||UNTRANSLATED_CONTENT_END|||-- Dein Inhalt hier -->\n  \u003C/body>\n\u003C/html>\n","xml",[215,526,527,533,545,555,566,572,578,584,594,604,614,620,629],{"__ignoreMap":481},[485,528,529],{"class":487,"line":488},[485,530,532],{"class":531},"sgsFI","\u003C!|||UNTRANSLATED_CONTENT_START|||-- index.html -->\n",[485,534,535,538,542],{"class":487,"line":502},[485,536,537],{"class":531},"\u003C",[485,539,541],{"class":540},"shJU0","html",[485,543,544],{"class":531},">\n",[485,546,547,550,553],{"class":487,"line":509},[485,548,549],{"class":531},"  \u003C",[485,551,552],{"class":540},"head",[485,554,544],{"class":531},[485,556,558,561,564],{"class":487,"line":557},4,[485,559,560],{"class":531},"    \u003C",[485,562,563],{"class":540},"style",[485,565,544],{"class":531},[485,567,569],{"class":487,"line":568},5,[485,570,571],{"class":531},"      body {\n",[485,573,575],{"class":487,"line":574},6,[485,576,577],{"class":531},"        background-color: #171321; /* GitLab dark */\n",[485,579,581],{"class":487,"line":580},7,[485,582,583],{"class":531},"      }\n",[485,585,587,590,592],{"class":487,"line":586},8,[485,588,589],{"class":531},"    \u003C/",[485,591,563],{"class":540},[485,593,544],{"class":531},[485,595,597,600,602],{"class":487,"line":596},9,[485,598,599],{"class":531},"  \u003C/",[485,601,552],{"class":540},[485,603,544],{"class":531},[485,605,607,609,612],{"class":487,"line":606},10,[485,608,549],{"class":531},[485,610,611],{"class":540},"body",[485,613,544],{"class":531},[485,615,617],{"class":487,"line":616},11,[485,618,619],{"class":531},"    \u003C!|||UNTRANSLATED_CONTENT_END|||-- Dein Inhalt hier -->\n",[485,621,623,625,627],{"class":487,"line":622},12,[485,624,599],{"class":531},[485,626,611],{"class":540},[485,628,544],{"class":531},[485,630,632,635,637],{"class":487,"line":631},13,[485,633,634],{"class":531},"\u003C/",[485,636,541],{"class":540},[485,638,544],{"class":531},[198,640,642],{"id":641},"_2-containerisiere-deine-anwendung","2. Containerisiere deine Anwendung",[13,644,645],{},"Erstelle ein Dockerfile, um deine Anwendung zu paketieren:",[476,647,652],{"className":648,"code":650,"language":651,"meta":481},[649],"language-text","FROM nginx:1.26.2\nCOPY index.html /usr/share/nginx/html/index.html\n","text",[215,653,650],{"__ignoreMap":481},[13,655,656],{},"Dieses Dockerfile:",[25,658,659,662],{},[28,660,661],{},"Verwendet nginx als Basis-Image für die Bereitstellung von Webinhalten",[28,663,664],{},"Kopiert deine HTML-Datei an die richtige Stelle in der nginx-Verzeichnisstruktur",[198,666,668],{"id":667},"_3-richte-deine-cicd-pipeline-ein","3. Richte deine CI/CD-Pipeline ein",[13,670,671,672,675],{},"Erstelle eine ",[215,673,674],{},".gitlab-ci.yml","-Datei, um deine Pipeline-Phasen zu definieren:",[476,677,681],{"className":678,"code":679,"language":680,"meta":481,"style":481},"language-yaml shiki shiki-themes github-light","variables:\n  TAG_LATEST: $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_NAME:latest\n  TAG_COMMIT: $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_NAME:$CI_COMMIT_SHA\n\nstages:\n  - publish\n  - deploy\n","yaml",[215,682,683,691,702,712,718,725,733],{"__ignoreMap":481},[485,684,685,688],{"class":487,"line":488},[485,686,687],{"class":540},"variables",[485,689,690],{"class":531},":\n",[485,692,693,696,699],{"class":487,"line":502},[485,694,695],{"class":540},"  TAG_LATEST",[485,697,698],{"class":531},": ",[485,700,701],{"class":495},"$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_NAME:latest\n",[485,703,704,707,709],{"class":487,"line":509},[485,705,706],{"class":540},"  TAG_COMMIT",[485,708,698],{"class":531},[485,710,711],{"class":495},"$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_NAME:$CI_COMMIT_SHA\n",[485,713,714],{"class":487,"line":557},[485,715,717],{"emptyLinePlaceholder":716},true,"\n",[485,719,720,723],{"class":487,"line":568},[485,721,722],{"class":540},"stages",[485,724,690],{"class":531},[485,726,727,730],{"class":487,"line":574},[485,728,729],{"class":531},"  - ",[485,731,732],{"class":495},"publish\n",[485,734,735,737],{"class":487,"line":580},[485,736,729],{"class":531},[485,738,739],{"class":495},"deploy\n",[13,741,742],{},"Sehen wir uns das genauer an:",[13,744,745,748],{},[215,746,747],{},"TAG_LATEST"," besteht aus drei Teilen:",[25,750,751],{},[28,752,753,756],{},[215,754,755],{},"$CI_REGISTRY_IMAGE"," ist der Pfad zum Container-Registry deines Projekts in GitLab",[13,758,759,760],{},"Zum Beispiel: ",[215,761,762],{},"registry.gitlab.com/your-group/your-project",[25,764,765],{},[28,766,767,770],{},[215,768,769],{},"$CI_COMMIT_REF_NAME"," ist der Name deiner Branch oder deines Tags",[13,772,773,774,777,778],{},"Zum Beispiel, wenn du dich im Haupt-Branch befindest: ",[215,775,776],{},"/main",", und wenn du dich in einem Feature-Branch befindest: ",[215,779,780],{},"/feature-login",[25,782,783],{},[28,784,785,788],{},[215,786,787],{},":latest"," ist ein festes Suffix",[13,790,791,792,794,795,798],{},"Wenn du dich also im Main-Branch befindest, wird ",[215,793,747],{}," zu: ",[215,796,797],{},"registry.gitlab.com/your-group/your-project/main:latest",".",[13,800,801,804,805,807,808,811,812,798],{},[215,802,803],{},"TAG_COMMIT"," ist fast identisch, aber anstelle von ",[215,806,787],{}," verwendet es: ",[215,809,810],{},"$CI_COMMIT_SHA",", was die Commit-Kennung ist, zum Beispiel: ",[215,813,814],{},":abc123def456",[13,816,817,818,794,820,798],{},"Für denselben Commit im Haupt-Branch wird ",[215,819,803],{},[215,821,822],{},"registry.gitlab.com/your-group/your-project/main:abc123def456",[13,824,825,826,828,829,831],{},"Der Grund für beides ist, dass ",[215,827,747],{}," dir eine einfache Möglichkeit bietet, immer die neueste Version zu erhalten, und ",[215,830,803],{}," gibt dir eine bestimmte Version, zu der du bei Bedarf zurückkehren kannst.",[198,833,835],{"id":834},"_4-im-container-registry-veröffentlichen","4. Im Container-Registry veröffentlichen",[13,837,838],{},"Füge den Veröffentlichungsauftrag zu deiner Pipeline hinzu:",[476,840,842],{"className":678,"code":841,"language":680,"meta":481,"style":481},"publish:\n  stage: publish\n  image: docker:latest\n  services:\n    - docker:dind\n  script:\n    - docker build -t $TAG_LATEST -t $TAG_COMMIT .\n    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY\n    - docker push $TAG_LATEST\n    - docker push $TAG_COMMIT\n",[215,843,844,851,860,870,877,885,892,899,906,913],{"__ignoreMap":481},[485,845,846,849],{"class":487,"line":488},[485,847,848],{"class":540},"publish",[485,850,690],{"class":531},[485,852,853,856,858],{"class":487,"line":502},[485,854,855],{"class":540},"  stage",[485,857,698],{"class":531},[485,859,732],{"class":495},[485,861,862,865,867],{"class":487,"line":509},[485,863,864],{"class":540},"  image",[485,866,698],{"class":531},[485,868,869],{"class":495},"docker:latest\n",[485,871,872,875],{"class":487,"line":557},[485,873,874],{"class":540},"  services",[485,876,690],{"class":531},[485,878,879,882],{"class":487,"line":568},[485,880,881],{"class":531},"    - ",[485,883,884],{"class":495},"docker:dind\n",[485,886,887,890],{"class":487,"line":574},[485,888,889],{"class":540},"  script",[485,891,690],{"class":531},[485,893,894,896],{"class":487,"line":580},[485,895,881],{"class":531},[485,897,898],{"class":495},"docker build -t $TAG_LATEST -t $TAG_COMMIT .\n",[485,900,901,903],{"class":487,"line":586},[485,902,881],{"class":531},[485,904,905],{"class":495},"docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY\n",[485,907,908,910],{"class":487,"line":596},[485,909,881],{"class":531},[485,911,912],{"class":495},"docker push $TAG_LATEST\n",[485,914,915,917],{"class":487,"line":606},[485,916,881],{"class":531},[485,918,919],{"class":495},"docker push $TAG_COMMIT\n",[13,921,922],{},"Dieser Job:",[25,924,925,928,931,934],{},[28,926,927],{},"verwendet Docker-in-Docker, um Bilder zu entwickeln",[28,929,930],{},"erstellt zwei getaggte Versionen deines Bildes",[28,932,933],{},"authentifiziert sich bei der GitLab-Registrierung",[28,935,936],{},"pusht beide Versionen in das Registry",[13,938,939],{},"Jetzt, da unsere Bilder sicher im Registry gespeichert sind, können wir uns darauf konzentrieren, sie in unseren Zielumgebungen bereitzustellen. Beginnen wir mit lokalen Tests, um unser Setup zu validieren, bevor wir zu Produktionsbereitstellungen übergehen.",[198,941,943],{"id":942},"_5-in-deiner-umgebung-bereitstellen","5. In deiner Umgebung bereitstellen",[13,945,946,947,950],{},"Vor der Bereitstellung in der Produktion kannst du einen lokalen Test durchführen. Wir haben unser Image gerade im GitLab-Repository veröffentlicht, das wir lokal abrufen werden. Wenn du dir über den genauen Pfad nicht sicher bist, navigiere zu ",[382,948,949],{},"Bereitstellen > Container-Registry",". Du solltest ein Symbol sehen, um den Pfad deines Bildes am Ende der Zeile für das Container-Image zu kopieren, das du testen möchtest.",[476,952,954],{"className":478,"code":953,"language":480,"meta":481,"style":481},"docker login registry.gitlab.com \ndocker run -p 80:80 registry.gitlab.com/your-project-path/main:latest\n",[215,955,956,968],{"__ignoreMap":481},[485,957,958,960,962,965],{"class":487,"line":488},[485,959,492],{"class":491},[485,961,496],{"class":495},[485,963,964],{"class":495}," registry.gitlab.com",[485,966,967],{"class":531}," \n",[485,969,970,972,975,979,982],{"class":487,"line":502},[485,971,492],{"class":491},[485,973,974],{"class":495}," run",[485,976,978],{"class":977},"sYu0t"," -p",[485,980,981],{"class":495}," 80:80",[485,983,984],{"class":495}," registry.gitlab.com/your-project-path/main:latest\n",[13,986,987],{},"Auf diese Weise solltest du über deinen Webbrowser lokal über deine lokale Host-Adresse auf deine Anwendung zugreifen können.",[13,989,990],{},"Du kannst jetzt einen Bereitstellungsjob zu deiner Pipeline hinzufügen:",[476,992,994],{"className":678,"code":993,"language":680,"meta":481,"style":481},"deploy:\n  stage: deploy\n  image: alpine:latest\n  script:\n    - chmod 400 $GITLAB_KEY\n    - apk add openssh-client\n    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY\n    - ssh -i $GITLAB_KEY -o StrictHostKeyChecking=no $USER@$TARGET_SERVER \n      docker pull $TAG_COMMIT &&\n      docker rm -f myapp || true &&\n      docker run -d -p 80:80 --name myapp $TAG_COMMIT\n",[215,995,996,1003,1011,1020,1026,1033,1040,1046,1055,1060,1065],{"__ignoreMap":481},[485,997,998,1001],{"class":487,"line":488},[485,999,1000],{"class":540},"deploy",[485,1002,690],{"class":531},[485,1004,1005,1007,1009],{"class":487,"line":502},[485,1006,855],{"class":540},[485,1008,698],{"class":531},[485,1010,739],{"class":495},[485,1012,1013,1015,1017],{"class":487,"line":509},[485,1014,864],{"class":540},[485,1016,698],{"class":531},[485,1018,1019],{"class":495},"alpine:latest\n",[485,1021,1022,1024],{"class":487,"line":557},[485,1023,889],{"class":540},[485,1025,690],{"class":531},[485,1027,1028,1030],{"class":487,"line":568},[485,1029,881],{"class":531},[485,1031,1032],{"class":495},"chmod 400 $GITLAB_KEY\n",[485,1034,1035,1037],{"class":487,"line":574},[485,1036,881],{"class":531},[485,1038,1039],{"class":495},"apk add openssh-client\n",[485,1041,1042,1044],{"class":487,"line":580},[485,1043,881],{"class":531},[485,1045,905],{"class":495},[485,1047,1048,1050,1053],{"class":487,"line":586},[485,1049,881],{"class":531},[485,1051,1052],{"class":495},"ssh -i $GITLAB_KEY -o StrictHostKeyChecking=no $USER@$TARGET_SERVER",[485,1054,967],{"class":531},[485,1056,1057],{"class":487,"line":596},[485,1058,1059],{"class":495},"      docker pull $TAG_COMMIT &&\n",[485,1061,1062],{"class":487,"line":606},[485,1063,1064],{"class":495},"      docker rm -f myapp || true &&\n",[485,1066,1067],{"class":487,"line":616},[485,1068,1069],{"class":495},"      docker run -d -p 80:80 --name myapp $TAG_COMMIT\n",[13,1071,922],{},[25,1073,1074,1077,1080,1083],{},[28,1075,1076],{},"richtet einen SSH-Zugriff auf dein Bereitstellungsziel ein",[28,1078,1079],{},"ruft das neueste Image auf",[28,1081,1082],{},"entfernt alle vorhandenen Container",[28,1084,1085],{},"stellt die neue Version bereit",[198,1087,1089],{"id":1088},"_6-bereitstellungen-nachverfolgen","6. Bereitstellungen nachverfolgen",[13,1091,1092],{},"Aktiviere die Nachverfolgung von Bereitstellungen, indem du die Umgebungskonfiguration hinzufügst:",[476,1094,1096],{"className":678,"code":1095,"language":680,"meta":481,"style":481},"deploy:\n  environment:\n    name: production\nurl: https://deine-anwendung-url.com\n",[215,1097,1098,1104,1111,1121],{"__ignoreMap":481},[485,1099,1100,1102],{"class":487,"line":488},[485,1101,1000],{"class":540},[485,1103,690],{"class":531},[485,1105,1106,1109],{"class":487,"line":502},[485,1107,1108],{"class":540},"  environment",[485,1110,690],{"class":531},[485,1112,1113,1116,1118],{"class":487,"line":509},[485,1114,1115],{"class":540},"    name",[485,1117,698],{"class":531},[485,1119,1120],{"class":495},"production\n",[485,1122,1123,1126,1128],{"class":487,"line":557},[485,1124,1125],{"class":540},"url",[485,1127,698],{"class":531},[485,1129,1130],{"class":495},"https://deine-anwendung-url.com\n",[13,1132,1133,1134,1137],{},"Dadurch wird ein Umgebungsobjekt im Abschnitt ",[382,1135,1136],{},"Betreiben > Umgebungen"," von GitLab erstellt, das Folgendes bietet:",[25,1139,1140,1143,1146],{},[28,1141,1142],{},"Bereitstellungsverlauf",[28,1144,1145],{},"aktueller Bereitstellungsstatus",[28,1147,1148],{},"schneller Zugriff auf deine Anwendung",[13,1150,1151],{},"Während eine einzelne Umgebungspipeline ein guter Ausgangspunkt ist, müssen die meisten Teams mehrere Umgebungen verwalten, um ordnungsgemäß zu testen und die Staging-Phase durchzuführen. Lass uns unsere Pipeline erweitern, um dieses realistischere Szenario zu bewältigen.",[198,1153,1155],{"id":1154},"_7-mehrere-umgebungen-einrichten","7. Mehrere Umgebungen einrichten",[13,1157,1158],{},"Für eine robustere Pipeline, konfiguriere Staging- und Produktionsbereitstellungen:",[476,1160,1162],{"className":678,"code":1161,"language":680,"meta":481,"style":481},"stages:\n  - publish\n  - staging\n  - release\n  - version\n  - production\n\nstaging:\n  stage: staging\n  rules:\n    - if: $CI_COMMIT_BRANCH == \"main\" && $CI_COMMIT_TAG == null\n  environment:\n    name: staging\n    url: https://staging.your-app.com\n  # deployment script here\n\nproduction:\n  stage: production\n  rules:\n    - if: $CI_COMMIT_TAG\n  environment:\n    name: production\n    url: https://your-app.com\n  # deployment script here\n",[215,1163,1164,1170,1176,1183,1190,1197,1203,1207,1214,1222,1229,1241,1247,1255,1266,1272,1277,1285,1294,1301,1313,1320,1329,1339],{"__ignoreMap":481},[485,1165,1166,1168],{"class":487,"line":488},[485,1167,722],{"class":540},[485,1169,690],{"class":531},[485,1171,1172,1174],{"class":487,"line":502},[485,1173,729],{"class":531},[485,1175,732],{"class":495},[485,1177,1178,1180],{"class":487,"line":509},[485,1179,729],{"class":531},[485,1181,1182],{"class":495},"staging\n",[485,1184,1185,1187],{"class":487,"line":557},[485,1186,729],{"class":531},[485,1188,1189],{"class":495},"release\n",[485,1191,1192,1194],{"class":487,"line":568},[485,1193,729],{"class":531},[485,1195,1196],{"class":495},"version\n",[485,1198,1199,1201],{"class":487,"line":574},[485,1200,729],{"class":531},[485,1202,1120],{"class":495},[485,1204,1205],{"class":487,"line":580},[485,1206,717],{"emptyLinePlaceholder":716},[485,1208,1209,1212],{"class":487,"line":586},[485,1210,1211],{"class":540},"staging",[485,1213,690],{"class":531},[485,1215,1216,1218,1220],{"class":487,"line":596},[485,1217,855],{"class":540},[485,1219,698],{"class":531},[485,1221,1182],{"class":495},[485,1223,1224,1227],{"class":487,"line":606},[485,1225,1226],{"class":540},"  rules",[485,1228,690],{"class":531},[485,1230,1231,1233,1236,1238],{"class":487,"line":616},[485,1232,881],{"class":531},[485,1234,1235],{"class":540},"if",[485,1237,698],{"class":531},[485,1239,1240],{"class":495},"$CI_COMMIT_BRANCH == \"main\" && $CI_COMMIT_TAG == null\n",[485,1242,1243,1245],{"class":487,"line":622},[485,1244,1108],{"class":540},[485,1246,690],{"class":531},[485,1248,1249,1251,1253],{"class":487,"line":631},[485,1250,1115],{"class":540},[485,1252,698],{"class":531},[485,1254,1182],{"class":495},[485,1256,1258,1261,1263],{"class":487,"line":1257},14,[485,1259,1260],{"class":540},"    url",[485,1262,698],{"class":531},[485,1264,1265],{"class":495},"https://staging.your-app.com\n",[485,1267,1269],{"class":487,"line":1268},15,[485,1270,1271],{"class":505},"  # deployment script here\n",[485,1273,1275],{"class":487,"line":1274},16,[485,1276,717],{"emptyLinePlaceholder":716},[485,1278,1280,1283],{"class":487,"line":1279},17,[485,1281,1282],{"class":540},"production",[485,1284,690],{"class":531},[485,1286,1288,1290,1292],{"class":487,"line":1287},18,[485,1289,855],{"class":540},[485,1291,698],{"class":531},[485,1293,1120],{"class":495},[485,1295,1297,1299],{"class":487,"line":1296},19,[485,1298,1226],{"class":540},[485,1300,690],{"class":531},[485,1302,1304,1306,1308,1310],{"class":487,"line":1303},20,[485,1305,881],{"class":531},[485,1307,1235],{"class":540},[485,1309,698],{"class":531},[485,1311,1312],{"class":495},"$CI_COMMIT_TAG\n",[485,1314,1316,1318],{"class":487,"line":1315},21,[485,1317,1108],{"class":540},[485,1319,690],{"class":531},[485,1321,1323,1325,1327],{"class":487,"line":1322},22,[485,1324,1115],{"class":540},[485,1326,698],{"class":531},[485,1328,1120],{"class":495},[485,1330,1332,1334,1336],{"class":487,"line":1331},23,[485,1333,1260],{"class":540},[485,1335,698],{"class":531},[485,1337,1338],{"class":495},"https://your-app.com\n",[485,1340,1342],{"class":487,"line":1341},24,[485,1343,1271],{"class":505},[13,1345,1346],{},"Dieses Setup:",[25,1348,1349,1352,1355],{},[28,1350,1351],{},"stellt die Staging-Phase deines Main-Branch bereit",[28,1353,1354],{},"verwendet GitLab-Tags, um Produktionsbereitstellungen auszulösen",[28,1356,1357],{},"bietet separate Nachverfolgung für jede Umgebung",[13,1359,1360,1361,1364,1365,1368],{},"Hier und in unserem nächsten Schritt nutzen wir eine sehr nützliche GitLab-Funktion: Tags. Durch manuelles Erstellen eines Tags im Abschnitt ",[382,1362,1363],{},"Code > Tags"," wird das ",[215,1366,1367],{},"$CI_COMMIT_TAG"," erstellt, wodurch wir Jobs entsprechend auslösen können.",[198,1370,1372],{"id":1371},"_8-automatisierte-versionshinweise-erstellen","8. Automatisierte Versionshinweise erstellen",[13,1374,1375,1376,1378],{},"Wir werden die Release-Funktionen von GitLab über unsere CI/CD-Pipeline nutzen. Aktualisiere zuerst deine Phasen in ",[215,1377,674],{},":",[476,1380,1382],{"className":678,"code":1381,"language":680,"meta":481,"style":481},"stages:\n\n- publish\n- staging\n- release # New stage for releases\n- version\n- production\n",[215,1383,1384,1390,1394,1401,1407,1417,1423],{"__ignoreMap":481},[485,1385,1386,1388],{"class":487,"line":488},[485,1387,722],{"class":540},[485,1389,690],{"class":531},[485,1391,1392],{"class":487,"line":502},[485,1393,717],{"emptyLinePlaceholder":716},[485,1395,1396,1399],{"class":487,"line":509},[485,1397,1398],{"class":531},"- ",[485,1400,732],{"class":495},[485,1402,1403,1405],{"class":487,"line":557},[485,1404,1398],{"class":531},[485,1406,1182],{"class":495},[485,1408,1409,1411,1414],{"class":487,"line":568},[485,1410,1398],{"class":531},[485,1412,1413],{"class":495},"release",[485,1415,1416],{"class":505}," # New stage for releases\n",[485,1418,1419,1421],{"class":487,"line":574},[485,1420,1398],{"class":531},[485,1422,1196],{"class":495},[485,1424,1425,1427],{"class":487,"line":580},[485,1426,1398],{"class":531},[485,1428,1120],{"class":495},[13,1430,1431],{},"Als Nächstes fügst du den Release-Job hinzu:",[476,1433,1435],{"className":678,"code":1434,"language":680,"meta":481,"style":481},"release_job:\n  stage: release\n  image: registry.gitlab.com/gitlab-org/release-cli:latest\n  rules:\n    - if: $CI_COMMIT_TAG                  # Only run when a tag is created\n  script:\n    - echo \"Creating release for $CI_COMMIT_TAG\"\n  release:                                # Release configuration\n    name: 'Release $CI_COMMIT_TAG'\n    description: 'Release created from $CI_COMMIT_TAG'\n    tag_name: '$CI_COMMIT_TAG'           # The tag to create\n    ref: '$CI_COMMIT_TAG'                # The tag to base release on\n",[215,1436,1437,1444,1452,1461,1467,1480,1486,1493,1504,1513,1523,1536],{"__ignoreMap":481},[485,1438,1439,1442],{"class":487,"line":488},[485,1440,1441],{"class":540},"release_job",[485,1443,690],{"class":531},[485,1445,1446,1448,1450],{"class":487,"line":502},[485,1447,855],{"class":540},[485,1449,698],{"class":531},[485,1451,1189],{"class":495},[485,1453,1454,1456,1458],{"class":487,"line":509},[485,1455,864],{"class":540},[485,1457,698],{"class":531},[485,1459,1460],{"class":495},"registry.gitlab.com/gitlab-org/release-cli:latest\n",[485,1462,1463,1465],{"class":487,"line":557},[485,1464,1226],{"class":540},[485,1466,690],{"class":531},[485,1468,1469,1471,1473,1475,1477],{"class":487,"line":568},[485,1470,881],{"class":531},[485,1472,1235],{"class":540},[485,1474,698],{"class":531},[485,1476,1367],{"class":495},[485,1478,1479],{"class":505},"                  # Only run when a tag is created\n",[485,1481,1482,1484],{"class":487,"line":574},[485,1483,889],{"class":540},[485,1485,690],{"class":531},[485,1487,1488,1490],{"class":487,"line":580},[485,1489,881],{"class":531},[485,1491,1492],{"class":495},"echo \"Creating release for $CI_COMMIT_TAG\"\n",[485,1494,1495,1498,1501],{"class":487,"line":586},[485,1496,1497],{"class":540},"  release",[485,1499,1500],{"class":531},":                                ",[485,1502,1503],{"class":505},"# Release configuration\n",[485,1505,1506,1508,1510],{"class":487,"line":596},[485,1507,1115],{"class":540},[485,1509,698],{"class":531},[485,1511,1512],{"class":495},"'Release $CI_COMMIT_TAG'\n",[485,1514,1515,1518,1520],{"class":487,"line":606},[485,1516,1517],{"class":540},"    description",[485,1519,698],{"class":531},[485,1521,1522],{"class":495},"'Release created from $CI_COMMIT_TAG'\n",[485,1524,1525,1528,1530,1533],{"class":487,"line":616},[485,1526,1527],{"class":540},"    tag_name",[485,1529,698],{"class":531},[485,1531,1532],{"class":495},"'$CI_COMMIT_TAG'",[485,1534,1535],{"class":505},"           # The tag to create\n",[485,1537,1538,1541,1543,1545],{"class":487,"line":622},[485,1539,1540],{"class":540},"    ref",[485,1542,698],{"class":531},[485,1544,1532],{"class":495},[485,1546,1547],{"class":505},"                # The tag to base release on\n",[13,1549,1550],{},"Du kannst dies verbessern, indem du Links zu deinen Container-Bildern hinzufügst:",[476,1552,1554],{"className":678,"code":1553,"language":680,"meta":481,"style":481},"release:\n  name: 'Release $CI_COMMIT_TAG'\n  description: 'Release created from $CI_COMMIT_TAG'\n  tag_name: '$CI_COMMIT_TAG'\n  ref: '$CI_COMMIT_TAG'\n  assets:\n    links:\n      - name: 'Container Image'\n        url: '$CI_REGISTRY_IMAGE/main:$CI_COMMIT_TAG'\n        link_type: 'image'\n",[215,1555,1556,1562,1571,1580,1590,1599,1606,1613,1626,1636],{"__ignoreMap":481},[485,1557,1558,1560],{"class":487,"line":488},[485,1559,1413],{"class":540},[485,1561,690],{"class":531},[485,1563,1564,1567,1569],{"class":487,"line":502},[485,1565,1566],{"class":540},"  name",[485,1568,698],{"class":531},[485,1570,1512],{"class":495},[485,1572,1573,1576,1578],{"class":487,"line":509},[485,1574,1575],{"class":540},"  description",[485,1577,698],{"class":531},[485,1579,1522],{"class":495},[485,1581,1582,1585,1587],{"class":487,"line":557},[485,1583,1584],{"class":540},"  tag_name",[485,1586,698],{"class":531},[485,1588,1589],{"class":495},"'$CI_COMMIT_TAG'\n",[485,1591,1592,1595,1597],{"class":487,"line":568},[485,1593,1594],{"class":540},"  ref",[485,1596,698],{"class":531},[485,1598,1589],{"class":495},[485,1600,1601,1604],{"class":487,"line":574},[485,1602,1603],{"class":540},"  assets",[485,1605,690],{"class":531},[485,1607,1608,1611],{"class":487,"line":580},[485,1609,1610],{"class":540},"    links",[485,1612,690],{"class":531},[485,1614,1615,1618,1621,1623],{"class":487,"line":586},[485,1616,1617],{"class":531},"      - ",[485,1619,1620],{"class":540},"name",[485,1622,698],{"class":531},[485,1624,1625],{"class":495},"'Container Image'\n",[485,1627,1628,1631,1633],{"class":487,"line":596},[485,1629,1630],{"class":540},"        url",[485,1632,698],{"class":531},[485,1634,1635],{"class":495},"'$CI_REGISTRY_IMAGE/main:$CI_COMMIT_TAG'\n",[485,1637,1638,1641,1643],{"class":487,"line":606},[485,1639,1640],{"class":540},"        link_type",[485,1642,698],{"class":531},[485,1644,1645],{"class":495},"'image'\n",[13,1647,1648],{},"Für die automatische Erzeugung von Versionshinweisen basierend auf Commit-Nachrichten:",[476,1650,1652],{"className":678,"code":1651,"language":680,"meta":481,"style":481},"release:\n  name: 'Release $CI_COMMIT_TAG'\n  description: 'Release notes for version $CI_COMMIT_TAG'\n  tag_name: '$CI_COMMIT_TAG'\n  ref: '$CI_COMMIT_TAG'\n  auto_generate_release_notes: true    # Enables automatic notes\n",[215,1653,1654,1660,1668,1677,1685,1693],{"__ignoreMap":481},[485,1655,1656,1658],{"class":487,"line":488},[485,1657,1413],{"class":540},[485,1659,690],{"class":531},[485,1661,1662,1664,1666],{"class":487,"line":502},[485,1663,1566],{"class":540},[485,1665,698],{"class":531},[485,1667,1512],{"class":495},[485,1669,1670,1672,1674],{"class":487,"line":509},[485,1671,1575],{"class":540},[485,1673,698],{"class":531},[485,1675,1676],{"class":495},"'Release notes for version $CI_COMMIT_TAG'\n",[485,1678,1679,1681,1683],{"class":487,"line":557},[485,1680,1584],{"class":540},[485,1682,698],{"class":531},[485,1684,1589],{"class":495},[485,1686,1687,1689,1691],{"class":487,"line":568},[485,1688,1594],{"class":540},[485,1690,698],{"class":531},[485,1692,1589],{"class":495},[485,1694,1695,1698,1700,1703],{"class":487,"line":574},[485,1696,1697],{"class":540},"  auto_generate_release_notes",[485,1699,698],{"class":531},[485,1701,1702],{"class":977},"true",[485,1704,1705],{"class":505},"    # Enables automatic notes\n",[13,1707,1708],{},"Für aussagekräftige automatisierte Versionshinweise:",[25,1710,1711,1714,1717],{},[28,1712,1713],{},"herkömmliche Commits verwenden (feat:, fix:, etc.)",[28,1715,1716],{},"Issue-Nummern einschließen (#123)",[28,1718,1719],{},"Betreff mit leerer Zeile vom Text trennen",[13,1721,1722],{},"Wenn du benutzerdefinierte Versionshinweise mit Bereitstellungsinformationen möchtest:",[476,1724,1727],{"className":1725,"code":1726,"language":651,"meta":481},[649],"release_job:\n  script:\n    - |\n      DEPLOY_TIME=$(date '+%Y-%m-%d %H:%M:%S')\n      CHANGES=$(git log $(git describe --tags --abbrev=0 @^)..@ --pretty=format:\"- %s\")\n      cat > release_notes.md \u003C\u003C EOF\n      ## Deployment Info\n      - Deployed on: $DEPLOY_TIME\n      - Environment: Production\n      - Version: $CI_COMMIT_TAG\n\n      ## Changes\n      $CHANGES\n\n      ## Artifacts\n      - Container Image: \\`$CI_REGISTRY_IMAGE/main:$CI_COMMIT_TAG\\`\n      EOF\n  release:\n    description: './release_notes.md'\n",[215,1728,1726],{"__ignoreMap":481},[13,1730,1731,1732,1735],{},"Nach der Konfiguration werden Releases automatisch erstellt, wenn du ein Git-Tag erstellst. Du kannst sie in GitLab unter ",[382,1733,1734],{},"Bereitstellen > Releases"," anzeigen.",[198,1737,1739],{"id":1738},"_9-alles-zusammensetzen","9. Alles zusammensetzen",[13,1741,1742],{},"So sieht unsere finale YAML-Datei aus:",[476,1744,1747],{"className":1745,"code":1746,"language":651,"meta":481},[649],"variables:\n  TAG_LATEST: $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_NAME:latest\n  TAG_COMMIT: $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_NAME:$CI_COMMIT_SHA\n  STAGING_TARGET: $STAGING_TARGET    # Set in CI/CD Variables\n  PRODUCTION_TARGET: $PRODUCTION_TARGET  # Set in CI/CD Variables\n\nstages:\n  - publish\n  - staging\n  - release\n  - version\n  - production\n\n# Build and publish to registry\npublish:\n  stage: publish\n  image: docker:latest\n  services:\n    - docker:dind\n  rules:\n    - if: $CI_COMMIT_BRANCH == \"main\" && $CI_COMMIT_TAG == null\n  script:\n    - docker build -t $TAG_LATEST -t $TAG_COMMIT .\n    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY\n    - docker push $TAG_LATEST\n    - docker push $TAG_COMMIT\n\n# Deploy to staging\nstaging:\n  stage: staging\n  image: alpine:latest\n  rules:\n    - if: $CI_COMMIT_BRANCH == \"main\" && $CI_COMMIT_TAG == null\n  script:\n    - chmod 400 $GITLAB_KEY\n    - apk add openssh-client\n    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY\n    - ssh -i $GITLAB_KEY -o StrictHostKeyChecking=no $USER@$STAGING_TARGET \"\n        docker pull $TAG_COMMIT &&\n        docker rm -f myapp || true &&\n        docker run -d -p 80:80 --name myapp $TAG_COMMIT\"\n  environment:\n    name: staging\n    url: http://$STAGING_TARGET\n\n# Create release\nrelease_job:\n  stage: release\n  image: registry.gitlab.com/gitlab-org/release-cli:latest\n  rules:\n    - if: $CI_COMMIT_TAG\n  script:\n    - |\n      DEPLOY_TIME=$(date '+%Y-%m-%d %H:%M:%S')\n      CHANGES=$(git log $(git describe --tags --abbrev=0 @^)..@ --pretty=format:\"- %s\")\n      cat > release_notes.md \u003C\u003C EOF\n      ## Deployment Info\n      - Deployed on: $DEPLOY_TIME\n      - Environment: Production\n      - Version: $CI_COMMIT_TAG\n\n      ## Changes\n      $CHANGES\n\n      ## Artifacts\n       - Container Image: \\`$CI_REGISTRY_IMAGE/main:$CI_COMMIT_TAG\\`\n      EOF\n  release:\n    name: 'Release $CI_COMMIT_TAG'\n    description: './release_notes.md'\n    tag_name: '$CI_COMMIT_TAG'\n    ref: '$CI_COMMIT_TAG'\n    assets:\n      links:\n        - name: 'Container Image'\n          url: '$CI_REGISTRY_IMAGE/main:$CI_COMMIT_TAG'\n          link_type: 'image'\n\n# Version the image with release tag\nversion_job:\n  stage: version\n  image: docker:latest\n  services:\n    - docker:dind\n  rules:\n    - if: $CI_COMMIT_TAG\n  script:\n    - docker pull $TAG_COMMIT\n    - docker tag $TAG_COMMIT $CI_REGISTRY_IMAGE/main:$CI_COMMIT_TAG\n    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY\n    - docker push $CI_REGISTRY_IMAGE/main:$CI_COMMIT_TAG\n\n# Deploy to production\nproduction:\n  stage: production\n  image: alpine:latest\n  rules:\n    - if: $CI_COMMIT_TAG\n  script:\n    - chmod 400 $GITLAB_KEY\n    - apk add openssh-client\n    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY\n    - ssh -i $GITLAB_KEY -o StrictHostKeyChecking=no $USER@$PRODUCTION_TARGET \"\n        docker pull $CI_REGISTRY_IMAGE/main:$CI_COMMIT_TAG &&\n        docker rm -f myapp || true &&\n        docker run -d -p 80:80 --name myapp $CI_REGISTRY_IMAGE/main:$CI_COMMIT_TAG\"\n  environment:\n    name: production\n    url: http://$PRODUCTION_TARGET\n",[215,1748,1746],{"__ignoreMap":481},[13,1750,1751],{},"Diese komplette Pipeline:",[25,1753,1754,1757,1760,1763,1766],{},[28,1755,1756],{},"veröffentlicht Images im Registry (Main-Branch)",[28,1758,1759],{},"stellt das Staging bereit (Main-Branch)",[28,1761,1762],{},"erstellt Releases (mit Tags)",[28,1764,1765],{},"bietet die Versionsverwaltung von Images mit Release-Tags",[28,1767,1768],{},"Stellt die Produktion bereit (für Tags)",[13,1770,1771],{},"Hauptvorteile:",[25,1773,1774,1777,1780,1783],{},[28,1775,1776],{},"Saubere, reproduzierbare, lokale Entwicklungs- und Testumgebung",[28,1778,1779],{},"Klarer Pfad zu Produktionsumgebungen mit Struktur, um Vertrauen in die Bereitstellung aufzubauen",[28,1781,1782],{},"Muster zur Wiederherstellung nach unerwarteten Fehlern usw.",[28,1784,1785],{},"Bereit, komplexere Bereitstellungsstrategien zu skalieren/zu übernehmen",[148,1787,102],{"id":1788},"best-practices",[13,1790,1791],{},"Während der gesamten Implementierung solltest du diese Grundsätze einhalten:",[25,1793,1794,1797,1800,1803,1806],{},[28,1795,1796],{},"Dokumentiere alles, von der variablen Nutzung bis hin zu Bereitstellungsverfahren",[28,1798,1799],{},"Nutze die integrierten Funktionen von GitLab (Umgebungen, Releases, Registry)",[28,1801,1802],{},"Implementiere ordnungsgemäße Zugriffskontrollen und Sicherheitsmaßnahmen",[28,1804,1805],{},"Sorge für Ausfälle mit robusten Rollback-Verfahren vor",[28,1807,1808],{},"Halte deine Pipeline-Konfigurationen SAUBER (wiederhole dich nicht)",[1810,1811,1812],"blockquote",{},[13,1813,1814,1817,1818],{},[382,1815,1816],{},"12x kürzere Bereitstellungszeit: Dank GitLabs vollständiger Integration lebt Hilti Effizienz",". GitLab bringt vollständige Transparenz, eine umfassende Codeverwaltung und umfangreiche Sicherheitsscans mit, um Hilti neue Softwarefähigkeiten zu ermöglichen. Erfahre, wie Hilti seine Softwareentwicklung revolutioniert hat. ",[382,1819,1820],{},[31,1821,1824],{"href":1822,"rel":1823},"https://about.gitlab.com/de-de/customers/hilti/",[],"Erfolgsstory lesen",[20,1826,108],{"id":1827},"skaliere-deine-bereitstellungsstrategie",[13,1829,1830],{},"Wie geht es weiter? Hier sind einige Aspekte, die du berücksichtigen solltest, wenn deine kontinuierliche Bereitstellungsstrategie ausgereift ist.",[148,1832,116],{"id":1833},"erweiterte-sicherheitsmaßnahmen",[13,1835,1836],{},"Erhöhe die Sicherheit durch:",[25,1838,1839,1842,1845,1848,1851],{},[28,1840,1841],{},"Geschützte Umgebungen mit eingeschränktem Zugang",[28,1843,1844],{},"Erforderliche Genehmigungen für Produktionseinsätze",[28,1846,1847],{},"Integriertes Sicherheitsscannen",[28,1849,1850],{},"Automatisierte Schwachstellenbewertungen",[28,1852,1853],{},"Branch-Schutzregeln für einsatzbedingte Änderungen",[148,1855,122],{"id":1856},"progressive-bereitstellungsstrategien",[13,1858,1859],{},"Implementiere erweiterte Bereitstellungsstrategien:",[25,1861,1862,1865,1868,1871,1874],{},[28,1863,1864],{},"Feature-Flags für kontrollierte Rollouts",[28,1866,1867],{},"Canary-Bereitstellungen zur Risikominderung",[28,1869,1870],{},"Blaugrüne Bereitstellungsstrategien",[28,1872,1873],{},"A/B-Testfähigkeiten",[28,1875,1876],{},"Dynamisches Umgebungsmanagement",[148,1878,128],{"id":1879},"überwachung-und-optimierung",[13,1881,1882],{},"Etabliere robuste Überwachungspraktiken:",[25,1884,1885,1888,1891,1894,1897],{},[28,1886,1887],{},"Verfolge Bereitstellungsmetriken nach",[28,1889,1890],{},"Richte eine Leistungsüberwachung ein",[28,1892,1893],{},"Konfiguriere Bereitstellungswarnungen",[28,1895,1896],{},"Richte Bereitstellungs-SLOs ein",[28,1898,1899],{},"Regelmäßige Pipeline-Optimierung",[20,1901,134],{"id":1902},"warum-gitlab",[13,1904,1905],{},"Durch die kontinuierlichen Bereitstellungsfunktionen ist GitLab eine herausragende Wahl für moderne Bereitstellungsworkflows. Die Plattform zeichnet sich dadurch aus, dass sie den Weg vom Code bis zur Produktion optimiert und eine integrierte Container-Registrierung, ein Umgebungsmanagement und eine Nachverfolgung der Bereitstellung innerhalb einer einzigen Benutzeroberfläche bietet. Die umgebungsspezifischen Variablen von GitLab, die Approval-Gates für die Bereitstellung und die Rollback-Funktionen bieten die Sicherheit und Kontrolle, die für Produktionsbereitstellungen erforderlich sind, während Funktionen wie Review-Apps und Feature-Flags progressive Bereitstellungsansätze ermöglichen. Als Teil der kompletten DevSecOps-Plattform von GitLab lassen sich diese CD-Funktionen nahtlos in deinen gesamten Software-Lebenszyklus integrieren.",[20,1907,140],{"id":1908},"noch-heute-starten",[13,1910,1911],{},"Der Weg zur kontinuierlichen Bereitstellung ist eine Evolution, keine Revolution. Beginne mit den Grundlagen, baue eine solide Grundlage auf und integriere nach und nach erweiterte Funktionen, wenn die Anforderungen deines Teams wachsen. GitLab bietet die Tools und die Flexibilität, um dich in jeder Phase dieser Reise zu unterstützen, von deiner ersten automatisierten Bereitstellung bis hin zu komplexen Bereitstellungspipelines für mehrere Umgebungen.",[1810,1913,1914],{},[13,1915,1916,1917,1922],{},"Melde dich für eine ",[31,1918,1921],{"href":1919,"rel":1920},"https://about.gitlab.com/free-trial/devsecops/",[],"kostenlose Testversion von GitLab Ultimate"," an, um noch heute mit der kontinuierlichen Bereitstellung zu beginnen.",[563,1924,1925],{},"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 .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}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 .sgsFI, html code.shiki .sgsFI{--shiki-default:#24292E}html pre.shiki code .shJU0, html code.shiki .shJU0{--shiki-default:#22863A}html pre.shiki code .sYu0t, html code.shiki .sYu0t{--shiki-default:#005CC5}",{"title":481,"searchDepth":502,"depth":502,"links":1927},[1928,1929,1934,1938,1943,1944],{"id":22,"depth":502,"text":23},{"id":143,"depth":502,"text":34,"children":1930},[1931,1932,1933],{"id":150,"depth":509,"text":42},{"id":297,"depth":509,"text":68},{"id":317,"depth":509,"text":74},{"id":340,"depth":502,"text":80,"children":1935},[1936,1937],{"id":343,"depth":509,"text":88},{"id":1788,"depth":509,"text":102},{"id":1827,"depth":502,"text":108,"children":1939},[1940,1941,1942],{"id":1833,"depth":509,"text":116},{"id":1856,"depth":509,"text":122},{"id":1879,"depth":509,"text":128},{"id":1902,"depth":502,"text":134},{"id":1908,"depth":502,"text":140},"product","2025-01-28","Erfahre, wie du mit dem Aufbau einer robusten Pipeline für die kontinuierliche Bereitstellung in GitLab beginnen kannst. In diesem Artikel findest du Schritt-für-Schritt-Anleitungen, praktische Beispiele und Best Practices.","md",null,false,"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749659478/Blog/Hero%20Images/REFERENCE_-_Use_this_page_as_a_reference_for_thumbnail_sizes.png",{},"/de-de/blog/from-code-to-production-a-guide-to-continuous-deployment-with-gitlab",{"ogTitle":1955,"ogImage":1951,"ogDescription":1947,"ogSiteName":1956,"noIndex":1950,"ogType":1957,"ogUrl":1958,"title":1955,"canonicalUrls":1958,"description":1947},"Leitfaden: Kontinuierliche Bereitstellung mit GitLab","https://about.gitlab.com","article","https://about.gitlab.com/blog/from-code-to-production-a-guide-to-continuous-deployment-with-gitlab","from-code-to-production-a-guide-to-continuous-deployment-with-gitlab","de-de/blog/from-code-to-production-a-guide-to-continuous-deployment-with-gitlab",[1962,1963,1964,1945,1965],"CD","CI/CD","features","tutorial","BlogPost","2025-05-14","bgYdejl4TJ9bevnRRy4v38H-AEW-1jLTWkOkUsGHnPI",{"logo":1970,"freeTrial":1975,"sales":1980,"login":1985,"items":1990,"search":2318,"minimal":2352,"duo":2370,"switchNav":2379,"pricingDeployment":2390},{"config":1971},{"href":1972,"dataGaName":1973,"dataGaLocation":1974},"/de-de/","gitlab logo","header",{"text":1976,"config":1977},"Kostenlose Testversion anfordern",{"href":1978,"dataGaName":1979,"dataGaLocation":1974},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/de-de&glm_content=default-saas-trial/","free trial",{"text":1981,"config":1982},"Demo anfordern",{"href":1983,"dataGaName":1984,"dataGaLocation":1974},"/de-de/sales/?contact-topic=request-demo","sales",{"text":1986,"config":1987},"Anmelden",{"href":1988,"dataGaName":1989,"dataGaLocation":1974},"https://gitlab.com/users/sign_in/","sign in",[1991,2020,2121,2126,2240,2296],{"text":1992,"config":1993,"menu":1995},"Plattform",{"dataNavLevelOne":1994},"platform",{"type":1996,"columns":1997},"cards",[1998,2004,2012],{"title":1992,"description":1999,"link":2000},"Die intelligente Orchestrierungsplattform für DevSecOps",{"text":2001,"config":2002},"Die Plattform erkunden",{"href":2003,"dataGaName":1994,"dataGaLocation":1974},"/de-de/platform/",{"title":2005,"description":2006,"link":2007},"GitLab Duo Agent Platform","Agentische KI für den gesamten Software-Lebenszyklus",{"text":2008,"config":2009},"Lerne GitLab Duo kennen",{"href":2010,"dataGaName":2011,"dataGaLocation":1974},"/de-de/gitlab-duo-agent-platform/","gitlab duo agent platform",{"title":2013,"description":2014,"link":2015},"Warum GitLab?","Erfahre, warum sich Unternehmen für GitLab entscheiden",{"text":2016,"config":2017},"Mehr erfahren",{"href":2018,"dataGaName":2019,"dataGaLocation":1974},"/de-de/why-gitlab/","why gitlab",{"text":2021,"left":716,"config":2022,"menu":2024},"Produkt",{"dataNavLevelOne":2023},"solutions",{"type":2025,"link":2026,"columns":2030,"feature":2100},"lists",{"text":2027,"config":2028},"Alle Lösungen anzeigen",{"href":2029,"dataGaName":2023,"dataGaLocation":1974},"/de-de/solutions/",[2031,2055,2078],{"title":2032,"description":2033,"link":2034,"items":2039},"Automatisierung","CI/CD und Automatisierung zur Beschleunigung der Bereitstellung",{"config":2035},{"icon":2036,"href":2037,"dataGaName":2038,"dataGaLocation":1974},"AutomatedCodeAlt","/de-de/solutions/delivery-automation/","automated software delivery",[2040,2043,2046,2051],{"text":1963,"config":2041},{"href":2042,"dataGaLocation":1974,"dataGaName":1963},"/de-de/solutions/continuous-integration/",{"text":2005,"config":2044},{"href":2010,"dataGaLocation":1974,"dataGaName":2045},"gitlab duo agent platform - product menu",{"text":2047,"config":2048},"Quellcodeverwaltung",{"href":2049,"dataGaLocation":1974,"dataGaName":2050},"/de-de/solutions/source-code-management/","Source Code Management",{"text":2052,"config":2053},"Automatische Softwarebereitstellung",{"href":2037,"dataGaLocation":1974,"dataGaName":2054},"Automated software delivery",{"title":2056,"description":2057,"link":2058,"items":2063},"Sicherheit","Entwickle Code schneller ohne Abstriche bei der Sicherheit",{"config":2059},{"href":2060,"dataGaName":2061,"dataGaLocation":1974,"icon":2062},"/de-de/solutions/application-security-testing/","security and compliance","ShieldCheckLight",[2064,2068,2073],{"text":2065,"config":2066},"Anwendungssicherheitstests",{"href":2060,"dataGaName":2067,"dataGaLocation":1974},"Application security testing",{"text":2069,"config":2070},"Schutz der Software-Lieferkette",{"href":2071,"dataGaLocation":1974,"dataGaName":2072},"/de-de/solutions/supply-chain/","Software supply chain security",{"text":2074,"config":2075},"Software-Compliance",{"href":2076,"dataGaName":2077,"dataGaLocation":1974},"/de-de/solutions/software-compliance/","software compliance",{"title":2079,"link":2080,"items":2085},"Messung",{"config":2081},{"icon":2082,"href":2083,"dataGaName":2084,"dataGaLocation":1974},"DigitalTransformation","/de-de/solutions/visibility-measurement/","visibility and measurement",[2086,2090,2095],{"text":2087,"config":2088},"Sichtbarkeit und Messung",{"href":2083,"dataGaLocation":1974,"dataGaName":2089},"Visibility and Measurement",{"text":2091,"config":2092},"Wertstrommanagement",{"href":2093,"dataGaLocation":1974,"dataGaName":2094},"/de-de/solutions/value-stream-management/","Value Stream Management",{"text":2096,"config":2097},"Analysen und Einblicke",{"href":2098,"dataGaLocation":1974,"dataGaName":2099},"/de-de/solutions/analytics-and-insights/","Analytics and insights",{"title":2101,"type":2025,"items":2102},"GitLab für",[2103,2109,2115],{"text":2104,"config":2105},"Enterprise",{"icon":2106,"href":2107,"dataGaLocation":1974,"dataGaName":2108},"Building","/de-de/enterprise/","enterprise",{"text":2110,"config":2111},"Kleinunternehmen",{"icon":2112,"href":2113,"dataGaLocation":1974,"dataGaName":2114},"Work","/de-de/small-business/","small business",{"text":2116,"config":2117},"Öffentlicher Sektor",{"icon":2118,"href":2119,"dataGaLocation":1974,"dataGaName":2120},"Organization","/de-de/solutions/public-sector/","public sector",{"text":2122,"config":2123},"Preise",{"href":2124,"dataGaName":2125,"dataGaLocation":1974,"dataNavLevelOne":2125},"/de-de/pricing/","pricing",{"text":2127,"config":2128,"menu":2130},"Ressourcen",{"dataNavLevelOne":2129},"resources",{"type":2025,"link":2131,"columns":2135,"feature":2229},{"text":2132,"config":2133},"Alle Ressourcen anzeigen",{"href":2134,"dataGaName":2129,"dataGaLocation":1974},"/de-de/resources/",[2136,2169,2196],{"title":2137,"items":2138},"Erste Schritte",[2139,2144,2149,2154,2159,2164],{"text":2140,"config":2141},"Installieren",{"href":2142,"dataGaName":2143,"dataGaLocation":1974},"/de-de/install/","install",{"text":2145,"config":2146},"Kurzanleitungen",{"href":2147,"dataGaName":2148,"dataGaLocation":1974},"/de-de/get-started/","quick setup checklists",{"text":2150,"config":2151},"Lernen",{"href":2152,"dataGaLocation":1974,"dataGaName":2153},"https://university.gitlab.com/","learn",{"text":2155,"config":2156},"Produktdokumentation",{"href":2157,"dataGaName":2158,"dataGaLocation":1974},"https://docs.gitlab.com/","product documentation",{"text":2160,"config":2161},"Best-Practice-Videos",{"href":2162,"dataGaName":2163,"dataGaLocation":1974},"/de-de/getting-started-videos/","best practice videos",{"text":2165,"config":2166},"Integrationen",{"href":2167,"dataGaName":2168,"dataGaLocation":1974},"/de-de/integrations/","integrations",{"title":2170,"items":2171},"Entdecken",[2172,2177,2182,2187,2191],{"text":2173,"config":2174},"Kundenerfolge",{"href":2175,"dataGaName":2176,"dataGaLocation":1974},"/de-de/customers/","customer success stories",{"text":2178,"config":2179},"Blog",{"href":2180,"dataGaName":2181,"dataGaLocation":1974},"/de-de/blog/","blog",{"text":2183,"config":2184},"Demo-Hub",{"href":2185,"dataGaName":2186,"dataGaLocation":1974},"/de-de/demo-hub/","demo hub",{"text":2188,"config":2189},"The Source",{"href":2190,"dataGaName":2181,"dataGaLocation":1974},"/de-de/the-source/",{"text":2192,"config":2193},"Remote",{"href":2194,"dataGaName":2195,"dataGaLocation":1974},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"title":2197,"items":2198},"Vernetzen",[2199,2204,2209,2214,2219,2224],{"text":2200,"config":2201},"GitLab-Services",{"href":2202,"dataGaName":2203,"dataGaLocation":1974},"/de-de/services/","services",{"text":2205,"config":2206},"Beitragen",{"href":2207,"dataGaName":2208,"dataGaLocation":1974},"https://contributors.gitlab.com","contribute",{"text":2210,"config":2211},"Community",{"href":2212,"dataGaName":2213,"dataGaLocation":1974},"/community/","community",{"text":2215,"config":2216},"Forum",{"href":2217,"dataGaName":2218,"dataGaLocation":1974},"https://forum.gitlab.com/","forum",{"text":2220,"config":2221},"Veranstaltungen",{"href":2222,"dataGaName":2223,"dataGaLocation":1974},"/events/","events",{"text":2225,"config":2226},"Partner",{"href":2227,"dataGaName":2228,"dataGaLocation":1974},"/de-de/partners/","partners",{"config":2230,"title":2233,"text":2234,"link":2235},{"background":2231,"textColor":2232},"url('https://res.cloudinary.com/about-gitlab-com/image/upload/v1777322348/qpq8yrgn8knii57omj0c.png')","#000","Neues bei GitLab","Über die neuesten Funktionen und Verbesserungen auf dem Laufenden bleiben.",{"text":2236,"config":2237},"Aktuelle Nachrichten",{"href":2238,"dataGaName":2239,"dataGaLocation":1974},"/de-de/whats-new/","whats new",{"text":2241,"config":2242,"menu":2244},"Unternehmen",{"dataNavLevelOne":2243},"company",{"type":2025,"columns":2245},[2246],{"items":2247},[2248,2253,2259,2261,2266,2271,2276,2281,2286,2291],{"text":2249,"config":2250},"Über",{"href":2251,"dataGaName":2252,"dataGaLocation":1974},"/de-de/company/","about",{"text":2254,"config":2255,"footerGa":2258},"Karriere",{"href":2256,"dataGaName":2257,"dataGaLocation":1974},"/jobs/","jobs",{"dataGaName":2257},{"text":2220,"config":2260},{"href":2222,"dataGaName":2223,"dataGaLocation":1974},{"text":2262,"config":2263},"Geschäftsführung",{"href":2264,"dataGaName":2265,"dataGaLocation":1974},"/company/team/e-group/","leadership",{"text":2267,"config":2268},"Handbuch",{"href":2269,"dataGaName":2270,"dataGaLocation":1974},"https://handbook.gitlab.com/","handbook",{"text":2272,"config":2273},"Investor Relations",{"href":2274,"dataGaName":2275,"dataGaLocation":1974},"https://ir.gitlab.com/overview/default.aspx","investor relations",{"text":2277,"config":2278},"Trust Center",{"href":2279,"dataGaName":2280,"dataGaLocation":1974},"/de-de/security/","trust center",{"text":2282,"config":2283},"AI Transparency Center",{"href":2284,"dataGaName":2285,"dataGaLocation":1974},"/de-de/ai-transparency-center/","ai transparency center",{"text":2287,"config":2288},"Newsletter",{"href":2289,"dataGaName":2290,"dataGaLocation":1974},"/company/contact/#contact-forms","newsletter",{"text":2292,"config":2293},"Presse",{"href":2294,"dataGaName":2295,"dataGaLocation":1974},"/press/","press",{"text":2297,"config":2298,"menu":2299},"Kontakt",{"dataNavLevelOne":2243},{"type":2025,"columns":2300},[2301],{"items":2302},[2303,2308,2313],{"text":2304,"config":2305},"Vertrieb kontaktieren",{"href":2306,"dataGaName":2307,"dataGaLocation":1974},"/de-de/sales/","talk to sales",{"text":2309,"config":2310},"Support-Portal",{"href":2311,"dataGaName":2312,"dataGaLocation":1974},"https://support.gitlab.com/hc/en-us","support portal",{"text":2314,"config":2315},"Kundenportal",{"href":2316,"dataGaName":2317,"dataGaLocation":1974},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":2319,"login":2320,"suggestions":2327},"Schließen",{"text":2321,"link":2322},"Um Repositorys und Projekte zu durchsuchen, melde dich an bei",{"text":2323,"config":2324},"gitlab.com",{"href":1988,"dataGaName":2325,"dataGaLocation":2326},"search login","search",{"text":2328,"default":2329},"Vorschläge",[2330,2332,2337,2339,2344,2349],{"text":2005,"config":2331},{"href":2010,"dataGaName":2005,"dataGaLocation":2326},{"text":2333,"config":2334},"Codevorschläge (KI)",{"href":2335,"dataGaName":2336,"dataGaLocation":2326},"/de-de/solutions/code-suggestions/","Code Suggestions (AI)",{"text":1963,"config":2338},{"href":2042,"dataGaName":1963,"dataGaLocation":2326},{"text":2340,"config":2341},"GitLab auf AWS",{"href":2342,"dataGaName":2343,"dataGaLocation":2326},"/de-de/partners/technology-partners/aws/","GitLab on AWS",{"text":2345,"config":2346},"GitLab auf Google Cloud",{"href":2347,"dataGaName":2348,"dataGaLocation":2326},"/de-de/partners/technology-partners/google-cloud-platform/","GitLab on Google Cloud",{"text":2013,"config":2350},{"href":2018,"dataGaName":2351,"dataGaLocation":2326},"Why GitLab?",{"freeTrial":2353,"mobileIcon":2358,"desktopIcon":2363,"secondaryButton":2366},{"text":2354,"config":2355},"Kostenlos testen",{"href":2356,"dataGaName":1979,"dataGaLocation":2357},"https://gitlab.com/-/trials/new/","nav",{"altText":2359,"config":2360},"GitLab-Symbol",{"src":2361,"dataGaName":2362,"dataGaLocation":2357},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":2359,"config":2364},{"src":2365,"dataGaName":2362,"dataGaLocation":2357},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":2137,"config":2367},{"href":2368,"dataGaName":2369,"dataGaLocation":2357},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/de-de/get-started/","get started",{"freeTrial":2371,"mobileIcon":2375,"desktopIcon":2377},{"text":2372,"config":2373},"Mehr über GitLab Duo erfahren",{"href":2010,"dataGaName":2374,"dataGaLocation":2357},"gitlab duo",{"altText":2359,"config":2376},{"src":2361,"dataGaName":2362,"dataGaLocation":2357},{"altText":2359,"config":2378},{"src":2365,"dataGaName":2362,"dataGaLocation":2357},{"button":2380,"mobileIcon":2385,"desktopIcon":2387},{"text":2381,"config":2382},"/Option",{"href":2383,"dataGaName":2384,"dataGaLocation":2357},"#contact","switch",{"altText":2359,"config":2386},{"src":2361,"dataGaName":2362,"dataGaLocation":2357},{"altText":2359,"config":2388},{"src":2389,"dataGaName":2362,"dataGaLocation":2357},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1773335277/ohhpiuoxoldryzrnhfrh.png",{"freeTrial":2391,"mobileIcon":2396,"desktopIcon":2398},{"text":2392,"config":2393},"Zurück zur Preisübersicht",{"href":2124,"dataGaName":2394,"dataGaLocation":2357,"icon":2395},"back to pricing","GoBack",{"altText":2359,"config":2397},{"src":2361,"dataGaName":2362,"dataGaLocation":2357},{"altText":2359,"config":2399},{"src":2365,"dataGaName":2362,"dataGaLocation":2357},{"title":2401,"button":2402,"config":2406},"GitLab Orbit ist da: die Kontextebene für KI-Agenten",{"text":2016,"config":2403},{"href":2404,"dataGaName":2405,"dataGaLocation":1974},"/de-de/gitlab-orbit/","orbit",{"layout":1413,"disabled":1950},{"data":2408},{"text":2409,"source":2410,"edit":2416,"contribute":2421,"config":2426,"items":2431,"minimal":2637},"Git ist eine Marke von Software Freedom Conservancy und unsere Verwendung von „GitLab“ erfolgt unter Lizenz.",{"text":2411,"config":2412},"Quelltext der Seite anzeigen",{"href":2413,"dataGaName":2414,"dataGaLocation":2415},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":2417,"config":2418},"Diese Seite bearbeiten",{"href":2419,"dataGaName":2420,"dataGaLocation":2415},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":2422,"config":2423},"Beteilige dich",{"href":2424,"dataGaName":2425,"dataGaLocation":2415},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":2427,"facebook":2428,"youtube":2429,"linkedin":2430},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[2432,2477,2530,2572,2604],{"title":2122,"links":2433,"subMenu":2448},[2434,2438,2443],{"text":2435,"config":2436},"Tarife anzeigen",{"href":2124,"dataGaName":2437,"dataGaLocation":2415},"view plans",{"text":2439,"config":2440},"Vorteile von Premium",{"href":2441,"dataGaName":2442,"dataGaLocation":2415},"/de-de/pricing/premium/","why premium",{"text":2444,"config":2445},"Vorteile von Ultimate",{"href":2446,"dataGaName":2447,"dataGaLocation":2415},"/de-de/pricing/ultimate/","why ultimate",[2449],{"title":2297,"links":2450},[2451,2453,2455,2457,2462,2467,2472],{"text":2304,"config":2452},{"href":2306,"dataGaName":1984,"dataGaLocation":2415},{"text":2309,"config":2454},{"href":2311,"dataGaName":2312,"dataGaLocation":2415},{"text":2314,"config":2456},{"href":2316,"dataGaName":2317,"dataGaLocation":2415},{"text":2458,"config":2459},"Status",{"href":2460,"dataGaName":2461,"dataGaLocation":2415},"https://status.gitlab.com/","status",{"text":2463,"config":2464},"Nutzungsbedingungen",{"href":2465,"dataGaName":2466,"dataGaLocation":2415},"/terms/","terms of use",{"text":2468,"config":2469},"Datenschutzerklärung",{"href":2470,"dataGaName":2471,"dataGaLocation":2415},"/de-de/privacy/","privacy statement",{"text":2473,"config":2474},"Cookie-Einstellungen",{"dataGaName":2475,"dataGaLocation":2415,"id":2476,"isOneTrustButton":716},"cookie preferences","ot-sdk-btn",{"title":2021,"links":2478,"subMenu":2487},[2479,2483],{"text":2480,"config":2481},"DevSecOps-Plattform",{"href":2003,"dataGaName":2482,"dataGaLocation":2415},"devsecops platform",{"text":2484,"config":2485},"KI-unterstützte Entwicklung",{"href":2010,"dataGaName":2486,"dataGaLocation":2415},"ai-assisted development",[2488],{"title":2489,"links":2490},"Themen",[2491,2495,2500,2505,2510,2515,2520,2525],{"text":1963,"config":2492},{"href":2493,"dataGaName":2494,"dataGaLocation":2415},"/de-de/topics/ci-cd/","cicd",{"text":2496,"config":2497},"GitOps",{"href":2498,"dataGaName":2499,"dataGaLocation":2415},"/de-de/topics/gitops/","gitops",{"text":2501,"config":2502},"DevOps",{"href":2503,"dataGaName":2504,"dataGaLocation":2415},"/de-de/topics/devops/","devops",{"text":2506,"config":2507},"Versionskontrolle",{"href":2508,"dataGaName":2509,"dataGaLocation":2415},"/de-de/topics/version-control/","version control",{"text":2511,"config":2512},"DevSecOps",{"href":2513,"dataGaName":2514,"dataGaLocation":2415},"/de-de/topics/devsecops/","devsecops",{"text":2516,"config":2517},"Cloud-nativ",{"href":2518,"dataGaName":2519,"dataGaLocation":2415},"/de-de/topics/cloud-native/","cloud native",{"text":2521,"config":2522},"KI für das Programmieren",{"href":2523,"dataGaName":2524,"dataGaLocation":2415},"/de-de/topics/devops/ai-for-coding/","ai for coding",{"text":2526,"config":2527},"Agentische KI",{"href":2528,"dataGaName":2529,"dataGaLocation":2415},"/de-de/topics/agentic-ai/","agentic ai",{"title":2531,"links":2532},"Lösungen",[2533,2536,2538,2543,2547,2550,2553,2556,2558,2560,2562,2567],{"text":2065,"config":2534},{"href":2060,"dataGaName":2535,"dataGaLocation":2415},"Application Security Testing",{"text":2052,"config":2537},{"href":2037,"dataGaName":2038,"dataGaLocation":2415},{"text":2539,"config":2540},"Agile Entwicklung",{"href":2541,"dataGaName":2542,"dataGaLocation":2415},"/de-de/solutions/agile-delivery/","agile delivery",{"text":2544,"config":2545},"SCM",{"href":2049,"dataGaName":2546,"dataGaLocation":2415},"source code management",{"text":1963,"config":2548},{"href":2042,"dataGaName":2549,"dataGaLocation":2415},"continuous integration & delivery",{"text":2091,"config":2551},{"href":2093,"dataGaName":2552,"dataGaLocation":2415},"value stream management",{"text":2496,"config":2554},{"href":2555,"dataGaName":2499,"dataGaLocation":2415},"/de-de/solutions/gitops/",{"text":2104,"config":2557},{"href":2107,"dataGaName":2108,"dataGaLocation":2415},{"text":2110,"config":2559},{"href":2113,"dataGaName":2114,"dataGaLocation":2415},{"text":2116,"config":2561},{"href":2119,"dataGaName":2120,"dataGaLocation":2415},{"text":2563,"config":2564},"Bildungswesen",{"href":2565,"dataGaName":2566,"dataGaLocation":2415},"/de-de/solutions/education/","education",{"text":2568,"config":2569},"Finanzdienstleistungen",{"href":2570,"dataGaName":2571,"dataGaLocation":2415},"/de-de/solutions/finance/","financial services",{"title":2127,"links":2573},[2574,2576,2578,2580,2583,2585,2588,2590,2592,2594,2596,2598,2600,2602],{"text":2140,"config":2575},{"href":2142,"dataGaName":2143,"dataGaLocation":2415},{"text":2145,"config":2577},{"href":2147,"dataGaName":2148,"dataGaLocation":2415},{"text":2150,"config":2579},{"href":2152,"dataGaName":2153,"dataGaLocation":2415},{"text":2155,"config":2581},{"href":2157,"dataGaName":2582,"dataGaLocation":2415},"docs",{"text":2178,"config":2584},{"href":2180,"dataGaName":2181,"dataGaLocation":2415},{"text":2586,"config":2587},"Neuerungen",{"href":2238,"dataGaName":2239,"dataGaLocation":2415},{"text":2173,"config":2589},{"href":2175,"dataGaName":2176,"dataGaLocation":2415},{"text":2192,"config":2591},{"href":2194,"dataGaName":2195,"dataGaLocation":2415},{"text":2200,"config":2593},{"href":2202,"dataGaName":2203,"dataGaLocation":2415},{"text":2205,"config":2595},{"href":2207,"dataGaName":2208,"dataGaLocation":2415},{"text":2210,"config":2597},{"href":2212,"dataGaName":2213,"dataGaLocation":2415},{"text":2215,"config":2599},{"href":2217,"dataGaName":2218,"dataGaLocation":2415},{"text":2220,"config":2601},{"href":2222,"dataGaName":2223,"dataGaLocation":2415},{"text":2225,"config":2603},{"href":2227,"dataGaName":2228,"dataGaLocation":2415},{"title":2241,"links":2605},[2606,2608,2610,2612,2614,2616,2621,2626,2628,2630,2632],{"text":2249,"config":2607},{"href":2251,"dataGaName":2243,"dataGaLocation":2415},{"text":2254,"config":2609},{"href":2256,"dataGaName":2257,"dataGaLocation":2415},{"text":2262,"config":2611},{"href":2264,"dataGaName":2265,"dataGaLocation":2415},{"text":2267,"config":2613},{"href":2269,"dataGaName":2270,"dataGaLocation":2415},{"text":2272,"config":2615},{"href":2274,"dataGaName":2275,"dataGaLocation":2415},{"text":2617,"config":2618},"Nachhaltigkeit",{"href":2619,"dataGaName":2620,"dataGaLocation":2415},"/sustainability/","Sustainability",{"text":2622,"config":2623},"Vielfalt, Inklusion und Zugehörigkeit",{"href":2624,"dataGaName":2625,"dataGaLocation":2415},"/de-de/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":2277,"config":2627},{"href":2279,"dataGaName":2280,"dataGaLocation":2415},{"text":2287,"config":2629},{"href":2289,"dataGaName":2290,"dataGaLocation":2415},{"text":2292,"config":2631},{"href":2294,"dataGaName":2295,"dataGaLocation":2415},{"text":2633,"config":2634},"Transparenzerklärung zu moderner Sklaverei",{"href":2635,"dataGaName":2636,"dataGaLocation":2415},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"items":2638},[2639,2642,2645],{"text":2640,"config":2641},"Terms",{"href":2465,"dataGaName":2466,"dataGaLocation":2415},{"text":2643,"config":2644},"Cookies",{"dataGaName":2475,"dataGaLocation":2415,"id":2476,"isOneTrustButton":716},{"text":2646,"config":2647},"Datenschutz",{"href":2470,"dataGaName":2471,"dataGaLocation":2415},[2649,2663],{"id":2650,"title":7,"body":1949,"config":2651,"content":2653,"description":1949,"extension":2657,"meta":2658,"navigation":716,"path":2659,"seo":2660,"stem":2661,"__hash__":2662},"blogAuthors/en-us/blog/authors/benjamin-skierlak.yml",{"template":2652},"BlogAuthor",{"name":7,"config":2654},{"headshot":2655,"ctfId":2656},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749659471/Blog/Author%20Headshots/Benjamin_Skierlak_headshot.png","Kzp6pkUjPORYYMoeLFPRf","yml",{},"/en-us/blog/authors/benjamin-skierlak",{},"en-us/blog/authors/benjamin-skierlak","RbLU9KGFtah9Juo58JyxfHHYNIU4fyzzOUb5p7-fubo",{"id":2664,"title":8,"body":1949,"config":2665,"content":2666,"description":1949,"extension":2657,"meta":2670,"navigation":716,"path":2671,"seo":2672,"stem":2673,"__hash__":2674},"blogAuthors/en-us/blog/authors/james-wormwell.yml",{"template":2652},{"name":8,"config":2667},{"headshot":2668,"ctfId":2669},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749659474/Blog/Author%20Headshots/james_wormwell_headshot.png","CPPijHb0Op5C5aVcvsOEf",{},"/en-us/blog/authors/james-wormwell",{},"en-us/blog/authors/james-wormwell","n6G4XENUWxgqOdCgfG0ECu0Uqj7qOS9zr3Rl8ouF49M",[2676,2684,2691],{"title":2677,"description":2678,"heroImage":2679,"category":1945,"date":2680,"authors":2681,"slug":2683,"externalUrl":1949},"DevOps Stack aufbauen: Häufige Fehler und Best Practices für moderne Toolchains","Ein DevOps Stack sollte mehr sein als eine Tool-Sammlung. Lerne, wie Teams häufige Fehler vermeiden und mit GitLab Toolchain-Komplexität reduzieren.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1775561395/bhe1as7ttjvzltxwgo5m.png","2026-08-07",[2682],"GitLab Germany Team","devops-stack",{"title":2685,"description":2686,"heroImage":2687,"category":1945,"date":2688,"authors":2689,"slug":2690,"externalUrl":1949},"Sechs Möglichkeiten, die DevOps Kosten zu senken, zu sparen und zu optimieren","Wir zeigen dir sechs Möglichkeiten, wie du deine DevOps Kosten senken kannst.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1775486753/cswmwtygkgkbdsibo09v.png","2026-07-20",[2682],"reduce-devops-costs",{"title":2692,"description":2693,"heroImage":2694,"category":1945,"date":2688,"authors":2695,"slug":2697,"externalUrl":1949},"Work Items automatisch zuweisen mit dem Trigger \"Work item created\"","Eine Schritt-für-Schritt-Anleitung zum neuen Trigger, der Work Items automatisch zuweist – skalierbare Triage ohne manuelles Eingreifen.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1773866173/vte9qh8rriznvyclhkes.png",[2696],"Cesar Saavedra","how-to-use-a-work-item-created-trigger",{"promotions":2699},[2700,2714,2725,2737],{"id":2701,"categories":2702,"header":2704,"text":2705,"button":2706,"image":2711},"ai-modernization",[2703],"ai","Hält KI, was uns versprochen wurde?","Das Quiz dauert maximal 5 Minuten.",{"text":2707,"config":2708},"Ermittle deinen KI-Reifegrad",{"href":2709,"dataGaName":2710,"dataGaLocation":2181},"/de-de/assessments/ai-modernization-assessment/","modernization assessment",{"config":2712},{"src":2713},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/qix0m7kwnd8x2fh1zq49.png",{"id":2715,"categories":2716,"header":2717,"text":2705,"button":2718,"image":2722},"devops-modernization",[1945,2514],"Verwaltest du Tool-Chaos oder stellst du Innovationen bereit?",{"text":2719,"config":2720},"Ermittle deinen DevOps-Reifegrad",{"href":2721,"dataGaName":2710,"dataGaLocation":2181},"/de-de/assessments/devops-modernization-assessment/",{"config":2723},{"src":2724},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138785/eg818fmakweyuznttgid.png",{"id":2726,"categories":2727,"header":2729,"text":2705,"button":2730,"image":2734},"security-modernization",[2728],"security","Tauschst du Schnelligkeit gegen Sicherheit ein?",{"text":2731,"config":2732},"Ermittle deinen Sicherheitsreifegrad",{"href":2733,"dataGaName":2710,"dataGaLocation":2181},"/de-de/assessments/security-modernization-assessment/",{"config":2735},{"src":2736},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/p4pbqd9nnjejg5ds6mdk.png",{"id":2738,"paths":2739,"header":2742,"text":2743,"button":2744,"image":2749},"github-azure-migration",[2740,2741],"migration-from-azure-devops-to-gitlab","integrating-azure-devops-scm-and-gitlab","Ist dein Team bereit für den Umzug von GitHub nach Azure?","GitHub stellt bereits auf Azure um. Finde heraus, was das für dich bedeutet.",{"text":2745,"config":2746},"Erfahre, wie GitLab im Vergleich zu GitHub abschneidet",{"href":2747,"dataGaName":2748,"dataGaLocation":2181},"/de-de/compare/gitlab-vs-github/github-azure-migration/","github azure migration",{"config":2750},{"src":2724},{"header":2752,"blurb":2753,"button":2754,"secondaryButton":2759},"Beginne noch heute, schneller zu entwickeln","Entdecke, was dein Team mit der intelligenten Orchestrierungsplattform für DevSecOps erreichen kann.\n",{"text":2755,"config":2756},"Kostenlosen Test starten",{"href":2757,"dataGaName":1979,"dataGaLocation":2758},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/de-de/","feature",{"text":2304,"config":2760},{"href":2306,"dataGaName":1984,"dataGaLocation":2758},1786803757946]