[{"data":1,"prerenderedAt":17012},["ShallowReactive",2],{"portfolio-de-slimspots":3,"employee-bernd-helm":352,"employee-daniel-walter":458,"related-refs-databases_devops-slimspots-de":496,"related-blog-databases_devops--de":512,"content-query-w8qtEh68yX":635,"content-query-K9Z9yOwvGV":1853,"content-query-G9vendBux1":6261,"content-query-hQiL1tjAhV":7341,"content-query-TVldk4ROTj":9626,"content-query-UKDfBsQuK3":11097,"content-query-6QVNjLYhQR":11630,"content-query-us0rrbF4qc":14544,"content-query-L6Pt7i9jc4":15813,"content-query-yFFm3xXL85":16365,"content-query-KtO3wftRle":16844,"content-query-vhr2h3d1hs":16913,"content-query-1PFeYVQSzn":16976},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":7,"subtitle":9,"heroImage":10,"areaOfApplication":11,"industry":12,"technologies":13,"period":17,"teamDescription":20,"budget":21,"tags":22,"body":25,"_type":346,"_id":347,"_source":348,"_file":349,"_stem":350,"_extension":351},"/portfolio/slimspots","portfolio",false,"","SlimSpots","VERARBEITUNG VON BILLIONEN DATENSÄTZEN IN ECHTZEIT","/images/portfolio/slimspots/slim_spots_prtfolio_phone.png","Ad-Marketing & Hochverfügbare Systeme","Online-Werbung und Marketing",[14,15,16],"linux","mariadb","php",{"from":18,"to":19},"September 2014","heute","2 Entwickler, 1 Projektleiter, 1 DevOps","sechstellig",[23,24],"databases","devops",{"type":26,"children":27,"toc":341},"root",[28,86,223,334],{"type":29,"tag":30,"props":31,"children":34},"element","section-component",{"className":32},[33],"no-pattern",[35,80],{"type":29,"tag":36,"props":37,"children":46},"v-card",{"className":38,"style":45},[39,40,41,42,43,44],"description__card","text-justify","px-4","px-md-18","py-4","py-md-14","background-color: rgba(var(--v-theme-primary), 0.1)",[47,60,70],{"type":29,"tag":48,"props":49,"children":50},"p",{},[51,58],{"type":29,"tag":52,"props":53,"children":54},"strong",{},[55],{"type":56,"value":57},"text","In der heutigen datengetriebenen Geschäftswelt ist die Fähigkeit, große Datenmengen in Echtzeit zu verarbeiten,\nein entscheidender Wettbewerbsvorteil.",{"type":56,"value":59}," SlimSpots, ein weltweit agierender Anbieter von Ad-Marketing-Lösungen, bringt\nTraffic-Lieferanten und Werbetreibende zusammen und benötigt dafür eine Infrastruktur, die nicht nur enorme Datenmengen\nbewältigen kann, sondern auch höchste Anforderungen an Skalierbarkeit, Verfügbarkeit und Geschwindigkeit erfüllt.",{"type":29,"tag":61,"props":62,"children":69},"img",{"alt":63,"aspect-ratio":64,"className":65,"object-fit":67,"src":68},"Slimspots Telefon mit KPIs","3",[66],"my-5","contain","/images/portfolio/slimspots/slim_spots_prtfolio.png",[],{"type":29,"tag":48,"props":71,"children":72},{},[73,78],{"type":29,"tag":52,"props":74,"children":75},{},[76],{"type":56,"value":77},"Unsere Aufgabe bestand darin, eine robuste, skalierbare Infrastruktur zu entwickeln und zu betreuen, die in\nMillisekunden Entscheidungen über die Auslieferung von Werbemitteln treffen und gleichzeitig Billionen von\nDatensätzen für detaillierte Analysen bereitstellen kann.",{"type":56,"value":79}," SlimSpots entscheidet für jeden Klick und Banner-View,\nwelche Werbung angezeigt wird – basierend auf Kriterien wie Browser, Gerät, Land, Internet-Provider, Uhrzeit,\nvorherigen Interaktionen und vielen weiteren Faktoren. Gleichzeitig müssen Traffic-Lieferanten und Werbetreibende\nin Echtzeit die Performance ihrer Kampagnen verfolgen können, um schnell auf Veränderungen reagieren zu können.",{"type":29,"tag":81,"props":82,"children":85},"v-divider",{"className":83},[84],"hw-my",[],{"type":29,"tag":30,"props":87,"children":88},{},[89,102,172],{"type":29,"tag":90,"props":91,"children":99},"h2",{"className":92,"id":98},[93,94,95,96,97],"justify-center","mt-12","mb-4","mb-md-8","pt-0","unsere-leistungen",[100],{"type":56,"value":101}," Unsere Leistungen ",{"type":29,"tag":36,"props":103,"children":109},{"className":104},[105,106,41,42,43,44,107,108],"background","transparent-4","mb-8","mb-md-12",[110,141],{"type":29,"tag":111,"props":112,"children":114},"v-row",{":no-gutters":113,"no-gutters":7},"true",[115,137],{"type":29,"tag":116,"props":117,"children":120},"v-col",{"cols":118,"md":119},12,"8",[121],{"type":29,"tag":122,"props":123,"children":125},"h3",{"id":124},"datenbank-und-serveradministration",[126],{"type":29,"tag":127,"props":128,"children":134},"span",{"className":129},[130,131,132,133],"w-100","text-center","mt-sm-n5","mt-md-n6",[135],{"type":56,"value":136},"Datenbank- und Serveradministration",{"type":29,"tag":116,"props":138,"children":140},{"cols":118,"md":139},"4",[],{"type":29,"tag":111,"props":142,"children":145},{"className":143},[144],"mt-0",[146,164],{"type":29,"tag":116,"props":147,"children":148},{"cols":118,"md":119},[149,154,159],{"type":29,"tag":48,"props":150,"children":151},{},[152],{"type":56,"value":153},"Für SlimSpots haben wir ein umfassendes System zur Datenbank- und Serveradministration implementiert,\ndas auf höchste Verfügbarkeit und Performance ausgerichtet ist. Im Zentrum unserer Lösung steht der Einsatz von\nMariaDB ColumnStore, einer spaltenbasierenden Datenbank, die speziell für die Verarbeitung enormer Datenmengen\nkonzipiert ist. Diese Technologie ermöglicht es, Abfragen auf mehrere Server und alle verfügbaren CPU-Kerne zu\nverteilen, was eine außergewöhnliche Skalierbarkeit gewährleistet.",{"type":29,"tag":48,"props":155,"children":156},{},[157],{"type":56,"value":158},"Die Implementierung einer spaltenbasierenden Datenbank bringt spezifische Herausforderungen mit sich, die wir durch\nsorgfältige Optimierung der Datenbankstruktur, der Abfragen und der Software gemeistert haben. Wir haben die Datenmodelle\nso gestaltet, dass sie optimal für analytische Abfragen geeignet sind, während gleichzeitig die Echtzeitverarbeitung\nsichergestellt wird. Diese Balance ist entscheidend für SlimSpots, da das System sowohl blitzschnelle Entscheidungen\ntreffen als auch umfangreiche historische Datenanalysen ermöglichen muss.",{"type":29,"tag":48,"props":160,"children":161},{},[162],{"type":56,"value":163},"Neben der Datenbankoptimierung haben wir auch die Betreuung der gesamten Serverinfrastruktur übernommen, die im Peak\naus 40 Servern bestand. Dies umfasste die Konfiguration, Überwachung und Wartung der Server sowie die Implementierung\nvon Hochverfügbarkeitslösungen, um Ausfallzeiten zu minimieren. Durch kontinuierliche Performanceanalysen und\nproaktive Optimierungen konnten wir die Infrastruktur stets an die wachsenden Anforderungen anpassen.",{"type":29,"tag":116,"props":165,"children":166},{"cols":118,"md":139},[167],{"type":29,"tag":168,"props":169,"children":171},"employees-card",{":showExecutiveRole":113,"name":170},"bernd-helm",[],{"type":29,"tag":36,"props":173,"children":175},{"className":174},[105,106,41,42,43,44],[176,195],{"type":29,"tag":111,"props":177,"children":178},{":no-gutters":113,"no-gutters":7},[179,182],{"type":29,"tag":116,"props":180,"children":181},{"cols":118,"md":139},[],{"type":29,"tag":116,"props":183,"children":184},{"cols":118,"md":119},[185],{"type":29,"tag":122,"props":186,"children":188},{"id":187},"optimierung-der-auslieferungssoftware",[189],{"type":29,"tag":127,"props":190,"children":192},{"className":191},[130,131,132,133],[193],{"type":56,"value":194},"Optimierung der Auslieferungssoftware",{"type":29,"tag":111,"props":196,"children":197},{},[198,205],{"type":29,"tag":116,"props":199,"children":200},{"cols":118,"md":139},[201],{"type":29,"tag":168,"props":202,"children":204},{":showExecutiveRole":113,"name":203},"daniel-walter",[],{"type":29,"tag":116,"props":206,"children":207},{"cols":118,"md":119},[208,213,218],{"type":29,"tag":48,"props":209,"children":210},{},[211],{"type":56,"value":212},"Ein wesentlicher Bestandteil unserer Arbeit für SlimSpots war die Verbesserung der Auslieferungssoftware, die für\ndie Echtzeitentscheidungen bei der Werbemittelschaltung verantwortlich ist. Diese Software muss in Millisekunden\nentscheiden, welche Werbung einem bestimmten Nutzer angezeigt wird, basierend auf zahlreichen Kriterien wie Gerät,\nStandort, Browser und vorherigen Interaktionen.",{"type":29,"tag":48,"props":214,"children":215},{},[216],{"type":56,"value":217},"Wir haben die bestehende Software grundlegend überarbeitet und optimiert, um die Verarbeitungsgeschwindigkeit zu\nerhöhen und gleichzeitig die Präzision der Entscheidungsfindung zu verbessern. Durch den Einsatz effizienter\nCaching-Mechanismen, die Optimierung der Datenbankabfragen und die Implementierung intelligenter Algorithmen\nkonnten wir die Antwortzeiten signifikant reduzieren und die Skalierbarkeit des Systems erhöhen.",{"type":29,"tag":48,"props":219,"children":220},{},[221],{"type":56,"value":222},"Besonderes Augenmerk legten wir auf die Echtzeitanalyse und -visualisierung der Kampagnenperformance. Werbetreibende\nund Traffic-Lieferanten benötigen sofortiges Feedback über die Wirksamkeit ihrer Maßnahmen. Unsere optimierte\nSoftware ermöglicht es, Daten in Echtzeit zu verarbeiten und aussagekräftige Dashboards zu generieren, die eine\nunmittelbare Bewertung der Kampagnenperformance erlauben.",{"type":29,"tag":30,"props":224,"children":225},{},[226,233,330],{"type":29,"tag":90,"props":227,"children":230},{"className":228,"id":229},[93,94,95,96,97],"besondere-herausforderungen",[231],{"type":56,"value":232}," Besondere Herausforderungen ",{"type":29,"tag":36,"props":234,"children":236},{"className":235},[105,106,41,42,43,44],[237],{"type":29,"tag":111,"props":238,"children":239},{},[240,260,290,302],{"type":29,"tag":116,"props":241,"children":243},{"cols":118,"md":242,"sm":64},"2",[244],{"type":29,"tag":245,"props":246,"children":254},"v-responsive",{"aspect-ratio":247,"className":248,"content-class":252,"style":253},"0.921",[249,250,251],"bg-primary-lighten-3","hw-hexagon","mx-auto","d-flex justify-center align-center","width: 100%; max-width: 120px;",[255],{"type":29,"tag":256,"props":257,"children":259},"hw-image",{"src":258},"/images/scalability-logo.svg",[],{"type":29,"tag":116,"props":261,"children":264},{"cols":118,"md":262,"sm":263},"10","9",[265,275,280,285],{"type":29,"tag":122,"props":266,"children":268},{"id":267},"extreme-skalierbarkeit-bei-konstanter-performance",[269],{"type":29,"tag":127,"props":270,"children":272},{"className":271},[132,133],[273],{"type":56,"value":274},"Extreme Skalierbarkeit bei konstanter Performance",{"type":29,"tag":48,"props":276,"children":277},{},[278],{"type":56,"value":279},"Eine der größten Herausforderungen in diesem Projekt war die Gewährleistung extremer Skalierbarkeit bei gleichzeitig\nkonstanter Performance. Die Datenmengen, die SlimSpots verarbeitet, wachsen kontinuierlich, und die Infrastruktur\nmuss in der Lage sein, mit diesem Wachstum Schritt zu halten, ohne dass es zu Leistungseinbußen kommt.",{"type":29,"tag":48,"props":281,"children":282},{},[283],{"type":56,"value":284},"Wir haben diese Herausforderung durch den Einsatz von MariaDB ColumnStore gemeistert, einer spaltenbasierenden\nDatenbank, die speziell für Big-Data-Analytik entwickelt wurde. Wir haben die Datenbankstruktur, die Abfragen und die Anwendungslogik sorgfältig aufeinander\nabgestimmt, um sowohl blitzschnelle Entscheidungen als auch umfangreiche historische Analysen zu ermöglichen.",{"type":29,"tag":48,"props":286,"children":287},{},[288],{"type":56,"value":289},"Die Skalierung auf bis zu 40 Server erforderte zudem ein durchdachtes Architekturkonzept, das eine effiziente\nLastverteilung und Fehlertoleranzmechanismen umfasst.\nDurch den Einsatz intelligenter Caching-Mechanismen und das Optimieren von Indexstrukturen konnten wir sicherstellen, dass das System auch bei sprunghaft\nansteigenden Anfragevolumen zuverlässig funktioniert.",{"type":29,"tag":116,"props":291,"children":292},{"cols":118,"md":242,"sm":64},[293],{"type":29,"tag":245,"props":294,"children":297},{"aspect-ratio":247,"className":295,"content-class":252,"style":253},[296,250,251],"bg-primary-lighten-1",[298],{"type":29,"tag":256,"props":299,"children":301},{"src":300},"/images/data-processing-logo.svg",[],{"type":29,"tag":116,"props":303,"children":304},{"cols":118,"md":262,"sm":263},[305,315,320,325],{"type":29,"tag":122,"props":306,"children":308},{"id":307},"weltweite-verfügbarkeit-und-datenanalyse",[309],{"type":29,"tag":127,"props":310,"children":312},{"className":311},[132,133],[313],{"type":56,"value":314},"Weltweite Verfügbarkeit und Datenanalyse",{"type":29,"tag":48,"props":316,"children":317},{},[318],{"type":56,"value":319},"Als weltweit agierendes Unternehmen benötigt SlimSpots eine Infrastruktur, die global verfügbar ist und dennoch\nniedrige Latenzzeiten bietet. Gleichzeitig müssen Daten über Jahre hinweg gespeichert und analysierbar sein, um\nlangfristige Trends zu erkennen und die Effektivität von Kampagnen zu bewerten.",{"type":29,"tag":48,"props":321,"children":322},{},[323],{"type":56,"value":324},"Wir haben ein verteiltes System implementiert, das eine lokale Verarbeitung mit globaler Datenkonsistenz verbindet.\nDie Herausforderung bestand darin, trotz der weltweiten Verteilung eine konsistente Datenbasis für Analysen zu schaffen.",{"type":29,"tag":48,"props":326,"children":327},{},[328],{"type":56,"value":329},"Besonders anspruchsvoll war die Anforderung, historische Daten über Jahre hinweg verfügbar und effizient abfragbar\nzu halten. Unsere System-Architektur ermöglicht es SlimSpots und seinen Kunden,\ndetaillierte Auswertungen über lange Zeiträume durchzuführen und so wertvolle Erkenntnisse für die Optimierung\nihrer Kampagnen zu gewinnen.",{"type":29,"tag":81,"props":331,"children":333},{"className":332},[84],[],{"type":29,"tag":30,"props":335,"children":336},{},[337],{"type":29,"tag":338,"props":339,"children":340},"contact-form",{},[],{"title":7,"searchDepth":342,"depth":342,"links":343},2,[344,345],{"id":98,"depth":342,"text":101},{"id":229,"depth":342,"text":232},"markdown","common:portfolio:9020.slimspots:index.md","common","portfolio/9020.slimspots/index.md","portfolio/9020.slimspots/index","md",{"_path":353,"_dir":354,"_draft":6,"_partial":6,"_locale":7,"slug":170,"teams":355,"primaryTeam":357,"firstName":358,"lastName":359,"prefixTitle":7,"suffixTitle":7,"education":360,"executiveRole":365,"role":366,"workingSince":374,"inTheCompanySince":375,"techSkills":376,"skills":422,"projects":434,"contactDetails":447,"_image":451,"image":452,"_id":453,"_type":454,"title":455,"_source":354,"_file":456,"_stem":457,"_extension":454},"/employees/bernd-helm","employees",[356,357],"ai","devOps","Bernd","Helm",[361],[362,363,364],"B. Sc. Angewandte Informatik","FHDW Dresden","2010","CTO",[367,368,357,369,370,371,372,373],"founder","chiefTechnologyOfficer","databaseSpecialist","admin","softwareDeveloper","backendDeveloper","consultant","2005","2008",[377,381,384,386,389,391,394,396,398,400,403,407,410,413,416,419],{"name":378,"level":379,"icon":380},"Docker","expert","/images/Docker.svg",{"name":382,"level":379,"icon":383},"Linux","/images/linux_os-mono.svg",{"name":385,"level":379},"Zabbix",{"name":387,"level":379,"icon":388},"MariaDB ColumnStore","/images/maria-db-logo.svg",{"name":390,"level":379},"OpenAI",{"name":392,"level":379,"icon":393},"Pytorch","/images/PyTorch.svg",{"name":395,"level":379},"PHP",{"name":397,"level":379},"Java",{"name":399,"level":379},"Python",{"name":401,"level":379,"icon":402},"SQL","/images/SQL.svg",{"name":404,"level":405,"icon":406},"C++","advanced","/images/cpp-logo.svg",{"name":408,"level":405,"icon":409},"C#","/images/csharp.svg",{"name":411,"level":405,"icon":412},"CSS","/images/css.svg",{"name":414,"level":405,"icon":415},"HTML","/images/html.svg",{"name":417,"level":405,"icon":418},"OpenCV","/images/OpenCV.svg",{"name":420,"level":405,"icon":421},"Vue.js","/images/vuejs.svg",[423,425,427,428,430,432],{"name":424,"level":379},"artificialIntelligence",{"name":426,"level":379},"codingGuidelines",{"name":23,"level":379},{"name":429,"level":379},"linuxServerAdministration",{"name":431,"level":379},"softwareArchitect",{"name":433,"level":405},"qualityAssurance",[435,438,440,442,445],{"project":436,"position":437},"Gridside","Technical Consultant",{"project":439,"position":437},"Herole",{"project":441,"position":437},"Montagespezis",{"project":443,"position":444},"Orsee","Technical Manager",{"project":446,"position":437},"Vipr",{"eMail":448,"phone":449,"visibility":450},"bernd.helm@helmundwalter.de","+49 351 799 035 20","1","images/employees/Portraits/bernd_helm.webp","images/employees/Portraits/BerndHelm_MS.webp","employees:employees:1.bernd-helm.json","json","Bernd Helm","employees/1.bernd-helm.json","employees/1.bernd-helm",{"_path":459,"_dir":354,"_draft":6,"_partial":6,"_locale":7,"slug":203,"teams":460,"primaryTeam":461,"firstName":462,"lastName":463,"prefixTitle":7,"suffixTitle":7,"education":464,"executiveRole":467,"role":468,"workingSince":375,"inTheCompanySince":375,"techSkills":472,"skills":479,"projects":486,"contactDetails":487,"_image":490,"image":491,"_id":492,"_type":454,"title":493,"_source":354,"_file":494,"_stem":495,"_extension":454},"/employees/daniel-walter",[461,357],"shopware","Daniel","Walter",[465],[362,466,364],"FHDW","CEO",[367,469,470,371,471,370,373],"chiefExecutiveOfficer","projectManager","fullstackDeveloper",[473,474,475,476],{"name":404,"level":379,"icon":406},{"name":408,"level":379,"icon":409},{"name":401,"level":379,"icon":402},{"name":477,"level":405,"icon":478},"Flutter","/images/Flutter.svg",[480,481,482,484,485],{"name":23,"level":379},{"name":429,"level":379},{"name":483,"level":379},"projectManagement",{"name":461,"level":379},{"name":431,"level":405},[],{"eMail":488,"phone":489,"visibility":450},"daniel.walter@helmundwalter.de","+49 351 799 035 21","images/employees/Portraits/daniel_walter.webp","images/employees/Portraits/DanielWalter_MS.webp","employees:employees:2.daniel-walter.json","Daniel Walter","employees/2.daniel-walter.json","employees/2.daniel-walter",[497],{"_path":498,"_dir":499,"_draft":6,"_partial":500,"_locale":7,"name":501,"slug":499,"text":502,"hoverText":503,"image":504,"customer":501,"tags":505,"_id":507,"_type":508,"title":509,"_source":348,"_file":510,"_stem":511,"_extension":508},"/portfolio/pixelx/_teaser","pixelx",true,"PixelX","IT-Sicherheit mit Augenmaß und Sachverstand","Für PixelX haben wir eine gezielte Sicherheitsanalyse durchgeführt, bei der wir dank unseres tiefen technischen Verständnisses eine kritische Schwachstelle identifizieren konnten. Mit minimalem Zeitaufwand erzielten wir maximalen Sicherheitsgewinn.","/images/portfolio/pixelx/pixelx_secured.png",[506,24],"security","common:portfolio:9010.pixelx:_teaser.yaml","yaml","Teaser","portfolio/9010.pixelx/_teaser.yaml","portfolio/9010.pixelx/_teaser",[513,529,542,552,562,573,585,597,609,622],{"_path":514,"_dir":515,"_draft":6,"_partial":6,"_locale":7,"title":516,"description":517,"author":518,"image":519,"releaseDate":520,"blogCategories":521,"articleTags":524,"tags":525,"_type":346,"_id":526,"_source":348,"_file":527,"_stem":528,"_extension":351},"/blog/traefik-magic","blog","Verwendung von Traefik als Reverse Proxy - Convention over Configuration","Wie man den Traefik Reverse Proxy so konfiguriert, dass man auf Traefik-spezifische Labels verzichten kann und automatisch Subdomains passend zum Namen des Compose-Projekts geroutet werden.","robert-juzak","/images/dev-ops-dark.svg","2026-03-13",[522,523],"Was uns bewegt","DevOps",[523],[24],"common:blog:21.traefik-magic.md","blog/21.traefik-magic.md","blog/21.traefik-magic",{"_path":530,"_dir":515,"_draft":6,"_partial":6,"_locale":7,"title":531,"description":532,"author":518,"image":519,"releaseDate":533,"blogCategories":534,"articleTags":535,"tags":538,"_type":346,"_id":539,"_source":348,"_file":540,"_stem":541,"_extension":351},"/blog/shopware-plugin-gitlab-pipeline-release","Testen, Bauen, und Veröffentlichen von Shopware 6 Plugin mit GitLab CI - Teil 1: Veröffentlichen","Teil 1: Veröffentlichen - Verwendung von GitLab zum Testen, Bauen und Veröffentlichen eines Shopware 6 Plugins","2026-02-26",[522,523],[523,536,537],"Open Source","Shopware",[461,24],"common:blog:18.shopware-plugin-gitlab-pipeline-release.md","blog/18.shopware-plugin-gitlab-pipeline-release.md","blog/18.shopware-plugin-gitlab-pipeline-release",{"_path":543,"_dir":515,"_draft":6,"_partial":6,"_locale":7,"title":544,"description":545,"author":518,"image":519,"releaseDate":533,"blogCategories":546,"articleTags":547,"tags":548,"_type":346,"_id":549,"_source":348,"_file":550,"_stem":551,"_extension":351},"/blog/shopware-plugin-gitlab-pipeline-build","Testen, Bauen, und Veröffentlichen eines Shopware 6 Plugins mit GitLab CI - Teil 2: Bauen","Teil 2: Bauen - Verwendung von GitLab zum Testen, Erstellen und Releasen eines Shopware 6 Plugins",[522,523],[523,536,537],[461,24],"common:blog:19.shopware-plugin-gitlab-pipeline-build.md","blog/19.shopware-plugin-gitlab-pipeline-build.md","blog/19.shopware-plugin-gitlab-pipeline-build",{"_path":553,"_dir":515,"_draft":6,"_partial":6,"_locale":7,"title":554,"description":555,"author":518,"image":519,"releaseDate":533,"blogCategories":556,"articleTags":557,"tags":558,"_type":346,"_id":559,"_source":348,"_file":560,"_stem":561,"_extension":351},"/blog/shopware-plugin-gitlab-pipeline-test","Testen, Bauen und Veröffentlichen eines Shopware 6 Plugins mit GitLab CI - Teil 3: Testen","Teil 3: Testen - Verwendung von GitLab zum Testen, Bauen und Veröffentlichen eines Shopware 6 Plugins",[522,523],[523,536,537],[461,24],"common:blog:20.shopware-plugin-gitlab-pipeline-test.md","blog/20.shopware-plugin-gitlab-pipeline-test.md","blog/20.shopware-plugin-gitlab-pipeline-test",{"_path":563,"_dir":515,"_draft":6,"_partial":6,"_locale":7,"title":564,"description":565,"author":518,"image":519,"releaseDate":566,"blogCategories":567,"articleTags":568,"tags":569,"_type":346,"_id":570,"_source":348,"_file":571,"_stem":572,"_extension":351},"/blog/gitops-docker-renovate","Softwareverwaltung mit GitLab, Renovate Bot und Docker","Software auf einem Server zu verwalten ist nicht einfach. Oder doch?","2025-10-30",[522,523],[523,536],[24],"common:blog:17.gitops-docker-renovate.md","blog/17.gitops-docker-renovate.md","blog/17.gitops-docker-renovate",{"_path":574,"_dir":515,"_draft":6,"_partial":6,"_locale":7,"title":575,"description":576,"author":518,"image":519,"releaseDate":577,"blogCategories":578,"articleTags":580,"tags":581,"_type":346,"_id":582,"_source":348,"_file":583,"_stem":584,"_extension":351},"/blog/shopware-renovate-bot","Konfiguration von Renovate für die ordnungsgemäße Behandlung von Shopware-Paketen","Shopware verwendet ein benutzerdefiniertes Versionierungsschema. Um Renovate die automatische Erstellung von PR's zu ermöglichen, müssen wir die Renovate-Konfiguration anpassen","2025-09-08",[579,523],"Das bewegt uns",[523,536],[461,24],"common:blog:16.shopware-renovate-bot.md","blog/16.shopware-renovate-bot.md","blog/16.shopware-renovate-bot",{"_path":586,"_dir":515,"_draft":6,"_partial":6,"_locale":7,"title":587,"description":588,"author":518,"image":519,"releaseDate":589,"blogCategories":590,"articleTags":592,"tags":593,"_type":346,"_id":594,"_source":348,"_file":595,"_stem":596,"_extension":351},"/blog/gitlab-behind-traefik","Installation von Gitlab hinter Traefik","Es ist super einfach, GitLab mit Docker auf einem dedizierten Server zu installieren. Aber was, wenn Sie es neben Ihren anderen Deployments bereitstellen müssen?","2025-07-16",[522,591],"Infrastruktur",[523],[24],"common:blog:14.gitlab-behind-traefik.md","blog/14.gitlab-behind-traefik.md","blog/14.gitlab-behind-traefik",{"_path":598,"_dir":515,"_draft":6,"_partial":6,"_locale":7,"title":599,"description":600,"author":601,"image":519,"releaseDate":602,"blogCategories":603,"articleTags":604,"tags":605,"_type":346,"_id":606,"_source":348,"_file":607,"_stem":608,"_extension":351},"/blog/a-tribute-to-our-dev-ops","A Tribute to our Dev Ops","Web-Anwendungen werden meistens in einer Dev-Umgebung entwickelt und getestet – doch der eigentliche Härtetest kommt in der Praxis auf den Prod-Systemen.","jens-bornschein","2025-03-31",[579],[523],[24],"common:blog:12.a-tribute-to-our-dev-ops.md","blog/12.a-tribute-to-our-dev-ops.md","blog/12.a-tribute-to-our-dev-ops",{"_path":610,"_dir":515,"_draft":6,"_partial":6,"_locale":7,"title":611,"description":612,"author":170,"image":613,"releaseDate":614,"blogCategories":615,"articleTags":616,"tags":618,"_type":346,"_id":619,"_source":348,"_file":620,"_stem":621,"_extension":351},"/blog/wie-man-verschiedene-dns-server-fuer-bestimter-domaens-verwendet","Wie man verschiedene DNS-Server für die Namensauflösung bestimmter Domänen verwendet - VPN Use-Case","Wie man ausgewählte Domains über VPN unter Linux auflöst. In der heutigen Welt nutzen mehr Menschen als je zuvor VPN-Dienste, um aus der Ferne zu arbeiten. In manchen Fällen ist es jedoch nicht wünschenswert, den gesamten Datenverkehr und alle Domainnamenauflösungen über die VPN-Verbindung zu leiten.","/blog/thumbnails/VPN.png","2022-04-21",[579,523],[617,382],"VPN",[24],"common:blog:10.wie-man-verschiedene-dns-server-fuer-bestimter-domaens-verwendet.md","blog/10.wie-man-verschiedene-dns-server-fuer-bestimter-domaens-verwendet.md","blog/10.wie-man-verschiedene-dns-server-fuer-bestimter-domaens-verwendet",{"_path":623,"_dir":515,"_draft":6,"_partial":6,"_locale":7,"title":624,"description":625,"author":170,"image":626,"releaseDate":627,"blogCategories":628,"articleTags":629,"tags":631,"_type":346,"_id":632,"_source":348,"_file":633,"_stem":634,"_extension":351},"/blog/btrfs-auffinden-und-reparieren-stark-fragmentierter-dataien","BTRFS: Auffinden und Reparieren stark fragmentierter Dateien","Die meisten der besten BTRFS-Funktionen werden durch die Copy-on-Write-Technologie ermöglicht. Wenn eine Anwendung einen Teil einer Datei umschreiben will, wie z.B. das erste MegaByte, werden die Daten nicht an Ort und Stelle geschrieben, sondern in einer sogenannten Erweiterung. Dadurch ist BTRFS in der Lage, mehrere Versionen von teilweise umgeschriebenen Dateien aufzubewahren, wobei nur die ...","/blog/thumbnails/BTRFS_white.png","2020-10-21",[579,591],[630],"BTRFS",[24],"common:blog:8.btrfs-auffinden-und-reparieren-stark-fragmentierter-dataien.md","blog/8.btrfs-auffinden-und-reparieren-stark-fragmentierter-dataien.md","blog/8.btrfs-auffinden-und-reparieren-stark-fragmentierter-dataien",{"_path":514,"_dir":515,"_draft":6,"_partial":6,"_locale":7,"title":516,"description":517,"author":518,"image":519,"releaseDate":520,"blogCategories":636,"articleTags":637,"tags":638,"body":639,"_type":346,"_id":526,"_source":348,"_file":527,"_stem":528,"_extension":351},[522,523],[523],[24],{"type":26,"children":640,"toc":1843},[641,653,658,804,809,884,890,918,923,951,964,983,989,1006,1107,1112,1117,1142,1188,1192,1197,1560,1565,1601,1607,1615,1669,1673,1680,1708,1714,1719,1725,1730,1742,1750,1756,1768,1837],{"type":29,"tag":48,"props":642,"children":643},{},[644,651],{"type":29,"tag":645,"props":646,"children":648},"a",{"href":647},"https://doc.traefik.io/traefik/",[649],{"type":56,"value":650},"Traefik",{"type":56,"value":652}," ist ein Reverse Proxy mit exzellenter Docker-Integration. Er verwendet Labels, die an Containern angebracht sind, um den Datenverkehr zu ihnen zu leiten.",{"type":29,"tag":48,"props":654,"children":655},{},[656],{"type":56,"value":657},"Ein typisches Set an Labels sieht ungefähr so aus:",{"type":29,"tag":659,"props":660,"children":670},"pre",{"code":661,"filename":662,"highlights":663,"language":508,"meta":7,"className":669,"style":7},"services:\n  whoami:\n    image: traefik/whoami\n    labels:\n      - \"traefik.enable=true\"\n      - \"traefik.http.routers.whoami.rule=Host(`whoami.example.com`)\"\n      - \"traefik.http.routers.whoami.entrypoints=websecure\"\n      - \"traefik.http.routers.whoami.tls=true\"\n      - \"traefik.http.routers.whoami.tls.certresolver=letsencrypt\"\n","whoami/docker-compose.yaml",[664,665,666,667,668],5,6,7,8,9,"language-yaml shiki shiki-themes github-dark github-dark monokai",[671],{"type":29,"tag":672,"props":673,"children":674},"code",{"__ignoreMap":7},[675,692,704,724,737,752,765,778,791],{"type":29,"tag":127,"props":676,"children":679},{"class":677,"line":678},"line",1,[680,686],{"type":29,"tag":127,"props":681,"children":683},{"style":682},"--shiki-default:#85E89D;--shiki-dark:#85E89D;--shiki-sepia:#F92672",[684],{"type":56,"value":685},"services",{"type":29,"tag":127,"props":687,"children":689},{"style":688},"--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2",[690],{"type":56,"value":691},":\n",{"type":29,"tag":127,"props":693,"children":694},{"class":677,"line":342},[695,700],{"type":29,"tag":127,"props":696,"children":697},{"style":682},[698],{"type":56,"value":699},"  whoami",{"type":29,"tag":127,"props":701,"children":702},{"style":688},[703],{"type":56,"value":691},{"type":29,"tag":127,"props":705,"children":707},{"class":677,"line":706},3,[708,713,718],{"type":29,"tag":127,"props":709,"children":710},{"style":682},[711],{"type":56,"value":712},"    image",{"type":29,"tag":127,"props":714,"children":715},{"style":688},[716],{"type":56,"value":717},": ",{"type":29,"tag":127,"props":719,"children":721},{"style":720},"--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74",[722],{"type":56,"value":723},"traefik/whoami\n",{"type":29,"tag":127,"props":725,"children":727},{"class":677,"line":726},4,[728,733],{"type":29,"tag":127,"props":729,"children":730},{"style":682},[731],{"type":56,"value":732},"    labels",{"type":29,"tag":127,"props":734,"children":735},{"style":688},[736],{"type":56,"value":691},{"type":29,"tag":127,"props":738,"children":741},{"class":739,"line":664},[677,740],"highlight",[742,747],{"type":29,"tag":127,"props":743,"children":744},{"style":688},[745],{"type":56,"value":746},"      - ",{"type":29,"tag":127,"props":748,"children":749},{"style":720},[750],{"type":56,"value":751},"\"traefik.enable=true\"\n",{"type":29,"tag":127,"props":753,"children":755},{"class":754,"line":665},[677,740],[756,760],{"type":29,"tag":127,"props":757,"children":758},{"style":688},[759],{"type":56,"value":746},{"type":29,"tag":127,"props":761,"children":762},{"style":720},[763],{"type":56,"value":764},"\"traefik.http.routers.whoami.rule=Host(`whoami.example.com`)\"\n",{"type":29,"tag":127,"props":766,"children":768},{"class":767,"line":666},[677,740],[769,773],{"type":29,"tag":127,"props":770,"children":771},{"style":688},[772],{"type":56,"value":746},{"type":29,"tag":127,"props":774,"children":775},{"style":720},[776],{"type":56,"value":777},"\"traefik.http.routers.whoami.entrypoints=websecure\"\n",{"type":29,"tag":127,"props":779,"children":781},{"class":780,"line":667},[677,740],[782,786],{"type":29,"tag":127,"props":783,"children":784},{"style":688},[785],{"type":56,"value":746},{"type":29,"tag":127,"props":787,"children":788},{"style":720},[789],{"type":56,"value":790},"\"traefik.http.routers.whoami.tls=true\"\n",{"type":29,"tag":127,"props":792,"children":794},{"class":793,"line":668},[677,740],[795,799],{"type":29,"tag":127,"props":796,"children":797},{"style":688},[798],{"type":56,"value":746},{"type":29,"tag":127,"props":800,"children":801},{"style":720},[802],{"type":56,"value":803},"\"traefik.http.routers.whoami.tls.certresolver=letsencrypt\"\n",{"type":29,"tag":48,"props":805,"children":806},{},[807],{"type":56,"value":808},"In diesem Beispiel:",{"type":29,"tag":810,"props":811,"children":812},"ul",{},[813,825,841,846,858,863],{"type":29,"tag":814,"props":815,"children":816},"li",{},[817,823],{"type":29,"tag":672,"props":818,"children":820},{"className":819},[],[821],{"type":56,"value":822},"whoami",{"type":56,"value":824}," ist der Name des \"Haupt\"-Dienstes (2)",{"type":29,"tag":814,"props":826,"children":827},{},[828,833,835],{"type":29,"tag":672,"props":829,"children":831},{"className":830},[],[832],{"type":56,"value":822},{"type":56,"value":834}," ist auch der Standard-",{"type":29,"tag":645,"props":836,"children":838},{"href":837},"https://docs.docker.com/compose/how-tos/project-name/",[839],{"type":56,"value":840},"Name des Compose-Projekts",{"type":29,"tag":814,"props":842,"children":843},{},[844],{"type":56,"value":845},"Traefik wird aktiviert (5)",{"type":29,"tag":814,"props":847,"children":848},{},[849,851,856],{"type":56,"value":850},"Der Dienst wird unter der Subdomain ",{"type":29,"tag":672,"props":852,"children":854},{"className":853},[],[855],{"type":56,"value":822},{"type":56,"value":857}," bereitgestellt (6)",{"type":29,"tag":814,"props":859,"children":860},{},[861],{"type":56,"value":862},"Die Auslieferung erfolgt über HTTPS (7)",{"type":29,"tag":814,"props":864,"children":865},{},[866,868,874,876,882],{"type":56,"value":867},"Ein vorkonfigurierter Certresolver namens ",{"type":29,"tag":672,"props":869,"children":871},{"className":870},[],[872],{"type":56,"value":873},"letsencrypt",{"type":56,"value":875}," wird für ",{"type":29,"tag":672,"props":877,"children":879},{"className":878},[],[880],{"type":56,"value":881},"tls",{"type":56,"value":883}," verwendet (8-9)",{"type":29,"tag":90,"props":885,"children":887},{"id":886},"das-problem",[888],{"type":56,"value":889},"Das Problem",{"type":29,"tag":48,"props":891,"children":892},{},[893,895,900,902,908,910,916],{"type":56,"value":894},"In meinem ",{"type":29,"tag":645,"props":896,"children":897},{"href":563},[898],{"type":56,"value":899},"anderen Beitrag über GitOps mit Docker",{"type":56,"value":901}," habe ich das Konzept eingeführt,\n",{"type":29,"tag":672,"props":903,"children":905},{"className":904},[],[906],{"type":56,"value":907},"git",{"type":56,"value":909}," als „Source of Truth“ für Docker-Deployments mittels ",{"type":29,"tag":645,"props":911,"children":913},{"href":912},"https://docs.docker.com/compose/",[914],{"type":56,"value":915},"Docker Compose",{"type":56,"value":917}," zu nutzen.",{"type":29,"tag":48,"props":919,"children":920},{},[921],{"type":56,"value":922},"Dabei gibt es einige Anforderungen:",{"type":29,"tag":810,"props":924,"children":925},{},[926,939],{"type":29,"tag":814,"props":927,"children":928},{},[929,931,937],{"type":56,"value":930},"Jeder Stack ist unter ",{"type":29,"tag":672,"props":932,"children":934},{"className":933},[],[935],{"type":56,"value":936},"\u003Cstack_name>.\u003Cyour_domain>",{"type":56,"value":938}," erreichbar",{"type":29,"tag":814,"props":940,"children":941},{},[942,944,949],{"type":56,"value":943},"Jeder Stack ist mit ",{"type":29,"tag":672,"props":945,"children":947},{"className":946},[],[948],{"type":56,"value":881},{"type":56,"value":950}," geschützt",{"type":29,"tag":48,"props":952,"children":953},{},[954,956,962],{"type":56,"value":955},"Wir könnten zwar in jeder ",{"type":29,"tag":672,"props":957,"children":959},{"className":958},[],[960],{"type":56,"value":961},"docker-compose.yaml",{"type":56,"value":963}," die Labels manuell hinzufügen, doch dabei zeigt sich schnell,\ndass wir die Konfiguration redundant wiederholen.",{"type":29,"tag":965,"props":966,"children":967},"ol",{},[968,973,978],{"type":29,"tag":814,"props":969,"children":970},{},[971],{"type":56,"value":972},"Traefik aktivieren",{"type":29,"tag":814,"props":974,"children":975},{},[976],{"type":56,"value":977},"Eine Subdomain zuweisen",{"type":29,"tag":814,"props":979,"children":980},{},[981],{"type":56,"value":982},"HTTPS aktivieren",{"type":29,"tag":90,"props":984,"children":986},{"id":985},"die-lösung",[987],{"type":56,"value":988},"Die Lösung",{"type":29,"tag":48,"props":990,"children":991},{},[992,994,1004],{"type":56,"value":993},"Mit hilfe der ",{"type":29,"tag":645,"props":995,"children":997},{"href":996},"https://docs.docker.com/compose/how-tos/environment-variables/envvars/#compose_project_name",[998],{"type":29,"tag":672,"props":999,"children":1001},{"className":1000},[],[1002],{"type":56,"value":1003},"$COMPOSE_PROJECT_NAME",{"type":56,"value":1005},"\nVariable können wir ein generisches Template für eine solche Konfiguration erstellen.\nDadurch stellen wir sicher, dass die Traefik-Regeln einheitlich sind.",{"type":29,"tag":659,"props":1007,"children":1010},{"code":1008,"filename":1009,"language":508,"meta":7,"className":669,"style":7},"services:\n  \u003Cmain_service>:\n    labels:\n      - \"traefik.enable=true\"\n      - \"traefik.http.routers.$COMPOSE_PROJECT_NAME.rule=Host(`\u003Cstack_name>.example.com`)\"\n      - \"traefik.http.routers.$COMPOSE_PROJECT_NAME.entrypoints=websecure\"\n      - \"traefik.http.routers.$COMPOSE_PROJECT_NAME.tls=true\"\n      - \"traefik.http.routers.$COMPOSE_PROJECT_NAME.tls.certresolver=letsencrypt\"\n","\u003Cstack_name>/docker-compose.yaml",[1011],{"type":29,"tag":672,"props":1012,"children":1013},{"__ignoreMap":7},[1014,1025,1037,1048,1059,1071,1083,1095],{"type":29,"tag":127,"props":1015,"children":1016},{"class":677,"line":678},[1017,1021],{"type":29,"tag":127,"props":1018,"children":1019},{"style":682},[1020],{"type":56,"value":685},{"type":29,"tag":127,"props":1022,"children":1023},{"style":688},[1024],{"type":56,"value":691},{"type":29,"tag":127,"props":1026,"children":1027},{"class":677,"line":342},[1028,1033],{"type":29,"tag":127,"props":1029,"children":1030},{"style":682},[1031],{"type":56,"value":1032},"  \u003Cmain_service>",{"type":29,"tag":127,"props":1034,"children":1035},{"style":688},[1036],{"type":56,"value":691},{"type":29,"tag":127,"props":1038,"children":1039},{"class":677,"line":706},[1040,1044],{"type":29,"tag":127,"props":1041,"children":1042},{"style":682},[1043],{"type":56,"value":732},{"type":29,"tag":127,"props":1045,"children":1046},{"style":688},[1047],{"type":56,"value":691},{"type":29,"tag":127,"props":1049,"children":1050},{"class":677,"line":726},[1051,1055],{"type":29,"tag":127,"props":1052,"children":1053},{"style":688},[1054],{"type":56,"value":746},{"type":29,"tag":127,"props":1056,"children":1057},{"style":720},[1058],{"type":56,"value":751},{"type":29,"tag":127,"props":1060,"children":1061},{"class":677,"line":664},[1062,1066],{"type":29,"tag":127,"props":1063,"children":1064},{"style":688},[1065],{"type":56,"value":746},{"type":29,"tag":127,"props":1067,"children":1068},{"style":720},[1069],{"type":56,"value":1070},"\"traefik.http.routers.$COMPOSE_PROJECT_NAME.rule=Host(`\u003Cstack_name>.example.com`)\"\n",{"type":29,"tag":127,"props":1072,"children":1073},{"class":677,"line":665},[1074,1078],{"type":29,"tag":127,"props":1075,"children":1076},{"style":688},[1077],{"type":56,"value":746},{"type":29,"tag":127,"props":1079,"children":1080},{"style":720},[1081],{"type":56,"value":1082},"\"traefik.http.routers.$COMPOSE_PROJECT_NAME.entrypoints=websecure\"\n",{"type":29,"tag":127,"props":1084,"children":1085},{"class":677,"line":666},[1086,1090],{"type":29,"tag":127,"props":1087,"children":1088},{"style":688},[1089],{"type":56,"value":746},{"type":29,"tag":127,"props":1091,"children":1092},{"style":720},[1093],{"type":56,"value":1094},"\"traefik.http.routers.$COMPOSE_PROJECT_NAME.tls=true\"\n",{"type":29,"tag":127,"props":1096,"children":1097},{"class":677,"line":667},[1098,1102],{"type":29,"tag":127,"props":1099,"children":1100},{"style":688},[1101],{"type":56,"value":746},{"type":29,"tag":127,"props":1103,"children":1104},{"style":720},[1105],{"type":56,"value":1106},"\"traefik.http.routers.$COMPOSE_PROJECT_NAME.tls.certresolver=letsencrypt\"\n",{"type":29,"tag":48,"props":1108,"children":1109},{},[1110],{"type":56,"value":1111},"Die gute Nachricht ist, dass Traefik es uns ermöglicht, einige Standardwerte zu konfigurieren, die den oben genannten Boilerplate-Code abdecken!",{"type":29,"tag":48,"props":1113,"children":1114},{},[1115],{"type":56,"value":1116},"Führen wir zwei einfache Konventionen ein:",{"type":29,"tag":965,"props":1118,"children":1119},{},[1120,1131],{"type":29,"tag":814,"props":1121,"children":1122},{},[1123,1129],{"type":29,"tag":672,"props":1124,"children":1126},{"className":1125},[],[1127],{"type":56,"value":1128},"app",{"type":56,"value":1130}," als Name des \"Hauptcontainers\", damit Traefik den Datenverkehr dorthin leitet",{"type":29,"tag":814,"props":1132,"children":1133},{},[1134,1140],{"type":29,"tag":672,"props":1135,"children":1137},{"className":1136},[],[1138],{"type":56,"value":1139},"\u003Cstack_name>",{"type":56,"value":1141}," (der Name des Compose-Projekts) in der Subdomain",{"type":29,"tag":659,"props":1143,"children":1146},{"code":1144,"filename":1145,"language":508,"meta":7,"className":669,"style":7},"services:\n  app:\n    image: traefik/whoami\n","(1) whoami/docker-compose.yaml",[1147],{"type":29,"tag":672,"props":1148,"children":1149},{"__ignoreMap":7},[1150,1161,1173],{"type":29,"tag":127,"props":1151,"children":1152},{"class":677,"line":678},[1153,1157],{"type":29,"tag":127,"props":1154,"children":1155},{"style":682},[1156],{"type":56,"value":685},{"type":29,"tag":127,"props":1158,"children":1159},{"style":688},[1160],{"type":56,"value":691},{"type":29,"tag":127,"props":1162,"children":1163},{"class":677,"line":342},[1164,1169],{"type":29,"tag":127,"props":1165,"children":1166},{"style":682},[1167],{"type":56,"value":1168},"  app",{"type":29,"tag":127,"props":1170,"children":1171},{"style":688},[1172],{"type":56,"value":691},{"type":29,"tag":127,"props":1174,"children":1175},{"class":677,"line":706},[1176,1180,1184],{"type":29,"tag":127,"props":1177,"children":1178},{"style":682},[1179],{"type":56,"value":712},{"type":29,"tag":127,"props":1181,"children":1182},{"style":688},[1183],{"type":56,"value":717},{"type":29,"tag":127,"props":1185,"children":1186},{"style":720},[1187],{"type":56,"value":723},{"type":29,"tag":1189,"props":1190,"children":1191},"hr",{},[],{"type":29,"tag":48,"props":1193,"children":1194},{},[1195],{"type":56,"value":1196},"Nun konfigurieren wir Traefik, um \"die Magie\" wirken zu lassen:",{"type":29,"tag":659,"props":1198,"children":1201},{"code":1199,"filename":1200,"language":508,"meta":7,"className":669,"style":7},"volumes:\n  letsencrypt:\n    \nservices:\n  traefik:\n    container_name: traefik\n    restart: always\n    image: traefik:3\n    network_mode: host\n    command:\n      - --certificatesresolvers.letsencrypt.acme.httpchallenge=true\n      - --certificatesresolvers.letsencrypt.acme.email=\u003Cyour_email_here>\n      - --certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json\n      - --certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web\n\n      - --entrypoints.web.address=:80\n      - --entrypoints.websecure.address=:443\n      \n      - --entrypoints.web.http.redirections.entrypoint.to=websecure\n      - --entrypoints.web.http.redirections.entrypoint.scheme=https\n      - --entrypoints.websecure.http.tls.certresolver=letsencrypt\n\n      - --providers.docker\n      - --providers.docker.defaultrule=Host(`{{ trimPrefix `app-` .Name }}.example.com`)\n      - --providers.docker.constraints=Label(`com.docker.compose.service`,`app`)\n    volumes:\n      - /var/run/docker.sock:/var/run/docker.sock:ro\n      - /letsencrypt:/letsencrypt\n","(2) traefik/docker-compose.yaml",[1202],{"type":29,"tag":672,"props":1203,"children":1204},{"__ignoreMap":7},[1205,1217,1229,1237,1248,1260,1277,1294,1310,1327,1340,1353,1365,1378,1391,1400,1413,1426,1435,1448,1461,1474,1482,1495,1508,1521,1534,1547],{"type":29,"tag":127,"props":1206,"children":1207},{"class":677,"line":678},[1208,1213],{"type":29,"tag":127,"props":1209,"children":1210},{"style":682},[1211],{"type":56,"value":1212},"volumes",{"type":29,"tag":127,"props":1214,"children":1215},{"style":688},[1216],{"type":56,"value":691},{"type":29,"tag":127,"props":1218,"children":1219},{"class":677,"line":342},[1220,1225],{"type":29,"tag":127,"props":1221,"children":1222},{"style":682},[1223],{"type":56,"value":1224},"  letsencrypt",{"type":29,"tag":127,"props":1226,"children":1227},{"style":688},[1228],{"type":56,"value":691},{"type":29,"tag":127,"props":1230,"children":1231},{"class":677,"line":706},[1232],{"type":29,"tag":127,"props":1233,"children":1234},{"style":688},[1235],{"type":56,"value":1236},"    \n",{"type":29,"tag":127,"props":1238,"children":1239},{"class":677,"line":726},[1240,1244],{"type":29,"tag":127,"props":1241,"children":1242},{"style":682},[1243],{"type":56,"value":685},{"type":29,"tag":127,"props":1245,"children":1246},{"style":688},[1247],{"type":56,"value":691},{"type":29,"tag":127,"props":1249,"children":1250},{"class":677,"line":664},[1251,1256],{"type":29,"tag":127,"props":1252,"children":1253},{"style":682},[1254],{"type":56,"value":1255},"  traefik",{"type":29,"tag":127,"props":1257,"children":1258},{"style":688},[1259],{"type":56,"value":691},{"type":29,"tag":127,"props":1261,"children":1262},{"class":677,"line":665},[1263,1268,1272],{"type":29,"tag":127,"props":1264,"children":1265},{"style":682},[1266],{"type":56,"value":1267},"    container_name",{"type":29,"tag":127,"props":1269,"children":1270},{"style":688},[1271],{"type":56,"value":717},{"type":29,"tag":127,"props":1273,"children":1274},{"style":720},[1275],{"type":56,"value":1276},"traefik\n",{"type":29,"tag":127,"props":1278,"children":1279},{"class":677,"line":666},[1280,1285,1289],{"type":29,"tag":127,"props":1281,"children":1282},{"style":682},[1283],{"type":56,"value":1284},"    restart",{"type":29,"tag":127,"props":1286,"children":1287},{"style":688},[1288],{"type":56,"value":717},{"type":29,"tag":127,"props":1290,"children":1291},{"style":720},[1292],{"type":56,"value":1293},"always\n",{"type":29,"tag":127,"props":1295,"children":1296},{"class":677,"line":667},[1297,1301,1305],{"type":29,"tag":127,"props":1298,"children":1299},{"style":682},[1300],{"type":56,"value":712},{"type":29,"tag":127,"props":1302,"children":1303},{"style":688},[1304],{"type":56,"value":717},{"type":29,"tag":127,"props":1306,"children":1307},{"style":720},[1308],{"type":56,"value":1309},"traefik:3\n",{"type":29,"tag":127,"props":1311,"children":1312},{"class":677,"line":668},[1313,1318,1322],{"type":29,"tag":127,"props":1314,"children":1315},{"style":682},[1316],{"type":56,"value":1317},"    network_mode",{"type":29,"tag":127,"props":1319,"children":1320},{"style":688},[1321],{"type":56,"value":717},{"type":29,"tag":127,"props":1323,"children":1324},{"style":720},[1325],{"type":56,"value":1326},"host\n",{"type":29,"tag":127,"props":1328,"children":1330},{"class":677,"line":1329},10,[1331,1336],{"type":29,"tag":127,"props":1332,"children":1333},{"style":682},[1334],{"type":56,"value":1335},"    command",{"type":29,"tag":127,"props":1337,"children":1338},{"style":688},[1339],{"type":56,"value":691},{"type":29,"tag":127,"props":1341,"children":1343},{"class":677,"line":1342},11,[1344,1348],{"type":29,"tag":127,"props":1345,"children":1346},{"style":688},[1347],{"type":56,"value":746},{"type":29,"tag":127,"props":1349,"children":1350},{"style":720},[1351],{"type":56,"value":1352},"--certificatesresolvers.letsencrypt.acme.httpchallenge=true\n",{"type":29,"tag":127,"props":1354,"children":1355},{"class":677,"line":118},[1356,1360],{"type":29,"tag":127,"props":1357,"children":1358},{"style":688},[1359],{"type":56,"value":746},{"type":29,"tag":127,"props":1361,"children":1362},{"style":720},[1363],{"type":56,"value":1364},"--certificatesresolvers.letsencrypt.acme.email=\u003Cyour_email_here>\n",{"type":29,"tag":127,"props":1366,"children":1368},{"class":677,"line":1367},13,[1369,1373],{"type":29,"tag":127,"props":1370,"children":1371},{"style":688},[1372],{"type":56,"value":746},{"type":29,"tag":127,"props":1374,"children":1375},{"style":720},[1376],{"type":56,"value":1377},"--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json\n",{"type":29,"tag":127,"props":1379,"children":1381},{"class":677,"line":1380},14,[1382,1386],{"type":29,"tag":127,"props":1383,"children":1384},{"style":688},[1385],{"type":56,"value":746},{"type":29,"tag":127,"props":1387,"children":1388},{"style":720},[1389],{"type":56,"value":1390},"--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web\n",{"type":29,"tag":127,"props":1392,"children":1394},{"class":677,"line":1393},15,[1395],{"type":29,"tag":127,"props":1396,"children":1397},{"emptyLinePlaceholder":500},[1398],{"type":56,"value":1399},"\n",{"type":29,"tag":127,"props":1401,"children":1403},{"class":677,"line":1402},16,[1404,1408],{"type":29,"tag":127,"props":1405,"children":1406},{"style":688},[1407],{"type":56,"value":746},{"type":29,"tag":127,"props":1409,"children":1410},{"style":720},[1411],{"type":56,"value":1412},"--entrypoints.web.address=:80\n",{"type":29,"tag":127,"props":1414,"children":1416},{"class":677,"line":1415},17,[1417,1421],{"type":29,"tag":127,"props":1418,"children":1419},{"style":688},[1420],{"type":56,"value":746},{"type":29,"tag":127,"props":1422,"children":1423},{"style":720},[1424],{"type":56,"value":1425},"--entrypoints.websecure.address=:443\n",{"type":29,"tag":127,"props":1427,"children":1429},{"class":677,"line":1428},18,[1430],{"type":29,"tag":127,"props":1431,"children":1432},{"style":688},[1433],{"type":56,"value":1434},"      \n",{"type":29,"tag":127,"props":1436,"children":1438},{"class":677,"line":1437},19,[1439,1443],{"type":29,"tag":127,"props":1440,"children":1441},{"style":688},[1442],{"type":56,"value":746},{"type":29,"tag":127,"props":1444,"children":1445},{"style":720},[1446],{"type":56,"value":1447},"--entrypoints.web.http.redirections.entrypoint.to=websecure\n",{"type":29,"tag":127,"props":1449,"children":1451},{"class":677,"line":1450},20,[1452,1456],{"type":29,"tag":127,"props":1453,"children":1454},{"style":688},[1455],{"type":56,"value":746},{"type":29,"tag":127,"props":1457,"children":1458},{"style":720},[1459],{"type":56,"value":1460},"--entrypoints.web.http.redirections.entrypoint.scheme=https\n",{"type":29,"tag":127,"props":1462,"children":1464},{"class":677,"line":1463},21,[1465,1469],{"type":29,"tag":127,"props":1466,"children":1467},{"style":688},[1468],{"type":56,"value":746},{"type":29,"tag":127,"props":1470,"children":1471},{"style":720},[1472],{"type":56,"value":1473},"--entrypoints.websecure.http.tls.certresolver=letsencrypt\n",{"type":29,"tag":127,"props":1475,"children":1477},{"class":677,"line":1476},22,[1478],{"type":29,"tag":127,"props":1479,"children":1480},{"emptyLinePlaceholder":500},[1481],{"type":56,"value":1399},{"type":29,"tag":127,"props":1483,"children":1485},{"class":677,"line":1484},23,[1486,1490],{"type":29,"tag":127,"props":1487,"children":1488},{"style":688},[1489],{"type":56,"value":746},{"type":29,"tag":127,"props":1491,"children":1492},{"style":720},[1493],{"type":56,"value":1494},"--providers.docker\n",{"type":29,"tag":127,"props":1496,"children":1498},{"class":677,"line":1497},24,[1499,1503],{"type":29,"tag":127,"props":1500,"children":1501},{"style":688},[1502],{"type":56,"value":746},{"type":29,"tag":127,"props":1504,"children":1505},{"style":720},[1506],{"type":56,"value":1507},"--providers.docker.defaultrule=Host(`{{ trimPrefix `app-` .Name }}.example.com`)\n",{"type":29,"tag":127,"props":1509,"children":1511},{"class":677,"line":1510},25,[1512,1516],{"type":29,"tag":127,"props":1513,"children":1514},{"style":688},[1515],{"type":56,"value":746},{"type":29,"tag":127,"props":1517,"children":1518},{"style":720},[1519],{"type":56,"value":1520},"--providers.docker.constraints=Label(`com.docker.compose.service`,`app`)\n",{"type":29,"tag":127,"props":1522,"children":1524},{"class":677,"line":1523},26,[1525,1530],{"type":29,"tag":127,"props":1526,"children":1527},{"style":682},[1528],{"type":56,"value":1529},"    volumes",{"type":29,"tag":127,"props":1531,"children":1532},{"style":688},[1533],{"type":56,"value":691},{"type":29,"tag":127,"props":1535,"children":1537},{"class":677,"line":1536},27,[1538,1542],{"type":29,"tag":127,"props":1539,"children":1540},{"style":688},[1541],{"type":56,"value":746},{"type":29,"tag":127,"props":1543,"children":1544},{"style":720},[1545],{"type":56,"value":1546},"/var/run/docker.sock:/var/run/docker.sock:ro\n",{"type":29,"tag":127,"props":1548,"children":1550},{"class":677,"line":1549},28,[1551,1555],{"type":29,"tag":127,"props":1552,"children":1553},{"style":688},[1554],{"type":56,"value":746},{"type":29,"tag":127,"props":1556,"children":1557},{"style":720},[1558],{"type":56,"value":1559},"/letsencrypt:/letsencrypt\n",{"type":29,"tag":48,"props":1561,"children":1562},{},[1563],{"type":56,"value":1564},"Erklären wir das ein wenig:",{"type":29,"tag":965,"props":1566,"children":1567},{},[1568,1581,1586,1591,1596],{"type":29,"tag":814,"props":1569,"children":1570},{},[1571,1573,1579],{"type":56,"value":1572},"Wir konfigurieren einen ",{"type":29,"tag":645,"props":1574,"children":1576},{"href":1575},"https://letsencrypt.org/",[1577],{"type":56,"value":1578},"Let's Encrypt",{"type":56,"value":1580}," Certificates Resolver (11-14)",{"type":29,"tag":814,"props":1582,"children":1583},{},[1584],{"type":56,"value":1585},"Wir hören auf Port 80 und 443 (16-17)",{"type":29,"tag":814,"props":1587,"children":1588},{},[1589],{"type":56,"value":1590},"Wir leiten den gesamten HTTP-Verkehr auf HTTPS um (19-20)",{"type":29,"tag":814,"props":1592,"children":1593},{},[1594],{"type":56,"value":1595},"Und binden den konfigurierten Certificates Resolver daran (21)",{"type":29,"tag":814,"props":1597,"children":1598},{},[1599],{"type":56,"value":1600},"Wir richten den Docker-Provider ein (23-25)",{"type":29,"tag":122,"props":1602,"children":1604},{"id":1603},"erklärung-für-die-zeilen-24-25",[1605],{"type":56,"value":1606},"Erklärung für die Zeilen 24-25",{"type":29,"tag":659,"props":1608,"children":1610},{"code":1609},"--providers.docker.defaultrule=Host(`{{ trimPrefix 'app-'.Name }}.example.com`)\n",[1611],{"type":29,"tag":672,"props":1612,"children":1613},{"__ignoreMap":7},[1614],{"type":56,"value":1609},{"type":29,"tag":810,"props":1616,"children":1617},{},[1618,1652],{"type":29,"tag":814,"props":1619,"children":1620},{},[1621,1627,1629,1635,1637,1642,1644,1650],{"type":29,"tag":672,"props":1622,"children":1624},{"className":1623},[],[1625],{"type":56,"value":1626},".Name",{"type":56,"value":1628}," wird automatisch als ",{"type":29,"tag":672,"props":1630,"children":1632},{"className":1631},[],[1633],{"type":56,"value":1634},"\u003Cservice-name>-\u003Cstack_name>",{"type":56,"value":1636}," generiert. Für dein ",{"type":29,"tag":672,"props":1638,"children":1640},{"className":1639},[],[1641],{"type":56,"value":822},{"type":56,"value":1643},"-Beispiel wäre das also ",{"type":29,"tag":672,"props":1645,"children":1647},{"className":1646},[],[1648],{"type":56,"value":1649},"app-whoami",{"type":56,"value":1651},".",{"type":29,"tag":814,"props":1653,"children":1654},{},[1655,1661,1663,1668],{"type":29,"tag":672,"props":1656,"children":1658},{"className":1657},[],[1659],{"type":56,"value":1660},"trimPrefix 'app-'.Name",{"type":56,"value":1662}," ergibt ",{"type":29,"tag":672,"props":1664,"children":1666},{"className":1665},[],[1667],{"type":56,"value":822},{"type":56,"value":1651},{"type":29,"tag":1670,"props":1671,"children":1672},"br",{},[],{"type":29,"tag":659,"props":1674,"children":1675},{"code":1520},[1676],{"type":29,"tag":672,"props":1677,"children":1678},{"__ignoreMap":7},[1679],{"type":56,"value":1520},{"type":29,"tag":48,"props":1681,"children":1682},{},[1683,1685,1690,1692,1698,1700,1706],{"type":56,"value":1684},"Alle Dienste sollten standardmäßig verfügbar sein, aber sie sollten gefiltert werden, sodass nur ",{"type":29,"tag":672,"props":1686,"children":1688},{"className":1687},[],[1689],{"type":56,"value":1128},{"type":56,"value":1691},"-Dienste berücksichtigt werden. Das Label ",{"type":29,"tag":672,"props":1693,"children":1695},{"className":1694},[],[1696],{"type":56,"value":1697},"com.docker.compose.service",{"type":56,"value":1699}," wird von ",{"type":29,"tag":672,"props":1701,"children":1703},{"className":1702},[],[1704],{"type":56,"value":1705},"docker-compose",{"type":56,"value":1707}," automatisch zu allen Containern hinzugefügt.",{"type":29,"tag":90,"props":1709,"children":1711},{"id":1710},"bonus-konfiguration",[1712],{"type":56,"value":1713},"Bonus-Konfiguration",{"type":29,"tag":48,"props":1715,"children":1716},{},[1717],{"type":56,"value":1718},"Wir können diese Konfiguration noch weiter verfeinern.",{"type":29,"tag":122,"props":1720,"children":1722},{"id":1721},"andere-dienste-im-stack-verfügbar-machen",[1723],{"type":56,"value":1724},"Andere Dienste im Stack verfügbar machen",{"type":29,"tag":48,"props":1726,"children":1727},{},[1728],{"type":56,"value":1729},"Manchmal möchte man mehr als nur den App-Container nach außen hin öffnen.",{"type":29,"tag":48,"props":1731,"children":1732},{},[1733,1735,1740],{"type":56,"value":1734},"Die aktuelle Konfiguration leitet den Datenverkehr nur an unsere ",{"type":29,"tag":672,"props":1736,"children":1738},{"className":1737},[],[1739],{"type":56,"value":1128},{"type":56,"value":1741},"-Dienste weiter.\nUm weiterhin die Standard-Konfigurationsmethode nutzen zu können, müssen wir diese wieder aktivieren:",{"type":29,"tag":659,"props":1743,"children":1745},{"code":1744},"--providers.docker.constraints=Label(`com.docker.compose.service`,`app`) || Label(`traefik.enable`, `true`)\n",[1746],{"type":29,"tag":672,"props":1747,"children":1748},{"__ignoreMap":7},[1749],{"type":56,"value":1744},{"type":29,"tag":122,"props":1751,"children":1753},{"id":1752},"stack-name-weicht-vom-verzeichnisnamen-ab",[1754],{"type":56,"value":1755},"Stack-Name weicht vom Verzeichnisnamen ab",{"type":29,"tag":48,"props":1757,"children":1758},{},[1759,1761,1766],{"type":56,"value":1760},"Beim Deployment der Stacks wird der Name basierend auf dem Verzeichnisnamen generiert, in dem sich die ",{"type":29,"tag":672,"props":1762,"children":1764},{"className":1763},[],[1765],{"type":56,"value":961},{"type":56,"value":1767}," Datei befindet.\nWir können den Namen auf verschiedene Arten ändern, aber hier ist die einfachste:",{"type":29,"tag":659,"props":1769,"children":1773},{"code":1770,"filename":1771,"highlights":1772,"language":508,"meta":7,"className":669,"style":7},"name: whoami # Projektname manuell setzen\nservices:\n  app:\n    image: traefik/whoami\n","whoami-example/docker-compose.yaml",[678],[1774],{"type":29,"tag":672,"props":1775,"children":1776},{"__ignoreMap":7},[1777,1800,1811,1822],{"type":29,"tag":127,"props":1778,"children":1780},{"class":1779,"line":678},[677,740],[1781,1786,1790,1794],{"type":29,"tag":127,"props":1782,"children":1783},{"style":682},[1784],{"type":56,"value":1785},"name",{"type":29,"tag":127,"props":1787,"children":1788},{"style":688},[1789],{"type":56,"value":717},{"type":29,"tag":127,"props":1791,"children":1792},{"style":720},[1793],{"type":56,"value":822},{"type":29,"tag":127,"props":1795,"children":1797},{"style":1796},"--shiki-default:#6A737D;--shiki-dark:#6A737D;--shiki-sepia:#88846F",[1798],{"type":56,"value":1799}," # Projektname manuell setzen\n",{"type":29,"tag":127,"props":1801,"children":1802},{"class":677,"line":342},[1803,1807],{"type":29,"tag":127,"props":1804,"children":1805},{"style":682},[1806],{"type":56,"value":685},{"type":29,"tag":127,"props":1808,"children":1809},{"style":688},[1810],{"type":56,"value":691},{"type":29,"tag":127,"props":1812,"children":1813},{"class":677,"line":706},[1814,1818],{"type":29,"tag":127,"props":1815,"children":1816},{"style":682},[1817],{"type":56,"value":1168},{"type":29,"tag":127,"props":1819,"children":1820},{"style":688},[1821],{"type":56,"value":691},{"type":29,"tag":127,"props":1823,"children":1824},{"class":677,"line":726},[1825,1829,1833],{"type":29,"tag":127,"props":1826,"children":1827},{"style":682},[1828],{"type":56,"value":712},{"type":29,"tag":127,"props":1830,"children":1831},{"style":688},[1832],{"type":56,"value":717},{"type":29,"tag":127,"props":1834,"children":1835},{"style":720},[1836],{"type":56,"value":723},{"type":29,"tag":1838,"props":1839,"children":1840},"style",{},[1841],{"type":56,"value":1842},"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 .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}",{"title":7,"searchDepth":342,"depth":342,"links":1844},[1845,1846,1849],{"id":886,"depth":342,"text":889},{"id":985,"depth":342,"text":988,"children":1847},[1848],{"id":1603,"depth":706,"text":1606},{"id":1710,"depth":342,"text":1713,"children":1850},[1851,1852],{"id":1721,"depth":706,"text":1724},{"id":1752,"depth":706,"text":1755},{"_path":530,"_dir":515,"_draft":6,"_partial":6,"_locale":7,"title":531,"description":532,"author":518,"image":519,"releaseDate":533,"blogCategories":1854,"articleTags":1855,"tags":1856,"body":1857,"_type":346,"_id":539,"_source":348,"_file":540,"_stem":541,"_extension":351},[522,523],[523,536,537],[461,24],{"type":26,"children":1858,"toc":6249},[1859,1866,1871,1883,1888,1893,1929,1934,1940,1945,1951,1964,3014,3019,3046,3056,3059,3072,3095,3230,3242,3247,3253,3265,3286,3688,3729,3734,3755,3897,3909,3915,3927,3932,3944,3979,3984,4911,4916,5015,5020,5079,5090,5095,5116,5251,5261,5267,5288,5291,5294,5300,5306,5311,5329,5379,5535,5541,5546,5557,5570,5793,6198,6203,6245],{"type":29,"tag":61,"props":1860,"children":1865},{"alt":7,"aspect-ratio":1861,"height":1862,"object-fit":1863,"src":1864},"1.78",300,"fill","/blog/shopware-plugin-release.png",[],{"type":29,"tag":48,"props":1867,"children":1868},{},[1869],{"type":56,"value":1870},"Es gibt viele Möglichkeiten, Shopware 6 Plugins zu installieren. Sie können sie direkt im Admin-Panel herunterladen oder mit Composer installieren.",{"type":29,"tag":48,"props":1872,"children":1873},{},[1874,1876,1882],{"type":56,"value":1875},"Einen detaillierten Vergleich finden Sie in der ",{"type":29,"tag":645,"props":1877,"children":1879},{"href":1878},"https://developer.shopware.com/docs/guides/plugins/plugins/",[1880],{"type":56,"value":1881},"offiziellen Dokumentation",{"type":56,"value":1651},{"type":29,"tag":48,"props":1884,"children":1885},{},[1886],{"type":56,"value":1887},"Als Entwickler und Betreuer von Themes, Anpassungen, Drittanbieter-APIs usw. konzentriere ich mich auf statische Plugins.",{"type":29,"tag":48,"props":1889,"children":1890},{},[1891],{"type":56,"value":1892},"Der Workflow ist einfach:",{"type":29,"tag":965,"props":1894,"children":1895},{},[1896,1907,1918],{"type":29,"tag":814,"props":1897,"children":1898},{},[1899,1901],{"type":56,"value":1900},"Erstelle ein Plugin mit ",{"type":29,"tag":672,"props":1902,"children":1904},{"className":1903},[],[1905],{"type":56,"value":1906},"bin/console plugin:create --static",{"type":29,"tag":814,"props":1908,"children":1909},{},[1910,1912],{"type":56,"value":1911},"Installiere es mit ",{"type":29,"tag":645,"props":1913,"children":1915},{"href":1914},"https://developer.shopware.com/docs/guides/plugins/plugins/#static-plugins",[1916],{"type":56,"value":1917},"Composer",{"type":29,"tag":814,"props":1919,"children":1920},{},[1921,1923],{"type":56,"value":1922},"Baue das Projekt mit ",{"type":29,"tag":645,"props":1924,"children":1926},{"href":1925},"https://developer.shopware.com/docs/products/cli/project-commands/build.html#example-docker-image",[1927],{"type":56,"value":1928},"shopware-cli",{"type":29,"tag":48,"props":1930,"children":1931},{},[1932],{"type":56,"value":1933},"Wenn wir dasselbe Plugin in mehr als einem Shop benötigen, könnten wir dasselbe Plugin mehrfach erstellen, das wäre aber für die Wartung nicht optimal.",{"type":29,"tag":90,"props":1935,"children":1937},{"id":1936},"das-plugin-extrahieren",[1938],{"type":56,"value":1939},"Das Plugin extrahieren",{"type":29,"tag":48,"props":1941,"children":1942},{},[1943],{"type":56,"value":1944},"Wir fangen damit an, dass wir den Quellcode unseres Plugins in ein separates Repository verschieben. Um die Sache vorerst einfach zu machen, machen wir das Repository öffentlich.",{"type":29,"tag":122,"props":1946,"children":1948},{"id":1947},"download-mit-git",[1949],{"type":56,"value":1950},"Download mit Git",{"type":29,"tag":48,"props":1952,"children":1953},{},[1954,1956,1962],{"type":56,"value":1955},"Wir müssen ",{"type":29,"tag":672,"props":1957,"children":1959},{"className":1958},[],[1960],{"type":56,"value":1961},"composer",{"type":56,"value":1963}," nur mitteilen, wo unser Plugin zu finden ist.",{"type":29,"tag":659,"props":1965,"children":1974},{"className":1966,"code":1967,"filename":1968,"highlights":1969,"language":454,"meta":7,"style":7},"language-json shiki shiki-themes github-dark github-dark monokai","{\n  \"name\": \"shopware/production\",\n  \"license\": \"MIT\",\n  \"type\": \"project\",\n  \"require\": {\n    \"composer-runtime-api\": \"^2.0\",\n    \"acme/sample-plugin\": \"^1.0\",\n    \"shopware/administration\": \"*\",\n    \"shopware/core\": \"6.6.10.2\",\n    \"shopware/elasticsearch\": \"*\",\n    \"shopware/storefront\": \"*\",\n    \"symfony/flex\": \"~2\"\n  },\n  \"repositories\": [\n    {\n      \"type\": \"path\",\n      \"url\": \"custom/plugins/*\",\n      \"options\": {\n        \"symlink\": true\n      }\n    },\n    {\n      \"type\": \"path\",\n      \"url\": \"custom/plugins/*/packages/*\",\n      \"options\": {\n        \"symlink\": true\n      }\n    },\n    {\n      \"type\": \"path\",\n      \"url\": \"custom/static-plugins/*\",\n      \"options\": {\n        \"symlink\": true\n      }\n    },\n    {\n      \"type\": \"git\",\n      \"url\": \"https://\u003CDOMAIN-NAME>/\u003Cgroup>/\u003Crepo>.git\"\n    }\n  ],\n  \"autoload\": {\n    \"psr-4\": {\n      \"App\\\\\": \"src/\"\n    }\n  },\n  \"prefer-stable\": true,\n  \"config\": {\n    \"allow-plugins\": {\n      \"symfony/flex\": true,\n      \"symfony/runtime\": true\n    },\n    \"optimize-autoloader\": true,\n    \"sort-packages\": true\n  },\n  \"scripts\": {\n    \"auto-scripts\": {\n      \"assets:install\": \"symfony-cmd\"\n    },\n    \"post-install-cmd\": [\n      \"@auto-scripts\"\n    ],\n    \"post-update-cmd\": [\n      \"@auto-scripts\"\n    ]\n  },\n  \"extra\": {\n    \"symfony\": {\n      \"allow-contrib\": true,\n      \"endpoint\": [\n        \"https://raw.githubusercontent.com/shopware/recipes/flex/main/index.json\",\n        \"flex://defaults\"\n      ]\n    }\n  }\n}\n","\u003Cproject-root>/composer.json",[1970,1971,1972,1973],36,37,38,39,[1975],{"type":29,"tag":672,"props":1976,"children":1977},{"__ignoreMap":7},[1978,1986,2010,2031,2052,2065,2086,2107,2128,2149,2169,2189,2206,2214,2227,2235,2256,2277,2289,2307,2315,2323,2330,2349,2369,2380,2395,2402,2409,2417,2437,2458,2470,2486,2494,2502,2510,2531,2548,2557,2566,2579,2592,2621,2629,2637,2658,2671,2684,2705,2722,2730,2751,2768,2776,2789,2802,2820,2828,2841,2850,2859,2872,2880,2889,2897,2910,2923,2944,2957,2970,2979,2988,2996,3005],{"type":29,"tag":127,"props":1979,"children":1980},{"class":677,"line":678},[1981],{"type":29,"tag":127,"props":1982,"children":1983},{"style":688},[1984],{"type":56,"value":1985},"{\n",{"type":29,"tag":127,"props":1987,"children":1988},{"class":677,"line":342},[1989,1995,1999,2005],{"type":29,"tag":127,"props":1990,"children":1992},{"style":1991},"--shiki-default:#79B8FF;--shiki-default-font-style:inherit;--shiki-dark:#79B8FF;--shiki-dark-font-style:inherit;--shiki-sepia:#66D9EF;--shiki-sepia-font-style:italic",[1993],{"type":56,"value":1994},"  \"name\"",{"type":29,"tag":127,"props":1996,"children":1997},{"style":688},[1998],{"type":56,"value":717},{"type":29,"tag":127,"props":2000,"children":2002},{"style":2001},"--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#CFCFC2",[2003],{"type":56,"value":2004},"\"shopware/production\"",{"type":29,"tag":127,"props":2006,"children":2007},{"style":688},[2008],{"type":56,"value":2009},",\n",{"type":29,"tag":127,"props":2011,"children":2012},{"class":677,"line":706},[2013,2018,2022,2027],{"type":29,"tag":127,"props":2014,"children":2015},{"style":1991},[2016],{"type":56,"value":2017},"  \"license\"",{"type":29,"tag":127,"props":2019,"children":2020},{"style":688},[2021],{"type":56,"value":717},{"type":29,"tag":127,"props":2023,"children":2024},{"style":2001},[2025],{"type":56,"value":2026},"\"MIT\"",{"type":29,"tag":127,"props":2028,"children":2029},{"style":688},[2030],{"type":56,"value":2009},{"type":29,"tag":127,"props":2032,"children":2033},{"class":677,"line":726},[2034,2039,2043,2048],{"type":29,"tag":127,"props":2035,"children":2036},{"style":1991},[2037],{"type":56,"value":2038},"  \"type\"",{"type":29,"tag":127,"props":2040,"children":2041},{"style":688},[2042],{"type":56,"value":717},{"type":29,"tag":127,"props":2044,"children":2045},{"style":2001},[2046],{"type":56,"value":2047},"\"project\"",{"type":29,"tag":127,"props":2049,"children":2050},{"style":688},[2051],{"type":56,"value":2009},{"type":29,"tag":127,"props":2053,"children":2054},{"class":677,"line":664},[2055,2060],{"type":29,"tag":127,"props":2056,"children":2057},{"style":1991},[2058],{"type":56,"value":2059},"  \"require\"",{"type":29,"tag":127,"props":2061,"children":2062},{"style":688},[2063],{"type":56,"value":2064},": {\n",{"type":29,"tag":127,"props":2066,"children":2067},{"class":677,"line":665},[2068,2073,2077,2082],{"type":29,"tag":127,"props":2069,"children":2070},{"style":1991},[2071],{"type":56,"value":2072},"    \"composer-runtime-api\"",{"type":29,"tag":127,"props":2074,"children":2075},{"style":688},[2076],{"type":56,"value":717},{"type":29,"tag":127,"props":2078,"children":2079},{"style":2001},[2080],{"type":56,"value":2081},"\"^2.0\"",{"type":29,"tag":127,"props":2083,"children":2084},{"style":688},[2085],{"type":56,"value":2009},{"type":29,"tag":127,"props":2087,"children":2088},{"class":677,"line":666},[2089,2094,2098,2103],{"type":29,"tag":127,"props":2090,"children":2091},{"style":1991},[2092],{"type":56,"value":2093},"    \"acme/sample-plugin\"",{"type":29,"tag":127,"props":2095,"children":2096},{"style":688},[2097],{"type":56,"value":717},{"type":29,"tag":127,"props":2099,"children":2100},{"style":2001},[2101],{"type":56,"value":2102},"\"^1.0\"",{"type":29,"tag":127,"props":2104,"children":2105},{"style":688},[2106],{"type":56,"value":2009},{"type":29,"tag":127,"props":2108,"children":2109},{"class":677,"line":667},[2110,2115,2119,2124],{"type":29,"tag":127,"props":2111,"children":2112},{"style":1991},[2113],{"type":56,"value":2114},"    \"shopware/administration\"",{"type":29,"tag":127,"props":2116,"children":2117},{"style":688},[2118],{"type":56,"value":717},{"type":29,"tag":127,"props":2120,"children":2121},{"style":2001},[2122],{"type":56,"value":2123},"\"*\"",{"type":29,"tag":127,"props":2125,"children":2126},{"style":688},[2127],{"type":56,"value":2009},{"type":29,"tag":127,"props":2129,"children":2130},{"class":677,"line":668},[2131,2136,2140,2145],{"type":29,"tag":127,"props":2132,"children":2133},{"style":1991},[2134],{"type":56,"value":2135},"    \"shopware/core\"",{"type":29,"tag":127,"props":2137,"children":2138},{"style":688},[2139],{"type":56,"value":717},{"type":29,"tag":127,"props":2141,"children":2142},{"style":2001},[2143],{"type":56,"value":2144},"\"6.6.10.2\"",{"type":29,"tag":127,"props":2146,"children":2147},{"style":688},[2148],{"type":56,"value":2009},{"type":29,"tag":127,"props":2150,"children":2151},{"class":677,"line":1329},[2152,2157,2161,2165],{"type":29,"tag":127,"props":2153,"children":2154},{"style":1991},[2155],{"type":56,"value":2156},"    \"shopware/elasticsearch\"",{"type":29,"tag":127,"props":2158,"children":2159},{"style":688},[2160],{"type":56,"value":717},{"type":29,"tag":127,"props":2162,"children":2163},{"style":2001},[2164],{"type":56,"value":2123},{"type":29,"tag":127,"props":2166,"children":2167},{"style":688},[2168],{"type":56,"value":2009},{"type":29,"tag":127,"props":2170,"children":2171},{"class":677,"line":1342},[2172,2177,2181,2185],{"type":29,"tag":127,"props":2173,"children":2174},{"style":1991},[2175],{"type":56,"value":2176},"    \"shopware/storefront\"",{"type":29,"tag":127,"props":2178,"children":2179},{"style":688},[2180],{"type":56,"value":717},{"type":29,"tag":127,"props":2182,"children":2183},{"style":2001},[2184],{"type":56,"value":2123},{"type":29,"tag":127,"props":2186,"children":2187},{"style":688},[2188],{"type":56,"value":2009},{"type":29,"tag":127,"props":2190,"children":2191},{"class":677,"line":118},[2192,2197,2201],{"type":29,"tag":127,"props":2193,"children":2194},{"style":1991},[2195],{"type":56,"value":2196},"    \"symfony/flex\"",{"type":29,"tag":127,"props":2198,"children":2199},{"style":688},[2200],{"type":56,"value":717},{"type":29,"tag":127,"props":2202,"children":2203},{"style":2001},[2204],{"type":56,"value":2205},"\"~2\"\n",{"type":29,"tag":127,"props":2207,"children":2208},{"class":677,"line":1367},[2209],{"type":29,"tag":127,"props":2210,"children":2211},{"style":688},[2212],{"type":56,"value":2213},"  },\n",{"type":29,"tag":127,"props":2215,"children":2216},{"class":677,"line":1380},[2217,2222],{"type":29,"tag":127,"props":2218,"children":2219},{"style":1991},[2220],{"type":56,"value":2221},"  \"repositories\"",{"type":29,"tag":127,"props":2223,"children":2224},{"style":688},[2225],{"type":56,"value":2226},": [\n",{"type":29,"tag":127,"props":2228,"children":2229},{"class":677,"line":1393},[2230],{"type":29,"tag":127,"props":2231,"children":2232},{"style":688},[2233],{"type":56,"value":2234},"    {\n",{"type":29,"tag":127,"props":2236,"children":2237},{"class":677,"line":1402},[2238,2243,2247,2252],{"type":29,"tag":127,"props":2239,"children":2240},{"style":1991},[2241],{"type":56,"value":2242},"      \"type\"",{"type":29,"tag":127,"props":2244,"children":2245},{"style":688},[2246],{"type":56,"value":717},{"type":29,"tag":127,"props":2248,"children":2249},{"style":2001},[2250],{"type":56,"value":2251},"\"path\"",{"type":29,"tag":127,"props":2253,"children":2254},{"style":688},[2255],{"type":56,"value":2009},{"type":29,"tag":127,"props":2257,"children":2258},{"class":677,"line":1415},[2259,2264,2268,2273],{"type":29,"tag":127,"props":2260,"children":2261},{"style":1991},[2262],{"type":56,"value":2263},"      \"url\"",{"type":29,"tag":127,"props":2265,"children":2266},{"style":688},[2267],{"type":56,"value":717},{"type":29,"tag":127,"props":2269,"children":2270},{"style":2001},[2271],{"type":56,"value":2272},"\"custom/plugins/*\"",{"type":29,"tag":127,"props":2274,"children":2275},{"style":688},[2276],{"type":56,"value":2009},{"type":29,"tag":127,"props":2278,"children":2279},{"class":677,"line":1428},[2280,2285],{"type":29,"tag":127,"props":2281,"children":2282},{"style":1991},[2283],{"type":56,"value":2284},"      \"options\"",{"type":29,"tag":127,"props":2286,"children":2287},{"style":688},[2288],{"type":56,"value":2064},{"type":29,"tag":127,"props":2290,"children":2291},{"class":677,"line":1437},[2292,2297,2301],{"type":29,"tag":127,"props":2293,"children":2294},{"style":1991},[2295],{"type":56,"value":2296},"        \"symlink\"",{"type":29,"tag":127,"props":2298,"children":2299},{"style":688},[2300],{"type":56,"value":717},{"type":29,"tag":127,"props":2302,"children":2304},{"style":2303},"--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF",[2305],{"type":56,"value":2306},"true\n",{"type":29,"tag":127,"props":2308,"children":2309},{"class":677,"line":1450},[2310],{"type":29,"tag":127,"props":2311,"children":2312},{"style":688},[2313],{"type":56,"value":2314},"      }\n",{"type":29,"tag":127,"props":2316,"children":2317},{"class":677,"line":1463},[2318],{"type":29,"tag":127,"props":2319,"children":2320},{"style":688},[2321],{"type":56,"value":2322},"    },\n",{"type":29,"tag":127,"props":2324,"children":2325},{"class":677,"line":1476},[2326],{"type":29,"tag":127,"props":2327,"children":2328},{"style":688},[2329],{"type":56,"value":2234},{"type":29,"tag":127,"props":2331,"children":2332},{"class":677,"line":1484},[2333,2337,2341,2345],{"type":29,"tag":127,"props":2334,"children":2335},{"style":1991},[2336],{"type":56,"value":2242},{"type":29,"tag":127,"props":2338,"children":2339},{"style":688},[2340],{"type":56,"value":717},{"type":29,"tag":127,"props":2342,"children":2343},{"style":2001},[2344],{"type":56,"value":2251},{"type":29,"tag":127,"props":2346,"children":2347},{"style":688},[2348],{"type":56,"value":2009},{"type":29,"tag":127,"props":2350,"children":2351},{"class":677,"line":1497},[2352,2356,2360,2365],{"type":29,"tag":127,"props":2353,"children":2354},{"style":1991},[2355],{"type":56,"value":2263},{"type":29,"tag":127,"props":2357,"children":2358},{"style":688},[2359],{"type":56,"value":717},{"type":29,"tag":127,"props":2361,"children":2362},{"style":2001},[2363],{"type":56,"value":2364},"\"custom/plugins/*/packages/*\"",{"type":29,"tag":127,"props":2366,"children":2367},{"style":688},[2368],{"type":56,"value":2009},{"type":29,"tag":127,"props":2370,"children":2371},{"class":677,"line":1510},[2372,2376],{"type":29,"tag":127,"props":2373,"children":2374},{"style":1991},[2375],{"type":56,"value":2284},{"type":29,"tag":127,"props":2377,"children":2378},{"style":688},[2379],{"type":56,"value":2064},{"type":29,"tag":127,"props":2381,"children":2382},{"class":677,"line":1523},[2383,2387,2391],{"type":29,"tag":127,"props":2384,"children":2385},{"style":1991},[2386],{"type":56,"value":2296},{"type":29,"tag":127,"props":2388,"children":2389},{"style":688},[2390],{"type":56,"value":717},{"type":29,"tag":127,"props":2392,"children":2393},{"style":2303},[2394],{"type":56,"value":2306},{"type":29,"tag":127,"props":2396,"children":2397},{"class":677,"line":1536},[2398],{"type":29,"tag":127,"props":2399,"children":2400},{"style":688},[2401],{"type":56,"value":2314},{"type":29,"tag":127,"props":2403,"children":2404},{"class":677,"line":1549},[2405],{"type":29,"tag":127,"props":2406,"children":2407},{"style":688},[2408],{"type":56,"value":2322},{"type":29,"tag":127,"props":2410,"children":2412},{"class":677,"line":2411},29,[2413],{"type":29,"tag":127,"props":2414,"children":2415},{"style":688},[2416],{"type":56,"value":2234},{"type":29,"tag":127,"props":2418,"children":2420},{"class":677,"line":2419},30,[2421,2425,2429,2433],{"type":29,"tag":127,"props":2422,"children":2423},{"style":1991},[2424],{"type":56,"value":2242},{"type":29,"tag":127,"props":2426,"children":2427},{"style":688},[2428],{"type":56,"value":717},{"type":29,"tag":127,"props":2430,"children":2431},{"style":2001},[2432],{"type":56,"value":2251},{"type":29,"tag":127,"props":2434,"children":2435},{"style":688},[2436],{"type":56,"value":2009},{"type":29,"tag":127,"props":2438,"children":2440},{"class":677,"line":2439},31,[2441,2445,2449,2454],{"type":29,"tag":127,"props":2442,"children":2443},{"style":1991},[2444],{"type":56,"value":2263},{"type":29,"tag":127,"props":2446,"children":2447},{"style":688},[2448],{"type":56,"value":717},{"type":29,"tag":127,"props":2450,"children":2451},{"style":2001},[2452],{"type":56,"value":2453},"\"custom/static-plugins/*\"",{"type":29,"tag":127,"props":2455,"children":2456},{"style":688},[2457],{"type":56,"value":2009},{"type":29,"tag":127,"props":2459,"children":2461},{"class":677,"line":2460},32,[2462,2466],{"type":29,"tag":127,"props":2463,"children":2464},{"style":1991},[2465],{"type":56,"value":2284},{"type":29,"tag":127,"props":2467,"children":2468},{"style":688},[2469],{"type":56,"value":2064},{"type":29,"tag":127,"props":2471,"children":2473},{"class":677,"line":2472},33,[2474,2478,2482],{"type":29,"tag":127,"props":2475,"children":2476},{"style":1991},[2477],{"type":56,"value":2296},{"type":29,"tag":127,"props":2479,"children":2480},{"style":688},[2481],{"type":56,"value":717},{"type":29,"tag":127,"props":2483,"children":2484},{"style":2303},[2485],{"type":56,"value":2306},{"type":29,"tag":127,"props":2487,"children":2489},{"class":677,"line":2488},34,[2490],{"type":29,"tag":127,"props":2491,"children":2492},{"style":688},[2493],{"type":56,"value":2314},{"type":29,"tag":127,"props":2495,"children":2497},{"class":677,"line":2496},35,[2498],{"type":29,"tag":127,"props":2499,"children":2500},{"style":688},[2501],{"type":56,"value":2322},{"type":29,"tag":127,"props":2503,"children":2505},{"class":2504,"line":1970},[677,740],[2506],{"type":29,"tag":127,"props":2507,"children":2508},{"style":688},[2509],{"type":56,"value":2234},{"type":29,"tag":127,"props":2511,"children":2513},{"class":2512,"line":1971},[677,740],[2514,2518,2522,2527],{"type":29,"tag":127,"props":2515,"children":2516},{"style":1991},[2517],{"type":56,"value":2242},{"type":29,"tag":127,"props":2519,"children":2520},{"style":688},[2521],{"type":56,"value":717},{"type":29,"tag":127,"props":2523,"children":2524},{"style":2001},[2525],{"type":56,"value":2526},"\"git\"",{"type":29,"tag":127,"props":2528,"children":2529},{"style":688},[2530],{"type":56,"value":2009},{"type":29,"tag":127,"props":2532,"children":2534},{"class":2533,"line":1972},[677,740],[2535,2539,2543],{"type":29,"tag":127,"props":2536,"children":2537},{"style":1991},[2538],{"type":56,"value":2263},{"type":29,"tag":127,"props":2540,"children":2541},{"style":688},[2542],{"type":56,"value":717},{"type":29,"tag":127,"props":2544,"children":2545},{"style":2001},[2546],{"type":56,"value":2547},"\"https://\u003CDOMAIN-NAME>/\u003Cgroup>/\u003Crepo>.git\"\n",{"type":29,"tag":127,"props":2549,"children":2551},{"class":2550,"line":1973},[677,740],[2552],{"type":29,"tag":127,"props":2553,"children":2554},{"style":688},[2555],{"type":56,"value":2556},"    }\n",{"type":29,"tag":127,"props":2558,"children":2560},{"class":677,"line":2559},40,[2561],{"type":29,"tag":127,"props":2562,"children":2563},{"style":688},[2564],{"type":56,"value":2565},"  ],\n",{"type":29,"tag":127,"props":2567,"children":2569},{"class":677,"line":2568},41,[2570,2575],{"type":29,"tag":127,"props":2571,"children":2572},{"style":1991},[2573],{"type":56,"value":2574},"  \"autoload\"",{"type":29,"tag":127,"props":2576,"children":2577},{"style":688},[2578],{"type":56,"value":2064},{"type":29,"tag":127,"props":2580,"children":2582},{"class":677,"line":2581},42,[2583,2588],{"type":29,"tag":127,"props":2584,"children":2585},{"style":1991},[2586],{"type":56,"value":2587},"    \"psr-4\"",{"type":29,"tag":127,"props":2589,"children":2590},{"style":688},[2591],{"type":56,"value":2064},{"type":29,"tag":127,"props":2593,"children":2595},{"class":677,"line":2594},43,[2596,2601,2607,2612,2616],{"type":29,"tag":127,"props":2597,"children":2598},{"style":1991},[2599],{"type":56,"value":2600},"      \"App",{"type":29,"tag":127,"props":2602,"children":2604},{"style":2603},"--shiki-default:#79B8FF;--shiki-default-font-style:inherit;--shiki-dark:#79B8FF;--shiki-dark-font-style:inherit;--shiki-sepia:#AE81FF;--shiki-sepia-font-style:italic",[2605],{"type":56,"value":2606},"\\\\",{"type":29,"tag":127,"props":2608,"children":2609},{"style":1991},[2610],{"type":56,"value":2611},"\"",{"type":29,"tag":127,"props":2613,"children":2614},{"style":688},[2615],{"type":56,"value":717},{"type":29,"tag":127,"props":2617,"children":2618},{"style":2001},[2619],{"type":56,"value":2620},"\"src/\"\n",{"type":29,"tag":127,"props":2622,"children":2624},{"class":677,"line":2623},44,[2625],{"type":29,"tag":127,"props":2626,"children":2627},{"style":688},[2628],{"type":56,"value":2556},{"type":29,"tag":127,"props":2630,"children":2632},{"class":677,"line":2631},45,[2633],{"type":29,"tag":127,"props":2634,"children":2635},{"style":688},[2636],{"type":56,"value":2213},{"type":29,"tag":127,"props":2638,"children":2640},{"class":677,"line":2639},46,[2641,2646,2650,2654],{"type":29,"tag":127,"props":2642,"children":2643},{"style":1991},[2644],{"type":56,"value":2645},"  \"prefer-stable\"",{"type":29,"tag":127,"props":2647,"children":2648},{"style":688},[2649],{"type":56,"value":717},{"type":29,"tag":127,"props":2651,"children":2652},{"style":2303},[2653],{"type":56,"value":113},{"type":29,"tag":127,"props":2655,"children":2656},{"style":688},[2657],{"type":56,"value":2009},{"type":29,"tag":127,"props":2659,"children":2661},{"class":677,"line":2660},47,[2662,2667],{"type":29,"tag":127,"props":2663,"children":2664},{"style":1991},[2665],{"type":56,"value":2666},"  \"config\"",{"type":29,"tag":127,"props":2668,"children":2669},{"style":688},[2670],{"type":56,"value":2064},{"type":29,"tag":127,"props":2672,"children":2674},{"class":677,"line":2673},48,[2675,2680],{"type":29,"tag":127,"props":2676,"children":2677},{"style":1991},[2678],{"type":56,"value":2679},"    \"allow-plugins\"",{"type":29,"tag":127,"props":2681,"children":2682},{"style":688},[2683],{"type":56,"value":2064},{"type":29,"tag":127,"props":2685,"children":2687},{"class":677,"line":2686},49,[2688,2693,2697,2701],{"type":29,"tag":127,"props":2689,"children":2690},{"style":1991},[2691],{"type":56,"value":2692},"      \"symfony/flex\"",{"type":29,"tag":127,"props":2694,"children":2695},{"style":688},[2696],{"type":56,"value":717},{"type":29,"tag":127,"props":2698,"children":2699},{"style":2303},[2700],{"type":56,"value":113},{"type":29,"tag":127,"props":2702,"children":2703},{"style":688},[2704],{"type":56,"value":2009},{"type":29,"tag":127,"props":2706,"children":2708},{"class":677,"line":2707},50,[2709,2714,2718],{"type":29,"tag":127,"props":2710,"children":2711},{"style":1991},[2712],{"type":56,"value":2713},"      \"symfony/runtime\"",{"type":29,"tag":127,"props":2715,"children":2716},{"style":688},[2717],{"type":56,"value":717},{"type":29,"tag":127,"props":2719,"children":2720},{"style":2303},[2721],{"type":56,"value":2306},{"type":29,"tag":127,"props":2723,"children":2725},{"class":677,"line":2724},51,[2726],{"type":29,"tag":127,"props":2727,"children":2728},{"style":688},[2729],{"type":56,"value":2322},{"type":29,"tag":127,"props":2731,"children":2733},{"class":677,"line":2732},52,[2734,2739,2743,2747],{"type":29,"tag":127,"props":2735,"children":2736},{"style":1991},[2737],{"type":56,"value":2738},"    \"optimize-autoloader\"",{"type":29,"tag":127,"props":2740,"children":2741},{"style":688},[2742],{"type":56,"value":717},{"type":29,"tag":127,"props":2744,"children":2745},{"style":2303},[2746],{"type":56,"value":113},{"type":29,"tag":127,"props":2748,"children":2749},{"style":688},[2750],{"type":56,"value":2009},{"type":29,"tag":127,"props":2752,"children":2754},{"class":677,"line":2753},53,[2755,2760,2764],{"type":29,"tag":127,"props":2756,"children":2757},{"style":1991},[2758],{"type":56,"value":2759},"    \"sort-packages\"",{"type":29,"tag":127,"props":2761,"children":2762},{"style":688},[2763],{"type":56,"value":717},{"type":29,"tag":127,"props":2765,"children":2766},{"style":2303},[2767],{"type":56,"value":2306},{"type":29,"tag":127,"props":2769,"children":2771},{"class":677,"line":2770},54,[2772],{"type":29,"tag":127,"props":2773,"children":2774},{"style":688},[2775],{"type":56,"value":2213},{"type":29,"tag":127,"props":2777,"children":2779},{"class":677,"line":2778},55,[2780,2785],{"type":29,"tag":127,"props":2781,"children":2782},{"style":1991},[2783],{"type":56,"value":2784},"  \"scripts\"",{"type":29,"tag":127,"props":2786,"children":2787},{"style":688},[2788],{"type":56,"value":2064},{"type":29,"tag":127,"props":2790,"children":2792},{"class":677,"line":2791},56,[2793,2798],{"type":29,"tag":127,"props":2794,"children":2795},{"style":1991},[2796],{"type":56,"value":2797},"    \"auto-scripts\"",{"type":29,"tag":127,"props":2799,"children":2800},{"style":688},[2801],{"type":56,"value":2064},{"type":29,"tag":127,"props":2803,"children":2805},{"class":677,"line":2804},57,[2806,2811,2815],{"type":29,"tag":127,"props":2807,"children":2808},{"style":1991},[2809],{"type":56,"value":2810},"      \"assets:install\"",{"type":29,"tag":127,"props":2812,"children":2813},{"style":688},[2814],{"type":56,"value":717},{"type":29,"tag":127,"props":2816,"children":2817},{"style":2001},[2818],{"type":56,"value":2819},"\"symfony-cmd\"\n",{"type":29,"tag":127,"props":2821,"children":2823},{"class":677,"line":2822},58,[2824],{"type":29,"tag":127,"props":2825,"children":2826},{"style":688},[2827],{"type":56,"value":2322},{"type":29,"tag":127,"props":2829,"children":2831},{"class":677,"line":2830},59,[2832,2837],{"type":29,"tag":127,"props":2833,"children":2834},{"style":1991},[2835],{"type":56,"value":2836},"    \"post-install-cmd\"",{"type":29,"tag":127,"props":2838,"children":2839},{"style":688},[2840],{"type":56,"value":2226},{"type":29,"tag":127,"props":2842,"children":2844},{"class":677,"line":2843},60,[2845],{"type":29,"tag":127,"props":2846,"children":2847},{"style":2001},[2848],{"type":56,"value":2849},"      \"@auto-scripts\"\n",{"type":29,"tag":127,"props":2851,"children":2853},{"class":677,"line":2852},61,[2854],{"type":29,"tag":127,"props":2855,"children":2856},{"style":688},[2857],{"type":56,"value":2858},"    ],\n",{"type":29,"tag":127,"props":2860,"children":2862},{"class":677,"line":2861},62,[2863,2868],{"type":29,"tag":127,"props":2864,"children":2865},{"style":1991},[2866],{"type":56,"value":2867},"    \"post-update-cmd\"",{"type":29,"tag":127,"props":2869,"children":2870},{"style":688},[2871],{"type":56,"value":2226},{"type":29,"tag":127,"props":2873,"children":2875},{"class":677,"line":2874},63,[2876],{"type":29,"tag":127,"props":2877,"children":2878},{"style":2001},[2879],{"type":56,"value":2849},{"type":29,"tag":127,"props":2881,"children":2883},{"class":677,"line":2882},64,[2884],{"type":29,"tag":127,"props":2885,"children":2886},{"style":688},[2887],{"type":56,"value":2888},"    ]\n",{"type":29,"tag":127,"props":2890,"children":2892},{"class":677,"line":2891},65,[2893],{"type":29,"tag":127,"props":2894,"children":2895},{"style":688},[2896],{"type":56,"value":2213},{"type":29,"tag":127,"props":2898,"children":2900},{"class":677,"line":2899},66,[2901,2906],{"type":29,"tag":127,"props":2902,"children":2903},{"style":1991},[2904],{"type":56,"value":2905},"  \"extra\"",{"type":29,"tag":127,"props":2907,"children":2908},{"style":688},[2909],{"type":56,"value":2064},{"type":29,"tag":127,"props":2911,"children":2913},{"class":677,"line":2912},67,[2914,2919],{"type":29,"tag":127,"props":2915,"children":2916},{"style":1991},[2917],{"type":56,"value":2918},"    \"symfony\"",{"type":29,"tag":127,"props":2920,"children":2921},{"style":688},[2922],{"type":56,"value":2064},{"type":29,"tag":127,"props":2924,"children":2926},{"class":677,"line":2925},68,[2927,2932,2936,2940],{"type":29,"tag":127,"props":2928,"children":2929},{"style":1991},[2930],{"type":56,"value":2931},"      \"allow-contrib\"",{"type":29,"tag":127,"props":2933,"children":2934},{"style":688},[2935],{"type":56,"value":717},{"type":29,"tag":127,"props":2937,"children":2938},{"style":2303},[2939],{"type":56,"value":113},{"type":29,"tag":127,"props":2941,"children":2942},{"style":688},[2943],{"type":56,"value":2009},{"type":29,"tag":127,"props":2945,"children":2947},{"class":677,"line":2946},69,[2948,2953],{"type":29,"tag":127,"props":2949,"children":2950},{"style":1991},[2951],{"type":56,"value":2952},"      \"endpoint\"",{"type":29,"tag":127,"props":2954,"children":2955},{"style":688},[2956],{"type":56,"value":2226},{"type":29,"tag":127,"props":2958,"children":2960},{"class":677,"line":2959},70,[2961,2966],{"type":29,"tag":127,"props":2962,"children":2963},{"style":2001},[2964],{"type":56,"value":2965},"        \"https://raw.githubusercontent.com/shopware/recipes/flex/main/index.json\"",{"type":29,"tag":127,"props":2967,"children":2968},{"style":688},[2969],{"type":56,"value":2009},{"type":29,"tag":127,"props":2971,"children":2973},{"class":677,"line":2972},71,[2974],{"type":29,"tag":127,"props":2975,"children":2976},{"style":2001},[2977],{"type":56,"value":2978},"        \"flex://defaults\"\n",{"type":29,"tag":127,"props":2980,"children":2982},{"class":677,"line":2981},72,[2983],{"type":29,"tag":127,"props":2984,"children":2985},{"style":688},[2986],{"type":56,"value":2987},"      ]\n",{"type":29,"tag":127,"props":2989,"children":2991},{"class":677,"line":2990},73,[2992],{"type":29,"tag":127,"props":2993,"children":2994},{"style":688},[2995],{"type":56,"value":2556},{"type":29,"tag":127,"props":2997,"children":2999},{"class":677,"line":2998},74,[3000],{"type":29,"tag":127,"props":3001,"children":3002},{"style":688},[3003],{"type":56,"value":3004},"  }\n",{"type":29,"tag":127,"props":3006,"children":3008},{"class":677,"line":3007},75,[3009],{"type":29,"tag":127,"props":3010,"children":3011},{"style":688},[3012],{"type":56,"value":3013},"}\n",{"type":29,"tag":48,"props":3015,"children":3016},{},[3017],{"type":56,"value":3018},"und installieren es mit",{"type":29,"tag":659,"props":3020,"children":3024},{"className":3021,"code":3022,"language":3023,"meta":7,"style":7},"language-shell shiki shiki-themes github-dark github-dark monokai","composer req acme/sample-plugin\n","shell",[3025],{"type":29,"tag":672,"props":3026,"children":3027},{"__ignoreMap":7},[3028],{"type":29,"tag":127,"props":3029,"children":3030},{"class":677,"line":678},[3031,3036,3041],{"type":29,"tag":127,"props":3032,"children":3034},{"style":3033},"--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E",[3035],{"type":56,"value":1961},{"type":29,"tag":127,"props":3037,"children":3038},{"style":720},[3039],{"type":56,"value":3040}," req",{"type":29,"tag":127,"props":3042,"children":3043},{"style":720},[3044],{"type":56,"value":3045}," acme/sample-plugin\n",{"type":29,"tag":3047,"props":3048,"children":3050},"v-alert",{"type":3049},"error",[3051],{"type":29,"tag":48,"props":3052,"children":3053},{},[3054],{"type":56,"value":3055},"Could not find a version of package acme/sample-plugin matching your minimum-stability (stable).\nRequire it with an explicit version constraint allowing its desired stability.",{"type":29,"tag":1670,"props":3057,"children":3058},{},[],{"type":29,"tag":48,"props":3060,"children":3061},{},[3062,3064,3070],{"type":56,"value":3063},"Ja... das ist der Nachteil. Wir müssen ",{"type":29,"tag":672,"props":3065,"children":3067},{"className":3066},[],[3068],{"type":56,"value":3069},"dev-master",{"type":56,"value":3071}," als Version verwenden",{"type":29,"tag":659,"props":3073,"children":3075},{"className":3021,"code":3074,"language":3023,"meta":7,"style":7},"composer req acme/sample-plugin:dev-master\n",[3076],{"type":29,"tag":672,"props":3077,"children":3078},{"__ignoreMap":7},[3079],{"type":29,"tag":127,"props":3080,"children":3081},{"class":677,"line":678},[3082,3086,3090],{"type":29,"tag":127,"props":3083,"children":3084},{"style":3033},[3085],{"type":56,"value":1961},{"type":29,"tag":127,"props":3087,"children":3088},{"style":720},[3089],{"type":56,"value":3040},{"type":29,"tag":127,"props":3091,"children":3092},{"style":720},[3093],{"type":56,"value":3094}," acme/sample-plugin:dev-master\n",{"type":29,"tag":659,"props":3096,"children":3100},{"className":3097,"code":3098,"language":3099,"meta":7,"style":7},"language-output shiki shiki-themes github-dark github-dark monokai","./composer.json has been updated\nRunning composer update acme/sample-plugin\nLoading composer repositories with package information                                                                \nUpdating dependencies                                 \nLock file operations: 1 install, 0 updates, 0 removals\n  - Locking acme/sample-plugin (dev-master 294414d)\nWriting lock file\nInstalling dependencies from lock file (including require-dev)\nPackage operations: 1 install, 0 updates, 0 removals\n  - Syncing acme/sample-plugin (dev-master 294414d) into cache\n  - Installing acme/sample-plugin (dev-master 294414d): Cloning 294414deb2 from cache\nGenerating optimized autoload files\n\nRun composer recipes at any time to see the status of your Symfony recipes.\n\nExecuting script assets:install [OK]\n","output",[3101],{"type":29,"tag":672,"props":3102,"children":3103},{"__ignoreMap":7},[3104,3112,3120,3128,3136,3144,3152,3160,3168,3176,3184,3192,3200,3207,3215,3222],{"type":29,"tag":127,"props":3105,"children":3106},{"class":677,"line":678},[3107],{"type":29,"tag":127,"props":3108,"children":3109},{},[3110],{"type":56,"value":3111},"./composer.json has been updated\n",{"type":29,"tag":127,"props":3113,"children":3114},{"class":677,"line":342},[3115],{"type":29,"tag":127,"props":3116,"children":3117},{},[3118],{"type":56,"value":3119},"Running composer update acme/sample-plugin\n",{"type":29,"tag":127,"props":3121,"children":3122},{"class":677,"line":706},[3123],{"type":29,"tag":127,"props":3124,"children":3125},{},[3126],{"type":56,"value":3127},"Loading composer repositories with package information                                                                \n",{"type":29,"tag":127,"props":3129,"children":3130},{"class":677,"line":726},[3131],{"type":29,"tag":127,"props":3132,"children":3133},{},[3134],{"type":56,"value":3135},"Updating dependencies                                 \n",{"type":29,"tag":127,"props":3137,"children":3138},{"class":677,"line":664},[3139],{"type":29,"tag":127,"props":3140,"children":3141},{},[3142],{"type":56,"value":3143},"Lock file operations: 1 install, 0 updates, 0 removals\n",{"type":29,"tag":127,"props":3145,"children":3146},{"class":677,"line":665},[3147],{"type":29,"tag":127,"props":3148,"children":3149},{},[3150],{"type":56,"value":3151},"  - Locking acme/sample-plugin (dev-master 294414d)\n",{"type":29,"tag":127,"props":3153,"children":3154},{"class":677,"line":666},[3155],{"type":29,"tag":127,"props":3156,"children":3157},{},[3158],{"type":56,"value":3159},"Writing lock file\n",{"type":29,"tag":127,"props":3161,"children":3162},{"class":677,"line":667},[3163],{"type":29,"tag":127,"props":3164,"children":3165},{},[3166],{"type":56,"value":3167},"Installing dependencies from lock file (including require-dev)\n",{"type":29,"tag":127,"props":3169,"children":3170},{"class":677,"line":668},[3171],{"type":29,"tag":127,"props":3172,"children":3173},{},[3174],{"type":56,"value":3175},"Package operations: 1 install, 0 updates, 0 removals\n",{"type":29,"tag":127,"props":3177,"children":3178},{"class":677,"line":1329},[3179],{"type":29,"tag":127,"props":3180,"children":3181},{},[3182],{"type":56,"value":3183},"  - Syncing acme/sample-plugin (dev-master 294414d) into cache\n",{"type":29,"tag":127,"props":3185,"children":3186},{"class":677,"line":1342},[3187],{"type":29,"tag":127,"props":3188,"children":3189},{},[3190],{"type":56,"value":3191},"  - Installing acme/sample-plugin (dev-master 294414d): Cloning 294414deb2 from cache\n",{"type":29,"tag":127,"props":3193,"children":3194},{"class":677,"line":118},[3195],{"type":29,"tag":127,"props":3196,"children":3197},{},[3198],{"type":56,"value":3199},"Generating optimized autoload files\n",{"type":29,"tag":127,"props":3201,"children":3202},{"class":677,"line":1367},[3203],{"type":29,"tag":127,"props":3204,"children":3205},{"emptyLinePlaceholder":500},[3206],{"type":56,"value":1399},{"type":29,"tag":127,"props":3208,"children":3209},{"class":677,"line":1380},[3210],{"type":29,"tag":127,"props":3211,"children":3212},{},[3213],{"type":56,"value":3214},"Run composer recipes at any time to see the status of your Symfony recipes.\n",{"type":29,"tag":127,"props":3216,"children":3217},{"class":677,"line":1393},[3218],{"type":29,"tag":127,"props":3219,"children":3220},{"emptyLinePlaceholder":500},[3221],{"type":56,"value":1399},{"type":29,"tag":127,"props":3223,"children":3224},{"class":677,"line":1402},[3225],{"type":29,"tag":127,"props":3226,"children":3227},{},[3228],{"type":56,"value":3229},"Executing script assets:install [OK]\n",{"type":29,"tag":48,"props":3231,"children":3232},{},[3233,3235,3240],{"type":56,"value":3234},"Composer wird ",{"type":29,"tag":672,"props":3236,"children":3238},{"className":3237},[],[3239],{"type":56,"value":907},{"type":56,"value":3241}," verwenden, um unser Repository zu klonen, und den Standard-Branch sowie den Commit-Hash verwenden, um den Release zu verfolgen.",{"type":29,"tag":48,"props":3243,"children":3244},{},[3245],{"type":56,"value":3246},"Das funktioniert, aber wir können es besser machen.",{"type":29,"tag":122,"props":3248,"children":3250},{"id":3249},"git-tags",[3251],{"type":56,"value":3252},"Git Tags",{"type":29,"tag":48,"props":3254,"children":3255},{},[3256,3258,3264],{"type":56,"value":3257},"Wir taggen nun unser Plugin als ",{"type":29,"tag":672,"props":3259,"children":3261},{"className":3260},[],[3262],{"type":56,"value":3263},"v1.0.0",{"type":56,"value":1651},{"type":29,"tag":48,"props":3266,"children":3267},{},[3268,3270,3276,3278,3284],{"type":56,"value":3269},"Bitte beachten, dass Sie die ",{"type":29,"tag":672,"props":3271,"children":3273},{"className":3272},[],[3274],{"type":56,"value":3275},"version",{"type":56,"value":3277}," in der ",{"type":29,"tag":672,"props":3279,"children":3281},{"className":3280},[],[3282],{"type":56,"value":3283},"composer.json",{"type":56,"value":3285}," gesetzt ist.",{"type":29,"tag":659,"props":3287,"children":3291},{"className":1966,"code":3288,"filename":3289,"highlights":3290,"language":454,"meta":7,"style":7},"{\n    \"name\": \"acme/sample-plugin\",\n    \"description\": \"acme/sample-plugin\",\n    \"type\": \"shopware-platform-plugin\",\n    \"version\": \"1.0.0\",\n    \"license\": \"MIT\",\n    \"require\": {\n        \"shopware/core\": \"~6.6.0\"\n    },\n    \"extra\": {\n        \"shopware-plugin-class\": \"Acme\\\\SamplePlugin\",\n        \"label\": {\n            \"de-DE\": \"Skeleton plugin\",\n            \"en-GB\": \"Skeleton plugin\"\n        }\n    },\n    \"autoload\": {\n        \"psr-4\": {\n            \"Acme\\\\\": \"src/\"\n        }\n    },\n    \"autoload-dev\": {\n        \"psr-4\": {\n            \"Acme\\\\Tests\\\\\": \"tests/\"\n        }\n    }\n}\n\n","\u003Cplugin-root>/composer.json",[664],[3292],{"type":29,"tag":672,"props":3293,"children":3294},{"__ignoreMap":7},[3295,3302,3323,3343,3364,3386,3406,3418,3435,3442,3454,3484,3496,3517,3534,3542,3549,3561,3573,3597,3604,3611,3623,3634,3667,3674,3681],{"type":29,"tag":127,"props":3296,"children":3297},{"class":677,"line":678},[3298],{"type":29,"tag":127,"props":3299,"children":3300},{"style":688},[3301],{"type":56,"value":1985},{"type":29,"tag":127,"props":3303,"children":3304},{"class":677,"line":342},[3305,3310,3314,3319],{"type":29,"tag":127,"props":3306,"children":3307},{"style":1991},[3308],{"type":56,"value":3309},"    \"name\"",{"type":29,"tag":127,"props":3311,"children":3312},{"style":688},[3313],{"type":56,"value":717},{"type":29,"tag":127,"props":3315,"children":3316},{"style":2001},[3317],{"type":56,"value":3318},"\"acme/sample-plugin\"",{"type":29,"tag":127,"props":3320,"children":3321},{"style":688},[3322],{"type":56,"value":2009},{"type":29,"tag":127,"props":3324,"children":3325},{"class":677,"line":706},[3326,3331,3335,3339],{"type":29,"tag":127,"props":3327,"children":3328},{"style":1991},[3329],{"type":56,"value":3330},"    \"description\"",{"type":29,"tag":127,"props":3332,"children":3333},{"style":688},[3334],{"type":56,"value":717},{"type":29,"tag":127,"props":3336,"children":3337},{"style":2001},[3338],{"type":56,"value":3318},{"type":29,"tag":127,"props":3340,"children":3341},{"style":688},[3342],{"type":56,"value":2009},{"type":29,"tag":127,"props":3344,"children":3345},{"class":677,"line":726},[3346,3351,3355,3360],{"type":29,"tag":127,"props":3347,"children":3348},{"style":1991},[3349],{"type":56,"value":3350},"    \"type\"",{"type":29,"tag":127,"props":3352,"children":3353},{"style":688},[3354],{"type":56,"value":717},{"type":29,"tag":127,"props":3356,"children":3357},{"style":2001},[3358],{"type":56,"value":3359},"\"shopware-platform-plugin\"",{"type":29,"tag":127,"props":3361,"children":3362},{"style":688},[3363],{"type":56,"value":2009},{"type":29,"tag":127,"props":3365,"children":3367},{"class":3366,"line":664},[677,740],[3368,3373,3377,3382],{"type":29,"tag":127,"props":3369,"children":3370},{"style":1991},[3371],{"type":56,"value":3372},"    \"version\"",{"type":29,"tag":127,"props":3374,"children":3375},{"style":688},[3376],{"type":56,"value":717},{"type":29,"tag":127,"props":3378,"children":3379},{"style":2001},[3380],{"type":56,"value":3381},"\"1.0.0\"",{"type":29,"tag":127,"props":3383,"children":3384},{"style":688},[3385],{"type":56,"value":2009},{"type":29,"tag":127,"props":3387,"children":3388},{"class":677,"line":665},[3389,3394,3398,3402],{"type":29,"tag":127,"props":3390,"children":3391},{"style":1991},[3392],{"type":56,"value":3393},"    \"license\"",{"type":29,"tag":127,"props":3395,"children":3396},{"style":688},[3397],{"type":56,"value":717},{"type":29,"tag":127,"props":3399,"children":3400},{"style":2001},[3401],{"type":56,"value":2026},{"type":29,"tag":127,"props":3403,"children":3404},{"style":688},[3405],{"type":56,"value":2009},{"type":29,"tag":127,"props":3407,"children":3408},{"class":677,"line":666},[3409,3414],{"type":29,"tag":127,"props":3410,"children":3411},{"style":1991},[3412],{"type":56,"value":3413},"    \"require\"",{"type":29,"tag":127,"props":3415,"children":3416},{"style":688},[3417],{"type":56,"value":2064},{"type":29,"tag":127,"props":3419,"children":3420},{"class":677,"line":667},[3421,3426,3430],{"type":29,"tag":127,"props":3422,"children":3423},{"style":1991},[3424],{"type":56,"value":3425},"        \"shopware/core\"",{"type":29,"tag":127,"props":3427,"children":3428},{"style":688},[3429],{"type":56,"value":717},{"type":29,"tag":127,"props":3431,"children":3432},{"style":2001},[3433],{"type":56,"value":3434},"\"~6.6.0\"\n",{"type":29,"tag":127,"props":3436,"children":3437},{"class":677,"line":668},[3438],{"type":29,"tag":127,"props":3439,"children":3440},{"style":688},[3441],{"type":56,"value":2322},{"type":29,"tag":127,"props":3443,"children":3444},{"class":677,"line":1329},[3445,3450],{"type":29,"tag":127,"props":3446,"children":3447},{"style":1991},[3448],{"type":56,"value":3449},"    \"extra\"",{"type":29,"tag":127,"props":3451,"children":3452},{"style":688},[3453],{"type":56,"value":2064},{"type":29,"tag":127,"props":3455,"children":3456},{"class":677,"line":1342},[3457,3462,3466,3471,3475,3480],{"type":29,"tag":127,"props":3458,"children":3459},{"style":1991},[3460],{"type":56,"value":3461},"        \"shopware-plugin-class\"",{"type":29,"tag":127,"props":3463,"children":3464},{"style":688},[3465],{"type":56,"value":717},{"type":29,"tag":127,"props":3467,"children":3468},{"style":2001},[3469],{"type":56,"value":3470},"\"Acme",{"type":29,"tag":127,"props":3472,"children":3473},{"style":2303},[3474],{"type":56,"value":2606},{"type":29,"tag":127,"props":3476,"children":3477},{"style":2001},[3478],{"type":56,"value":3479},"SamplePlugin\"",{"type":29,"tag":127,"props":3481,"children":3482},{"style":688},[3483],{"type":56,"value":2009},{"type":29,"tag":127,"props":3485,"children":3486},{"class":677,"line":118},[3487,3492],{"type":29,"tag":127,"props":3488,"children":3489},{"style":1991},[3490],{"type":56,"value":3491},"        \"label\"",{"type":29,"tag":127,"props":3493,"children":3494},{"style":688},[3495],{"type":56,"value":2064},{"type":29,"tag":127,"props":3497,"children":3498},{"class":677,"line":1367},[3499,3504,3508,3513],{"type":29,"tag":127,"props":3500,"children":3501},{"style":1991},[3502],{"type":56,"value":3503},"            \"de-DE\"",{"type":29,"tag":127,"props":3505,"children":3506},{"style":688},[3507],{"type":56,"value":717},{"type":29,"tag":127,"props":3509,"children":3510},{"style":2001},[3511],{"type":56,"value":3512},"\"Skeleton plugin\"",{"type":29,"tag":127,"props":3514,"children":3515},{"style":688},[3516],{"type":56,"value":2009},{"type":29,"tag":127,"props":3518,"children":3519},{"class":677,"line":1380},[3520,3525,3529],{"type":29,"tag":127,"props":3521,"children":3522},{"style":1991},[3523],{"type":56,"value":3524},"            \"en-GB\"",{"type":29,"tag":127,"props":3526,"children":3527},{"style":688},[3528],{"type":56,"value":717},{"type":29,"tag":127,"props":3530,"children":3531},{"style":2001},[3532],{"type":56,"value":3533},"\"Skeleton plugin\"\n",{"type":29,"tag":127,"props":3535,"children":3536},{"class":677,"line":1393},[3537],{"type":29,"tag":127,"props":3538,"children":3539},{"style":688},[3540],{"type":56,"value":3541},"        }\n",{"type":29,"tag":127,"props":3543,"children":3544},{"class":677,"line":1402},[3545],{"type":29,"tag":127,"props":3546,"children":3547},{"style":688},[3548],{"type":56,"value":2322},{"type":29,"tag":127,"props":3550,"children":3551},{"class":677,"line":1415},[3552,3557],{"type":29,"tag":127,"props":3553,"children":3554},{"style":1991},[3555],{"type":56,"value":3556},"    \"autoload\"",{"type":29,"tag":127,"props":3558,"children":3559},{"style":688},[3560],{"type":56,"value":2064},{"type":29,"tag":127,"props":3562,"children":3563},{"class":677,"line":1428},[3564,3569],{"type":29,"tag":127,"props":3565,"children":3566},{"style":1991},[3567],{"type":56,"value":3568},"        \"psr-4\"",{"type":29,"tag":127,"props":3570,"children":3571},{"style":688},[3572],{"type":56,"value":2064},{"type":29,"tag":127,"props":3574,"children":3575},{"class":677,"line":1437},[3576,3581,3585,3589,3593],{"type":29,"tag":127,"props":3577,"children":3578},{"style":1991},[3579],{"type":56,"value":3580},"            \"Acme",{"type":29,"tag":127,"props":3582,"children":3583},{"style":2603},[3584],{"type":56,"value":2606},{"type":29,"tag":127,"props":3586,"children":3587},{"style":1991},[3588],{"type":56,"value":2611},{"type":29,"tag":127,"props":3590,"children":3591},{"style":688},[3592],{"type":56,"value":717},{"type":29,"tag":127,"props":3594,"children":3595},{"style":2001},[3596],{"type":56,"value":2620},{"type":29,"tag":127,"props":3598,"children":3599},{"class":677,"line":1450},[3600],{"type":29,"tag":127,"props":3601,"children":3602},{"style":688},[3603],{"type":56,"value":3541},{"type":29,"tag":127,"props":3605,"children":3606},{"class":677,"line":1463},[3607],{"type":29,"tag":127,"props":3608,"children":3609},{"style":688},[3610],{"type":56,"value":2322},{"type":29,"tag":127,"props":3612,"children":3613},{"class":677,"line":1476},[3614,3619],{"type":29,"tag":127,"props":3615,"children":3616},{"style":1991},[3617],{"type":56,"value":3618},"    \"autoload-dev\"",{"type":29,"tag":127,"props":3620,"children":3621},{"style":688},[3622],{"type":56,"value":2064},{"type":29,"tag":127,"props":3624,"children":3625},{"class":677,"line":1484},[3626,3630],{"type":29,"tag":127,"props":3627,"children":3628},{"style":1991},[3629],{"type":56,"value":3568},{"type":29,"tag":127,"props":3631,"children":3632},{"style":688},[3633],{"type":56,"value":2064},{"type":29,"tag":127,"props":3635,"children":3636},{"class":677,"line":1497},[3637,3641,3645,3650,3654,3658,3662],{"type":29,"tag":127,"props":3638,"children":3639},{"style":1991},[3640],{"type":56,"value":3580},{"type":29,"tag":127,"props":3642,"children":3643},{"style":2603},[3644],{"type":56,"value":2606},{"type":29,"tag":127,"props":3646,"children":3647},{"style":1991},[3648],{"type":56,"value":3649},"Tests",{"type":29,"tag":127,"props":3651,"children":3652},{"style":2603},[3653],{"type":56,"value":2606},{"type":29,"tag":127,"props":3655,"children":3656},{"style":1991},[3657],{"type":56,"value":2611},{"type":29,"tag":127,"props":3659,"children":3660},{"style":688},[3661],{"type":56,"value":717},{"type":29,"tag":127,"props":3663,"children":3664},{"style":2001},[3665],{"type":56,"value":3666},"\"tests/\"\n",{"type":29,"tag":127,"props":3668,"children":3669},{"class":677,"line":1510},[3670],{"type":29,"tag":127,"props":3671,"children":3672},{"style":688},[3673],{"type":56,"value":3541},{"type":29,"tag":127,"props":3675,"children":3676},{"class":677,"line":1523},[3677],{"type":29,"tag":127,"props":3678,"children":3679},{"style":688},[3680],{"type":56,"value":2556},{"type":29,"tag":127,"props":3682,"children":3683},{"class":677,"line":1536},[3684],{"type":29,"tag":127,"props":3685,"children":3686},{"style":688},[3687],{"type":56,"value":3013},{"type":29,"tag":659,"props":3689,"children":3691},{"className":3021,"code":3690,"language":3023,"meta":7,"style":7},"git tag v1.0.0\ngit push --tags\n",[3692],{"type":29,"tag":672,"props":3693,"children":3694},{"__ignoreMap":7},[3695,3712],{"type":29,"tag":127,"props":3696,"children":3697},{"class":677,"line":678},[3698,3702,3707],{"type":29,"tag":127,"props":3699,"children":3700},{"style":3033},[3701],{"type":56,"value":907},{"type":29,"tag":127,"props":3703,"children":3704},{"style":720},[3705],{"type":56,"value":3706}," tag",{"type":29,"tag":127,"props":3708,"children":3709},{"style":720},[3710],{"type":56,"value":3711}," v1.0.0\n",{"type":29,"tag":127,"props":3713,"children":3714},{"class":677,"line":342},[3715,3719,3724],{"type":29,"tag":127,"props":3716,"children":3717},{"style":3033},[3718],{"type":56,"value":907},{"type":29,"tag":127,"props":3720,"children":3721},{"style":720},[3722],{"type":56,"value":3723}," push",{"type":29,"tag":127,"props":3725,"children":3726},{"style":2303},[3727],{"type":56,"value":3728}," --tags\n",{"type":29,"tag":48,"props":3730,"children":3731},{},[3732],{"type":56,"value":3733},"Nun wird dies funktionieren:",{"type":29,"tag":659,"props":3735,"children":3736},{"className":3021,"code":3022,"language":3023,"meta":7,"style":7},[3737],{"type":29,"tag":672,"props":3738,"children":3739},{"__ignoreMap":7},[3740],{"type":29,"tag":127,"props":3741,"children":3742},{"class":677,"line":678},[3743,3747,3751],{"type":29,"tag":127,"props":3744,"children":3745},{"style":3033},[3746],{"type":56,"value":1961},{"type":29,"tag":127,"props":3748,"children":3749},{"style":720},[3750],{"type":56,"value":3040},{"type":29,"tag":127,"props":3752,"children":3753},{"style":720},[3754],{"type":56,"value":3045},{"type":29,"tag":659,"props":3756,"children":3760},{"className":3757,"code":3758,"language":3759,"meta":7,"style":7},"language-terminaloutput shiki shiki-themes github-dark github-dark monokai","./composer.json has been updated                                                                                                            \nRunning composer update acme/sample-plugin\nLoading composer repositories with package information\nUpdating dependencies\nLock file operations: 1 install, 0 updates, 0 removals\n  - Locking acme/sample-plugin (1.0.0)\nWriting lock file\nInstalling dependencies from lock file (including require-dev)\nPackage operations: 1 install, 0 updates, 0 removals\n  - Syncing acme/sample-plugin (1.0.0) into cache\n  - Installing acme/sample-plugin (1.0.0): Cloning 294414deb2 from cache\nGenerating optimized autoload files\n\nRun composer recipes at any time to see the status of your Symfony recipes.\n\nExecuting script assets:install [OK]\n\nUsing version ^1.0 for acme/sample-plugin\n","terminaloutput",[3761],{"type":29,"tag":672,"props":3762,"children":3763},{"__ignoreMap":7},[3764,3772,3779,3787,3795,3802,3810,3817,3824,3831,3839,3847,3854,3861,3868,3875,3882,3889],{"type":29,"tag":127,"props":3765,"children":3766},{"class":677,"line":678},[3767],{"type":29,"tag":127,"props":3768,"children":3769},{},[3770],{"type":56,"value":3771},"./composer.json has been updated                                                                                                            \n",{"type":29,"tag":127,"props":3773,"children":3774},{"class":677,"line":342},[3775],{"type":29,"tag":127,"props":3776,"children":3777},{},[3778],{"type":56,"value":3119},{"type":29,"tag":127,"props":3780,"children":3781},{"class":677,"line":706},[3782],{"type":29,"tag":127,"props":3783,"children":3784},{},[3785],{"type":56,"value":3786},"Loading composer repositories with package information\n",{"type":29,"tag":127,"props":3788,"children":3789},{"class":677,"line":726},[3790],{"type":29,"tag":127,"props":3791,"children":3792},{},[3793],{"type":56,"value":3794},"Updating dependencies\n",{"type":29,"tag":127,"props":3796,"children":3797},{"class":677,"line":664},[3798],{"type":29,"tag":127,"props":3799,"children":3800},{},[3801],{"type":56,"value":3143},{"type":29,"tag":127,"props":3803,"children":3804},{"class":677,"line":665},[3805],{"type":29,"tag":127,"props":3806,"children":3807},{},[3808],{"type":56,"value":3809},"  - Locking acme/sample-plugin (1.0.0)\n",{"type":29,"tag":127,"props":3811,"children":3812},{"class":677,"line":666},[3813],{"type":29,"tag":127,"props":3814,"children":3815},{},[3816],{"type":56,"value":3159},{"type":29,"tag":127,"props":3818,"children":3819},{"class":677,"line":667},[3820],{"type":29,"tag":127,"props":3821,"children":3822},{},[3823],{"type":56,"value":3167},{"type":29,"tag":127,"props":3825,"children":3826},{"class":677,"line":668},[3827],{"type":29,"tag":127,"props":3828,"children":3829},{},[3830],{"type":56,"value":3175},{"type":29,"tag":127,"props":3832,"children":3833},{"class":677,"line":1329},[3834],{"type":29,"tag":127,"props":3835,"children":3836},{},[3837],{"type":56,"value":3838},"  - Syncing acme/sample-plugin (1.0.0) into cache\n",{"type":29,"tag":127,"props":3840,"children":3841},{"class":677,"line":1342},[3842],{"type":29,"tag":127,"props":3843,"children":3844},{},[3845],{"type":56,"value":3846},"  - Installing acme/sample-plugin (1.0.0): Cloning 294414deb2 from cache\n",{"type":29,"tag":127,"props":3848,"children":3849},{"class":677,"line":118},[3850],{"type":29,"tag":127,"props":3851,"children":3852},{},[3853],{"type":56,"value":3199},{"type":29,"tag":127,"props":3855,"children":3856},{"class":677,"line":1367},[3857],{"type":29,"tag":127,"props":3858,"children":3859},{"emptyLinePlaceholder":500},[3860],{"type":56,"value":1399},{"type":29,"tag":127,"props":3862,"children":3863},{"class":677,"line":1380},[3864],{"type":29,"tag":127,"props":3865,"children":3866},{},[3867],{"type":56,"value":3214},{"type":29,"tag":127,"props":3869,"children":3870},{"class":677,"line":1393},[3871],{"type":29,"tag":127,"props":3872,"children":3873},{"emptyLinePlaceholder":500},[3874],{"type":56,"value":1399},{"type":29,"tag":127,"props":3876,"children":3877},{"class":677,"line":1402},[3878],{"type":29,"tag":127,"props":3879,"children":3880},{},[3881],{"type":56,"value":3229},{"type":29,"tag":127,"props":3883,"children":3884},{"class":677,"line":1415},[3885],{"type":29,"tag":127,"props":3886,"children":3887},{"emptyLinePlaceholder":500},[3888],{"type":56,"value":1399},{"type":29,"tag":127,"props":3890,"children":3891},{"class":677,"line":1428},[3892],{"type":29,"tag":127,"props":3893,"children":3894},{},[3895],{"type":56,"value":3896},"Using version ^1.0 for acme/sample-plugin\n",{"type":29,"tag":48,"props":3898,"children":3899},{},[3900,3902,3907],{"type":56,"value":3901},"Das ist besser, aber wir verwenden immer noch ",{"type":29,"tag":672,"props":3903,"children":3905},{"className":3904},[],[3906],{"type":56,"value":907},{"type":56,"value":3908},", um das Plugin abzurufen. Wir können es noch besser machen.",{"type":29,"tag":122,"props":3910,"children":3912},{"id":3911},"gitlab-package-registry",[3913],{"type":56,"value":3914},"GitLab Package Registry",{"type":29,"tag":48,"props":3916,"children":3917},{},[3918,3920,3925],{"type":56,"value":3919},"Hier beginnt der GitLab-Teil. Weitere Details sind in der ",{"type":29,"tag":645,"props":3921,"children":3923},{"href":3922},"https://docs.gitlab.com/18.3/user/packages/composer_repository/",[3924],{"type":56,"value":1881},{"type":56,"value":3926}," zu finden.",{"type":29,"tag":48,"props":3928,"children":3929},{},[3930],{"type":56,"value":3931},"An dieser Stelle spielt es keine Rolle, ob unser Projekt öffentlich ist oder nicht, da wir uns ohnehin gegenüber der Package Registry authentifizieren müssen.",{"type":29,"tag":48,"props":3933,"children":3934},{},[3935,3937,3942],{"type":56,"value":3936},"Wir veröffentlichen unseren ",{"type":29,"tag":672,"props":3938,"children":3940},{"className":3939},[],[3941],{"type":56,"value":3263},{"type":56,"value":3943},"-Tag als Composer-Paket.",{"type":29,"tag":659,"props":3945,"children":3947},{"className":3021,"code":3946,"language":3023,"meta":7,"style":7},"curl --fail-with-body --data tag=v1.0.0 \"https://__token__:\u003Cpersonal-access-token>@\u003CDOMAIN-NAME>/api/v4/projects/\u003Cproject_id>/packages/composer\"\n",[3948],{"type":29,"tag":672,"props":3949,"children":3950},{"__ignoreMap":7},[3951],{"type":29,"tag":127,"props":3952,"children":3953},{"class":677,"line":678},[3954,3959,3964,3969,3974],{"type":29,"tag":127,"props":3955,"children":3956},{"style":3033},[3957],{"type":56,"value":3958},"curl",{"type":29,"tag":127,"props":3960,"children":3961},{"style":2303},[3962],{"type":56,"value":3963}," --fail-with-body",{"type":29,"tag":127,"props":3965,"children":3966},{"style":2303},[3967],{"type":56,"value":3968}," --data",{"type":29,"tag":127,"props":3970,"children":3971},{"style":720},[3972],{"type":56,"value":3973}," tag=v1.0.0",{"type":29,"tag":127,"props":3975,"children":3976},{"style":720},[3977],{"type":56,"value":3978}," \"https://__token__:\u003Cpersonal-access-token>@\u003CDOMAIN-NAME>/api/v4/projects/\u003Cproject_id>/packages/composer\"\n",{"type":29,"tag":48,"props":3980,"children":3981},{},[3982],{"type":56,"value":3983},"Nun müssen wir die Repository-Informationen aktualisieren:",{"type":29,"tag":659,"props":3985,"children":3988},{"className":1966,"code":3986,"filename":1968,"highlights":3987,"language":454,"meta":7,"style":7},"{\n  \"name\": \"shopware/production\",\n  \"license\": \"MIT\",\n  \"type\": \"project\",\n  \"require\": {\n    \"composer-runtime-api\": \"^2.0\",\n    \"acme/sample-plugin\": \"^1.0\",\n    \"shopware/administration\": \"*\",\n    \"shopware/core\": \"6.6.10.2\",\n    \"shopware/elasticsearch\": \"*\",\n    \"shopware/storefront\": \"*\",\n    \"symfony/flex\": \"~2\"\n  },\n  \"repositories\": [\n    {\n      \"type\": \"path\",\n      \"url\": \"custom/plugins/*\",\n      \"options\": {\n        \"symlink\": true\n      }\n    },\n    {\n      \"type\": \"path\",\n      \"url\": \"custom/plugins/*/packages/*\",\n      \"options\": {\n        \"symlink\": true\n      }\n    },\n    {\n      \"type\": \"path\",\n      \"url\": \"custom/static-plugins/*\",\n      \"options\": {\n        \"symlink\": true\n      }\n    },\n    {\n      \"type\": \"composer\",\n      \"url\": \"https://\u003CDOMAIN-NAME>/api/v4/api/v4/group/\u003Cgroup_id>/-/packages/composer/packages.json\"\n    }\n  ],\n  \"autoload\": {\n    \"psr-4\": {\n      \"App\\\\\": \"src/\"\n    }\n  },\n  \"prefer-stable\": true,\n  \"config\": {\n    \"allow-plugins\": {\n      \"symfony/flex\": true,\n      \"symfony/runtime\": true\n    },\n    \"optimize-autoloader\": true,\n    \"sort-packages\": true\n  },\n  \"scripts\": {\n    \"auto-scripts\": {\n      \"assets:install\": \"symfony-cmd\"\n    },\n    \"post-install-cmd\": [\n      \"@auto-scripts\"\n    ],\n    \"post-update-cmd\": [\n      \"@auto-scripts\"\n    ]\n  },\n  \"extra\": {\n    \"symfony\": {\n      \"allow-contrib\": true,\n      \"endpoint\": [\n        \"https://raw.githubusercontent.com/shopware/recipes/flex/main/index.json\",\n        \"flex://defaults\"\n      ]\n    }\n  }\n}\n",[1970,1971,1972,1973],[3989],{"type":29,"tag":672,"props":3990,"children":3991},{"__ignoreMap":7},[3992,3999,4018,4037,4056,4067,4086,4105,4124,4143,4162,4181,4196,4203,4214,4221,4240,4259,4270,4285,4292,4299,4306,4325,4344,4355,4370,4377,4384,4391,4410,4429,4440,4455,4462,4469,4477,4498,4515,4523,4530,4541,4552,4575,4582,4589,4608,4619,4630,4649,4664,4671,4690,4705,4712,4723,4734,4749,4756,4767,4774,4781,4792,4799,4806,4813,4824,4835,4854,4865,4876,4883,4890,4897,4904],{"type":29,"tag":127,"props":3993,"children":3994},{"class":677,"line":678},[3995],{"type":29,"tag":127,"props":3996,"children":3997},{"style":688},[3998],{"type":56,"value":1985},{"type":29,"tag":127,"props":4000,"children":4001},{"class":677,"line":342},[4002,4006,4010,4014],{"type":29,"tag":127,"props":4003,"children":4004},{"style":1991},[4005],{"type":56,"value":1994},{"type":29,"tag":127,"props":4007,"children":4008},{"style":688},[4009],{"type":56,"value":717},{"type":29,"tag":127,"props":4011,"children":4012},{"style":2001},[4013],{"type":56,"value":2004},{"type":29,"tag":127,"props":4015,"children":4016},{"style":688},[4017],{"type":56,"value":2009},{"type":29,"tag":127,"props":4019,"children":4020},{"class":677,"line":706},[4021,4025,4029,4033],{"type":29,"tag":127,"props":4022,"children":4023},{"style":1991},[4024],{"type":56,"value":2017},{"type":29,"tag":127,"props":4026,"children":4027},{"style":688},[4028],{"type":56,"value":717},{"type":29,"tag":127,"props":4030,"children":4031},{"style":2001},[4032],{"type":56,"value":2026},{"type":29,"tag":127,"props":4034,"children":4035},{"style":688},[4036],{"type":56,"value":2009},{"type":29,"tag":127,"props":4038,"children":4039},{"class":677,"line":726},[4040,4044,4048,4052],{"type":29,"tag":127,"props":4041,"children":4042},{"style":1991},[4043],{"type":56,"value":2038},{"type":29,"tag":127,"props":4045,"children":4046},{"style":688},[4047],{"type":56,"value":717},{"type":29,"tag":127,"props":4049,"children":4050},{"style":2001},[4051],{"type":56,"value":2047},{"type":29,"tag":127,"props":4053,"children":4054},{"style":688},[4055],{"type":56,"value":2009},{"type":29,"tag":127,"props":4057,"children":4058},{"class":677,"line":664},[4059,4063],{"type":29,"tag":127,"props":4060,"children":4061},{"style":1991},[4062],{"type":56,"value":2059},{"type":29,"tag":127,"props":4064,"children":4065},{"style":688},[4066],{"type":56,"value":2064},{"type":29,"tag":127,"props":4068,"children":4069},{"class":677,"line":665},[4070,4074,4078,4082],{"type":29,"tag":127,"props":4071,"children":4072},{"style":1991},[4073],{"type":56,"value":2072},{"type":29,"tag":127,"props":4075,"children":4076},{"style":688},[4077],{"type":56,"value":717},{"type":29,"tag":127,"props":4079,"children":4080},{"style":2001},[4081],{"type":56,"value":2081},{"type":29,"tag":127,"props":4083,"children":4084},{"style":688},[4085],{"type":56,"value":2009},{"type":29,"tag":127,"props":4087,"children":4088},{"class":677,"line":666},[4089,4093,4097,4101],{"type":29,"tag":127,"props":4090,"children":4091},{"style":1991},[4092],{"type":56,"value":2093},{"type":29,"tag":127,"props":4094,"children":4095},{"style":688},[4096],{"type":56,"value":717},{"type":29,"tag":127,"props":4098,"children":4099},{"style":2001},[4100],{"type":56,"value":2102},{"type":29,"tag":127,"props":4102,"children":4103},{"style":688},[4104],{"type":56,"value":2009},{"type":29,"tag":127,"props":4106,"children":4107},{"class":677,"line":667},[4108,4112,4116,4120],{"type":29,"tag":127,"props":4109,"children":4110},{"style":1991},[4111],{"type":56,"value":2114},{"type":29,"tag":127,"props":4113,"children":4114},{"style":688},[4115],{"type":56,"value":717},{"type":29,"tag":127,"props":4117,"children":4118},{"style":2001},[4119],{"type":56,"value":2123},{"type":29,"tag":127,"props":4121,"children":4122},{"style":688},[4123],{"type":56,"value":2009},{"type":29,"tag":127,"props":4125,"children":4126},{"class":677,"line":668},[4127,4131,4135,4139],{"type":29,"tag":127,"props":4128,"children":4129},{"style":1991},[4130],{"type":56,"value":2135},{"type":29,"tag":127,"props":4132,"children":4133},{"style":688},[4134],{"type":56,"value":717},{"type":29,"tag":127,"props":4136,"children":4137},{"style":2001},[4138],{"type":56,"value":2144},{"type":29,"tag":127,"props":4140,"children":4141},{"style":688},[4142],{"type":56,"value":2009},{"type":29,"tag":127,"props":4144,"children":4145},{"class":677,"line":1329},[4146,4150,4154,4158],{"type":29,"tag":127,"props":4147,"children":4148},{"style":1991},[4149],{"type":56,"value":2156},{"type":29,"tag":127,"props":4151,"children":4152},{"style":688},[4153],{"type":56,"value":717},{"type":29,"tag":127,"props":4155,"children":4156},{"style":2001},[4157],{"type":56,"value":2123},{"type":29,"tag":127,"props":4159,"children":4160},{"style":688},[4161],{"type":56,"value":2009},{"type":29,"tag":127,"props":4163,"children":4164},{"class":677,"line":1342},[4165,4169,4173,4177],{"type":29,"tag":127,"props":4166,"children":4167},{"style":1991},[4168],{"type":56,"value":2176},{"type":29,"tag":127,"props":4170,"children":4171},{"style":688},[4172],{"type":56,"value":717},{"type":29,"tag":127,"props":4174,"children":4175},{"style":2001},[4176],{"type":56,"value":2123},{"type":29,"tag":127,"props":4178,"children":4179},{"style":688},[4180],{"type":56,"value":2009},{"type":29,"tag":127,"props":4182,"children":4183},{"class":677,"line":118},[4184,4188,4192],{"type":29,"tag":127,"props":4185,"children":4186},{"style":1991},[4187],{"type":56,"value":2196},{"type":29,"tag":127,"props":4189,"children":4190},{"style":688},[4191],{"type":56,"value":717},{"type":29,"tag":127,"props":4193,"children":4194},{"style":2001},[4195],{"type":56,"value":2205},{"type":29,"tag":127,"props":4197,"children":4198},{"class":677,"line":1367},[4199],{"type":29,"tag":127,"props":4200,"children":4201},{"style":688},[4202],{"type":56,"value":2213},{"type":29,"tag":127,"props":4204,"children":4205},{"class":677,"line":1380},[4206,4210],{"type":29,"tag":127,"props":4207,"children":4208},{"style":1991},[4209],{"type":56,"value":2221},{"type":29,"tag":127,"props":4211,"children":4212},{"style":688},[4213],{"type":56,"value":2226},{"type":29,"tag":127,"props":4215,"children":4216},{"class":677,"line":1393},[4217],{"type":29,"tag":127,"props":4218,"children":4219},{"style":688},[4220],{"type":56,"value":2234},{"type":29,"tag":127,"props":4222,"children":4223},{"class":677,"line":1402},[4224,4228,4232,4236],{"type":29,"tag":127,"props":4225,"children":4226},{"style":1991},[4227],{"type":56,"value":2242},{"type":29,"tag":127,"props":4229,"children":4230},{"style":688},[4231],{"type":56,"value":717},{"type":29,"tag":127,"props":4233,"children":4234},{"style":2001},[4235],{"type":56,"value":2251},{"type":29,"tag":127,"props":4237,"children":4238},{"style":688},[4239],{"type":56,"value":2009},{"type":29,"tag":127,"props":4241,"children":4242},{"class":677,"line":1415},[4243,4247,4251,4255],{"type":29,"tag":127,"props":4244,"children":4245},{"style":1991},[4246],{"type":56,"value":2263},{"type":29,"tag":127,"props":4248,"children":4249},{"style":688},[4250],{"type":56,"value":717},{"type":29,"tag":127,"props":4252,"children":4253},{"style":2001},[4254],{"type":56,"value":2272},{"type":29,"tag":127,"props":4256,"children":4257},{"style":688},[4258],{"type":56,"value":2009},{"type":29,"tag":127,"props":4260,"children":4261},{"class":677,"line":1428},[4262,4266],{"type":29,"tag":127,"props":4263,"children":4264},{"style":1991},[4265],{"type":56,"value":2284},{"type":29,"tag":127,"props":4267,"children":4268},{"style":688},[4269],{"type":56,"value":2064},{"type":29,"tag":127,"props":4271,"children":4272},{"class":677,"line":1437},[4273,4277,4281],{"type":29,"tag":127,"props":4274,"children":4275},{"style":1991},[4276],{"type":56,"value":2296},{"type":29,"tag":127,"props":4278,"children":4279},{"style":688},[4280],{"type":56,"value":717},{"type":29,"tag":127,"props":4282,"children":4283},{"style":2303},[4284],{"type":56,"value":2306},{"type":29,"tag":127,"props":4286,"children":4287},{"class":677,"line":1450},[4288],{"type":29,"tag":127,"props":4289,"children":4290},{"style":688},[4291],{"type":56,"value":2314},{"type":29,"tag":127,"props":4293,"children":4294},{"class":677,"line":1463},[4295],{"type":29,"tag":127,"props":4296,"children":4297},{"style":688},[4298],{"type":56,"value":2322},{"type":29,"tag":127,"props":4300,"children":4301},{"class":677,"line":1476},[4302],{"type":29,"tag":127,"props":4303,"children":4304},{"style":688},[4305],{"type":56,"value":2234},{"type":29,"tag":127,"props":4307,"children":4308},{"class":677,"line":1484},[4309,4313,4317,4321],{"type":29,"tag":127,"props":4310,"children":4311},{"style":1991},[4312],{"type":56,"value":2242},{"type":29,"tag":127,"props":4314,"children":4315},{"style":688},[4316],{"type":56,"value":717},{"type":29,"tag":127,"props":4318,"children":4319},{"style":2001},[4320],{"type":56,"value":2251},{"type":29,"tag":127,"props":4322,"children":4323},{"style":688},[4324],{"type":56,"value":2009},{"type":29,"tag":127,"props":4326,"children":4327},{"class":677,"line":1497},[4328,4332,4336,4340],{"type":29,"tag":127,"props":4329,"children":4330},{"style":1991},[4331],{"type":56,"value":2263},{"type":29,"tag":127,"props":4333,"children":4334},{"style":688},[4335],{"type":56,"value":717},{"type":29,"tag":127,"props":4337,"children":4338},{"style":2001},[4339],{"type":56,"value":2364},{"type":29,"tag":127,"props":4341,"children":4342},{"style":688},[4343],{"type":56,"value":2009},{"type":29,"tag":127,"props":4345,"children":4346},{"class":677,"line":1510},[4347,4351],{"type":29,"tag":127,"props":4348,"children":4349},{"style":1991},[4350],{"type":56,"value":2284},{"type":29,"tag":127,"props":4352,"children":4353},{"style":688},[4354],{"type":56,"value":2064},{"type":29,"tag":127,"props":4356,"children":4357},{"class":677,"line":1523},[4358,4362,4366],{"type":29,"tag":127,"props":4359,"children":4360},{"style":1991},[4361],{"type":56,"value":2296},{"type":29,"tag":127,"props":4363,"children":4364},{"style":688},[4365],{"type":56,"value":717},{"type":29,"tag":127,"props":4367,"children":4368},{"style":2303},[4369],{"type":56,"value":2306},{"type":29,"tag":127,"props":4371,"children":4372},{"class":677,"line":1536},[4373],{"type":29,"tag":127,"props":4374,"children":4375},{"style":688},[4376],{"type":56,"value":2314},{"type":29,"tag":127,"props":4378,"children":4379},{"class":677,"line":1549},[4380],{"type":29,"tag":127,"props":4381,"children":4382},{"style":688},[4383],{"type":56,"value":2322},{"type":29,"tag":127,"props":4385,"children":4386},{"class":677,"line":2411},[4387],{"type":29,"tag":127,"props":4388,"children":4389},{"style":688},[4390],{"type":56,"value":2234},{"type":29,"tag":127,"props":4392,"children":4393},{"class":677,"line":2419},[4394,4398,4402,4406],{"type":29,"tag":127,"props":4395,"children":4396},{"style":1991},[4397],{"type":56,"value":2242},{"type":29,"tag":127,"props":4399,"children":4400},{"style":688},[4401],{"type":56,"value":717},{"type":29,"tag":127,"props":4403,"children":4404},{"style":2001},[4405],{"type":56,"value":2251},{"type":29,"tag":127,"props":4407,"children":4408},{"style":688},[4409],{"type":56,"value":2009},{"type":29,"tag":127,"props":4411,"children":4412},{"class":677,"line":2439},[4413,4417,4421,4425],{"type":29,"tag":127,"props":4414,"children":4415},{"style":1991},[4416],{"type":56,"value":2263},{"type":29,"tag":127,"props":4418,"children":4419},{"style":688},[4420],{"type":56,"value":717},{"type":29,"tag":127,"props":4422,"children":4423},{"style":2001},[4424],{"type":56,"value":2453},{"type":29,"tag":127,"props":4426,"children":4427},{"style":688},[4428],{"type":56,"value":2009},{"type":29,"tag":127,"props":4430,"children":4431},{"class":677,"line":2460},[4432,4436],{"type":29,"tag":127,"props":4433,"children":4434},{"style":1991},[4435],{"type":56,"value":2284},{"type":29,"tag":127,"props":4437,"children":4438},{"style":688},[4439],{"type":56,"value":2064},{"type":29,"tag":127,"props":4441,"children":4442},{"class":677,"line":2472},[4443,4447,4451],{"type":29,"tag":127,"props":4444,"children":4445},{"style":1991},[4446],{"type":56,"value":2296},{"type":29,"tag":127,"props":4448,"children":4449},{"style":688},[4450],{"type":56,"value":717},{"type":29,"tag":127,"props":4452,"children":4453},{"style":2303},[4454],{"type":56,"value":2306},{"type":29,"tag":127,"props":4456,"children":4457},{"class":677,"line":2488},[4458],{"type":29,"tag":127,"props":4459,"children":4460},{"style":688},[4461],{"type":56,"value":2314},{"type":29,"tag":127,"props":4463,"children":4464},{"class":677,"line":2496},[4465],{"type":29,"tag":127,"props":4466,"children":4467},{"style":688},[4468],{"type":56,"value":2322},{"type":29,"tag":127,"props":4470,"children":4472},{"class":4471,"line":1970},[677,740],[4473],{"type":29,"tag":127,"props":4474,"children":4475},{"style":688},[4476],{"type":56,"value":2234},{"type":29,"tag":127,"props":4478,"children":4480},{"class":4479,"line":1971},[677,740],[4481,4485,4489,4494],{"type":29,"tag":127,"props":4482,"children":4483},{"style":1991},[4484],{"type":56,"value":2242},{"type":29,"tag":127,"props":4486,"children":4487},{"style":688},[4488],{"type":56,"value":717},{"type":29,"tag":127,"props":4490,"children":4491},{"style":2001},[4492],{"type":56,"value":4493},"\"composer\"",{"type":29,"tag":127,"props":4495,"children":4496},{"style":688},[4497],{"type":56,"value":2009},{"type":29,"tag":127,"props":4499,"children":4501},{"class":4500,"line":1972},[677,740],[4502,4506,4510],{"type":29,"tag":127,"props":4503,"children":4504},{"style":1991},[4505],{"type":56,"value":2263},{"type":29,"tag":127,"props":4507,"children":4508},{"style":688},[4509],{"type":56,"value":717},{"type":29,"tag":127,"props":4511,"children":4512},{"style":2001},[4513],{"type":56,"value":4514},"\"https://\u003CDOMAIN-NAME>/api/v4/api/v4/group/\u003Cgroup_id>/-/packages/composer/packages.json\"\n",{"type":29,"tag":127,"props":4516,"children":4518},{"class":4517,"line":1973},[677,740],[4519],{"type":29,"tag":127,"props":4520,"children":4521},{"style":688},[4522],{"type":56,"value":2556},{"type":29,"tag":127,"props":4524,"children":4525},{"class":677,"line":2559},[4526],{"type":29,"tag":127,"props":4527,"children":4528},{"style":688},[4529],{"type":56,"value":2565},{"type":29,"tag":127,"props":4531,"children":4532},{"class":677,"line":2568},[4533,4537],{"type":29,"tag":127,"props":4534,"children":4535},{"style":1991},[4536],{"type":56,"value":2574},{"type":29,"tag":127,"props":4538,"children":4539},{"style":688},[4540],{"type":56,"value":2064},{"type":29,"tag":127,"props":4542,"children":4543},{"class":677,"line":2581},[4544,4548],{"type":29,"tag":127,"props":4545,"children":4546},{"style":1991},[4547],{"type":56,"value":2587},{"type":29,"tag":127,"props":4549,"children":4550},{"style":688},[4551],{"type":56,"value":2064},{"type":29,"tag":127,"props":4553,"children":4554},{"class":677,"line":2594},[4555,4559,4563,4567,4571],{"type":29,"tag":127,"props":4556,"children":4557},{"style":1991},[4558],{"type":56,"value":2600},{"type":29,"tag":127,"props":4560,"children":4561},{"style":2603},[4562],{"type":56,"value":2606},{"type":29,"tag":127,"props":4564,"children":4565},{"style":1991},[4566],{"type":56,"value":2611},{"type":29,"tag":127,"props":4568,"children":4569},{"style":688},[4570],{"type":56,"value":717},{"type":29,"tag":127,"props":4572,"children":4573},{"style":2001},[4574],{"type":56,"value":2620},{"type":29,"tag":127,"props":4576,"children":4577},{"class":677,"line":2623},[4578],{"type":29,"tag":127,"props":4579,"children":4580},{"style":688},[4581],{"type":56,"value":2556},{"type":29,"tag":127,"props":4583,"children":4584},{"class":677,"line":2631},[4585],{"type":29,"tag":127,"props":4586,"children":4587},{"style":688},[4588],{"type":56,"value":2213},{"type":29,"tag":127,"props":4590,"children":4591},{"class":677,"line":2639},[4592,4596,4600,4604],{"type":29,"tag":127,"props":4593,"children":4594},{"style":1991},[4595],{"type":56,"value":2645},{"type":29,"tag":127,"props":4597,"children":4598},{"style":688},[4599],{"type":56,"value":717},{"type":29,"tag":127,"props":4601,"children":4602},{"style":2303},[4603],{"type":56,"value":113},{"type":29,"tag":127,"props":4605,"children":4606},{"style":688},[4607],{"type":56,"value":2009},{"type":29,"tag":127,"props":4609,"children":4610},{"class":677,"line":2660},[4611,4615],{"type":29,"tag":127,"props":4612,"children":4613},{"style":1991},[4614],{"type":56,"value":2666},{"type":29,"tag":127,"props":4616,"children":4617},{"style":688},[4618],{"type":56,"value":2064},{"type":29,"tag":127,"props":4620,"children":4621},{"class":677,"line":2673},[4622,4626],{"type":29,"tag":127,"props":4623,"children":4624},{"style":1991},[4625],{"type":56,"value":2679},{"type":29,"tag":127,"props":4627,"children":4628},{"style":688},[4629],{"type":56,"value":2064},{"type":29,"tag":127,"props":4631,"children":4632},{"class":677,"line":2686},[4633,4637,4641,4645],{"type":29,"tag":127,"props":4634,"children":4635},{"style":1991},[4636],{"type":56,"value":2692},{"type":29,"tag":127,"props":4638,"children":4639},{"style":688},[4640],{"type":56,"value":717},{"type":29,"tag":127,"props":4642,"children":4643},{"style":2303},[4644],{"type":56,"value":113},{"type":29,"tag":127,"props":4646,"children":4647},{"style":688},[4648],{"type":56,"value":2009},{"type":29,"tag":127,"props":4650,"children":4651},{"class":677,"line":2707},[4652,4656,4660],{"type":29,"tag":127,"props":4653,"children":4654},{"style":1991},[4655],{"type":56,"value":2713},{"type":29,"tag":127,"props":4657,"children":4658},{"style":688},[4659],{"type":56,"value":717},{"type":29,"tag":127,"props":4661,"children":4662},{"style":2303},[4663],{"type":56,"value":2306},{"type":29,"tag":127,"props":4665,"children":4666},{"class":677,"line":2724},[4667],{"type":29,"tag":127,"props":4668,"children":4669},{"style":688},[4670],{"type":56,"value":2322},{"type":29,"tag":127,"props":4672,"children":4673},{"class":677,"line":2732},[4674,4678,4682,4686],{"type":29,"tag":127,"props":4675,"children":4676},{"style":1991},[4677],{"type":56,"value":2738},{"type":29,"tag":127,"props":4679,"children":4680},{"style":688},[4681],{"type":56,"value":717},{"type":29,"tag":127,"props":4683,"children":4684},{"style":2303},[4685],{"type":56,"value":113},{"type":29,"tag":127,"props":4687,"children":4688},{"style":688},[4689],{"type":56,"value":2009},{"type":29,"tag":127,"props":4691,"children":4692},{"class":677,"line":2753},[4693,4697,4701],{"type":29,"tag":127,"props":4694,"children":4695},{"style":1991},[4696],{"type":56,"value":2759},{"type":29,"tag":127,"props":4698,"children":4699},{"style":688},[4700],{"type":56,"value":717},{"type":29,"tag":127,"props":4702,"children":4703},{"style":2303},[4704],{"type":56,"value":2306},{"type":29,"tag":127,"props":4706,"children":4707},{"class":677,"line":2770},[4708],{"type":29,"tag":127,"props":4709,"children":4710},{"style":688},[4711],{"type":56,"value":2213},{"type":29,"tag":127,"props":4713,"children":4714},{"class":677,"line":2778},[4715,4719],{"type":29,"tag":127,"props":4716,"children":4717},{"style":1991},[4718],{"type":56,"value":2784},{"type":29,"tag":127,"props":4720,"children":4721},{"style":688},[4722],{"type":56,"value":2064},{"type":29,"tag":127,"props":4724,"children":4725},{"class":677,"line":2791},[4726,4730],{"type":29,"tag":127,"props":4727,"children":4728},{"style":1991},[4729],{"type":56,"value":2797},{"type":29,"tag":127,"props":4731,"children":4732},{"style":688},[4733],{"type":56,"value":2064},{"type":29,"tag":127,"props":4735,"children":4736},{"class":677,"line":2804},[4737,4741,4745],{"type":29,"tag":127,"props":4738,"children":4739},{"style":1991},[4740],{"type":56,"value":2810},{"type":29,"tag":127,"props":4742,"children":4743},{"style":688},[4744],{"type":56,"value":717},{"type":29,"tag":127,"props":4746,"children":4747},{"style":2001},[4748],{"type":56,"value":2819},{"type":29,"tag":127,"props":4750,"children":4751},{"class":677,"line":2822},[4752],{"type":29,"tag":127,"props":4753,"children":4754},{"style":688},[4755],{"type":56,"value":2322},{"type":29,"tag":127,"props":4757,"children":4758},{"class":677,"line":2830},[4759,4763],{"type":29,"tag":127,"props":4760,"children":4761},{"style":1991},[4762],{"type":56,"value":2836},{"type":29,"tag":127,"props":4764,"children":4765},{"style":688},[4766],{"type":56,"value":2226},{"type":29,"tag":127,"props":4768,"children":4769},{"class":677,"line":2843},[4770],{"type":29,"tag":127,"props":4771,"children":4772},{"style":2001},[4773],{"type":56,"value":2849},{"type":29,"tag":127,"props":4775,"children":4776},{"class":677,"line":2852},[4777],{"type":29,"tag":127,"props":4778,"children":4779},{"style":688},[4780],{"type":56,"value":2858},{"type":29,"tag":127,"props":4782,"children":4783},{"class":677,"line":2861},[4784,4788],{"type":29,"tag":127,"props":4785,"children":4786},{"style":1991},[4787],{"type":56,"value":2867},{"type":29,"tag":127,"props":4789,"children":4790},{"style":688},[4791],{"type":56,"value":2226},{"type":29,"tag":127,"props":4793,"children":4794},{"class":677,"line":2874},[4795],{"type":29,"tag":127,"props":4796,"children":4797},{"style":2001},[4798],{"type":56,"value":2849},{"type":29,"tag":127,"props":4800,"children":4801},{"class":677,"line":2882},[4802],{"type":29,"tag":127,"props":4803,"children":4804},{"style":688},[4805],{"type":56,"value":2888},{"type":29,"tag":127,"props":4807,"children":4808},{"class":677,"line":2891},[4809],{"type":29,"tag":127,"props":4810,"children":4811},{"style":688},[4812],{"type":56,"value":2213},{"type":29,"tag":127,"props":4814,"children":4815},{"class":677,"line":2899},[4816,4820],{"type":29,"tag":127,"props":4817,"children":4818},{"style":1991},[4819],{"type":56,"value":2905},{"type":29,"tag":127,"props":4821,"children":4822},{"style":688},[4823],{"type":56,"value":2064},{"type":29,"tag":127,"props":4825,"children":4826},{"class":677,"line":2912},[4827,4831],{"type":29,"tag":127,"props":4828,"children":4829},{"style":1991},[4830],{"type":56,"value":2918},{"type":29,"tag":127,"props":4832,"children":4833},{"style":688},[4834],{"type":56,"value":2064},{"type":29,"tag":127,"props":4836,"children":4837},{"class":677,"line":2925},[4838,4842,4846,4850],{"type":29,"tag":127,"props":4839,"children":4840},{"style":1991},[4841],{"type":56,"value":2931},{"type":29,"tag":127,"props":4843,"children":4844},{"style":688},[4845],{"type":56,"value":717},{"type":29,"tag":127,"props":4847,"children":4848},{"style":2303},[4849],{"type":56,"value":113},{"type":29,"tag":127,"props":4851,"children":4852},{"style":688},[4853],{"type":56,"value":2009},{"type":29,"tag":127,"props":4855,"children":4856},{"class":677,"line":2946},[4857,4861],{"type":29,"tag":127,"props":4858,"children":4859},{"style":1991},[4860],{"type":56,"value":2952},{"type":29,"tag":127,"props":4862,"children":4863},{"style":688},[4864],{"type":56,"value":2226},{"type":29,"tag":127,"props":4866,"children":4867},{"class":677,"line":2959},[4868,4872],{"type":29,"tag":127,"props":4869,"children":4870},{"style":2001},[4871],{"type":56,"value":2965},{"type":29,"tag":127,"props":4873,"children":4874},{"style":688},[4875],{"type":56,"value":2009},{"type":29,"tag":127,"props":4877,"children":4878},{"class":677,"line":2972},[4879],{"type":29,"tag":127,"props":4880,"children":4881},{"style":2001},[4882],{"type":56,"value":2978},{"type":29,"tag":127,"props":4884,"children":4885},{"class":677,"line":2981},[4886],{"type":29,"tag":127,"props":4887,"children":4888},{"style":688},[4889],{"type":56,"value":2987},{"type":29,"tag":127,"props":4891,"children":4892},{"class":677,"line":2990},[4893],{"type":29,"tag":127,"props":4894,"children":4895},{"style":688},[4896],{"type":56,"value":2556},{"type":29,"tag":127,"props":4898,"children":4899},{"class":677,"line":2998},[4900],{"type":29,"tag":127,"props":4901,"children":4902},{"style":688},[4903],{"type":56,"value":3004},{"type":29,"tag":127,"props":4905,"children":4906},{"class":677,"line":3007},[4907],{"type":29,"tag":127,"props":4908,"children":4909},{"style":688},[4910],{"type":56,"value":3013},{"type":29,"tag":48,"props":4912,"children":4913},{},[4914],{"type":56,"value":4915},"oder über das CLI:",{"type":29,"tag":659,"props":4917,"children":4919},{"className":3021,"code":4918,"language":3023,"meta":7,"style":7},"composer config repositories.\u003Cgroup_id> composer https://\u003CDOMAIN-NAME>/api/v4/group/\u003Cgroup_id>/-/packages/composer/packages.json\n",[4920],{"type":29,"tag":672,"props":4921,"children":4922},{"__ignoreMap":7},[4923],{"type":29,"tag":127,"props":4924,"children":4925},{"class":677,"line":678},[4926,4930,4935,4940,4946,4951,4956,4961,4966,4971,4975,4980,4985,4989,4994,4998,5002,5006,5010],{"type":29,"tag":127,"props":4927,"children":4928},{"style":3033},[4929],{"type":56,"value":1961},{"type":29,"tag":127,"props":4931,"children":4932},{"style":720},[4933],{"type":56,"value":4934}," config",{"type":29,"tag":127,"props":4936,"children":4937},{"style":720},[4938],{"type":56,"value":4939}," repositories.",{"type":29,"tag":127,"props":4941,"children":4943},{"style":4942},"--shiki-default:#F97583;--shiki-dark:#F97583;--shiki-sepia:#F92672",[4944],{"type":56,"value":4945},"\u003C",{"type":29,"tag":127,"props":4947,"children":4948},{"style":720},[4949],{"type":56,"value":4950},"group_i",{"type":29,"tag":127,"props":4952,"children":4953},{"style":688},[4954],{"type":56,"value":4955},"d",{"type":29,"tag":127,"props":4957,"children":4958},{"style":4942},[4959],{"type":56,"value":4960},">",{"type":29,"tag":127,"props":4962,"children":4963},{"style":720},[4964],{"type":56,"value":4965}," composer",{"type":29,"tag":127,"props":4967,"children":4968},{"style":720},[4969],{"type":56,"value":4970}," https://",{"type":29,"tag":127,"props":4972,"children":4973},{"style":4942},[4974],{"type":56,"value":4945},{"type":29,"tag":127,"props":4976,"children":4977},{"style":720},[4978],{"type":56,"value":4979},"DOMAIN-NAM",{"type":29,"tag":127,"props":4981,"children":4982},{"style":688},[4983],{"type":56,"value":4984},"E",{"type":29,"tag":127,"props":4986,"children":4987},{"style":4942},[4988],{"type":56,"value":4960},{"type":29,"tag":127,"props":4990,"children":4991},{"style":720},[4992],{"type":56,"value":4993},"/api/v4/group/",{"type":29,"tag":127,"props":4995,"children":4996},{"style":4942},[4997],{"type":56,"value":4945},{"type":29,"tag":127,"props":4999,"children":5000},{"style":720},[5001],{"type":56,"value":4950},{"type":29,"tag":127,"props":5003,"children":5004},{"style":688},[5005],{"type":56,"value":4955},{"type":29,"tag":127,"props":5007,"children":5008},{"style":4942},[5009],{"type":56,"value":4960},{"type":29,"tag":127,"props":5011,"children":5012},{"style":720},[5013],{"type":56,"value":5014},"/-/packages/composer/packages.json\n",{"type":29,"tag":48,"props":5016,"children":5017},{},[5018],{"type":56,"value":5019},"Und die GitLab-Anmeldeinformationen einrichten:",{"type":29,"tag":659,"props":5021,"children":5023},{"className":3021,"code":5022,"language":3023,"meta":7,"style":7},"composer config gitlab-token.\u003CDOMAIN-NAME> \u003Cpersonal_access_token>\n",[5024],{"type":29,"tag":672,"props":5025,"children":5026},{"__ignoreMap":7},[5027],{"type":29,"tag":127,"props":5028,"children":5029},{"class":677,"line":678},[5030,5034,5038,5043,5047,5051,5055,5059,5064,5069,5074],{"type":29,"tag":127,"props":5031,"children":5032},{"style":3033},[5033],{"type":56,"value":1961},{"type":29,"tag":127,"props":5035,"children":5036},{"style":720},[5037],{"type":56,"value":4934},{"type":29,"tag":127,"props":5039,"children":5040},{"style":720},[5041],{"type":56,"value":5042}," gitlab-token.",{"type":29,"tag":127,"props":5044,"children":5045},{"style":4942},[5046],{"type":56,"value":4945},{"type":29,"tag":127,"props":5048,"children":5049},{"style":720},[5050],{"type":56,"value":4979},{"type":29,"tag":127,"props":5052,"children":5053},{"style":688},[5054],{"type":56,"value":4984},{"type":29,"tag":127,"props":5056,"children":5057},{"style":4942},[5058],{"type":56,"value":4960},{"type":29,"tag":127,"props":5060,"children":5061},{"style":4942},[5062],{"type":56,"value":5063}," \u003C",{"type":29,"tag":127,"props":5065,"children":5066},{"style":720},[5067],{"type":56,"value":5068},"personal_access_toke",{"type":29,"tag":127,"props":5070,"children":5071},{"style":688},[5072],{"type":56,"value":5073},"n",{"type":29,"tag":127,"props":5075,"children":5076},{"style":4942},[5077],{"type":56,"value":5078},">\n",{"type":29,"tag":48,"props":5080,"children":5081},{},[5082,5084,5089],{"type":56,"value":5083},"Mehr über diesen Prozess in der ",{"type":29,"tag":645,"props":5085,"children":5087},{"href":5086},"https://docs.gitlab.com/user/packages/composer_repository/#install-a-composer-package",[5088],{"type":56,"value":1881},{"type":56,"value":3926},{"type":29,"tag":48,"props":5091,"children":5092},{},[5093],{"type":56,"value":5094},"Jetzt installieren wir unser Paket wie gewohnt:",{"type":29,"tag":659,"props":5096,"children":5097},{"className":3021,"code":3022,"language":3023,"meta":7,"style":7},[5098],{"type":29,"tag":672,"props":5099,"children":5100},{"__ignoreMap":7},[5101],{"type":29,"tag":127,"props":5102,"children":5103},{"class":677,"line":678},[5104,5108,5112],{"type":29,"tag":127,"props":5105,"children":5106},{"style":3033},[5107],{"type":56,"value":1961},{"type":29,"tag":127,"props":5109,"children":5110},{"style":720},[5111],{"type":56,"value":3040},{"type":29,"tag":127,"props":5113,"children":5114},{"style":720},[5115],{"type":56,"value":3045},{"type":29,"tag":659,"props":5117,"children":5119},{"className":3757,"code":5118,"language":3759,"meta":7,"style":7},"./composer.json has been updated\nRunning composer update acme/sample-plugin\nLoading composer repositories with package information\nUpdating dependencies\nLock file operations: 1 install, 0 updates, 0 removals\n  - Locking acme/sample-plugin (1.0.0)\nWriting lock file\nInstalling dependencies from lock file (including require-dev)\nPackage operations: 1 install, 0 updates, 0 removals\n  - Downloading acme/sample-plugin (1.0.0)\n  - Installing acme/sample-plugin (1.0.0): Extracting archive\nGenerating optimized autoload files\n\nRun composer recipes at any time to see the status of your Symfony recipes.\n\nExecuting script assets:install [OK]\n\nUsing version ^1.0 for acme/sample-plugin\n",[5120],{"type":29,"tag":672,"props":5121,"children":5122},{"__ignoreMap":7},[5123,5130,5137,5144,5151,5158,5165,5172,5179,5186,5194,5202,5209,5216,5223,5230,5237,5244],{"type":29,"tag":127,"props":5124,"children":5125},{"class":677,"line":678},[5126],{"type":29,"tag":127,"props":5127,"children":5128},{},[5129],{"type":56,"value":3111},{"type":29,"tag":127,"props":5131,"children":5132},{"class":677,"line":342},[5133],{"type":29,"tag":127,"props":5134,"children":5135},{},[5136],{"type":56,"value":3119},{"type":29,"tag":127,"props":5138,"children":5139},{"class":677,"line":706},[5140],{"type":29,"tag":127,"props":5141,"children":5142},{},[5143],{"type":56,"value":3786},{"type":29,"tag":127,"props":5145,"children":5146},{"class":677,"line":726},[5147],{"type":29,"tag":127,"props":5148,"children":5149},{},[5150],{"type":56,"value":3794},{"type":29,"tag":127,"props":5152,"children":5153},{"class":677,"line":664},[5154],{"type":29,"tag":127,"props":5155,"children":5156},{},[5157],{"type":56,"value":3143},{"type":29,"tag":127,"props":5159,"children":5160},{"class":677,"line":665},[5161],{"type":29,"tag":127,"props":5162,"children":5163},{},[5164],{"type":56,"value":3809},{"type":29,"tag":127,"props":5166,"children":5167},{"class":677,"line":666},[5168],{"type":29,"tag":127,"props":5169,"children":5170},{},[5171],{"type":56,"value":3159},{"type":29,"tag":127,"props":5173,"children":5174},{"class":677,"line":667},[5175],{"type":29,"tag":127,"props":5176,"children":5177},{},[5178],{"type":56,"value":3167},{"type":29,"tag":127,"props":5180,"children":5181},{"class":677,"line":668},[5182],{"type":29,"tag":127,"props":5183,"children":5184},{},[5185],{"type":56,"value":3175},{"type":29,"tag":127,"props":5187,"children":5188},{"class":677,"line":1329},[5189],{"type":29,"tag":127,"props":5190,"children":5191},{},[5192],{"type":56,"value":5193},"  - Downloading acme/sample-plugin (1.0.0)\n",{"type":29,"tag":127,"props":5195,"children":5196},{"class":677,"line":1342},[5197],{"type":29,"tag":127,"props":5198,"children":5199},{},[5200],{"type":56,"value":5201},"  - Installing acme/sample-plugin (1.0.0): Extracting archive\n",{"type":29,"tag":127,"props":5203,"children":5204},{"class":677,"line":118},[5205],{"type":29,"tag":127,"props":5206,"children":5207},{},[5208],{"type":56,"value":3199},{"type":29,"tag":127,"props":5210,"children":5211},{"class":677,"line":1367},[5212],{"type":29,"tag":127,"props":5213,"children":5214},{"emptyLinePlaceholder":500},[5215],{"type":56,"value":1399},{"type":29,"tag":127,"props":5217,"children":5218},{"class":677,"line":1380},[5219],{"type":29,"tag":127,"props":5220,"children":5221},{},[5222],{"type":56,"value":3214},{"type":29,"tag":127,"props":5224,"children":5225},{"class":677,"line":1393},[5226],{"type":29,"tag":127,"props":5227,"children":5228},{"emptyLinePlaceholder":500},[5229],{"type":56,"value":1399},{"type":29,"tag":127,"props":5231,"children":5232},{"class":677,"line":1402},[5233],{"type":29,"tag":127,"props":5234,"children":5235},{},[5236],{"type":56,"value":3229},{"type":29,"tag":127,"props":5238,"children":5239},{"class":677,"line":1415},[5240],{"type":29,"tag":127,"props":5241,"children":5242},{"emptyLinePlaceholder":500},[5243],{"type":56,"value":1399},{"type":29,"tag":127,"props":5245,"children":5246},{"class":677,"line":1428},[5247],{"type":29,"tag":127,"props":5248,"children":5249},{},[5250],{"type":56,"value":3896},{"type":29,"tag":48,"props":5252,"children":5253},{},[5254],{"type":29,"tag":127,"props":5255,"children":5258},{"className":5256},[5257],"text-h2",[5259],{"type":56,"value":5260},"Großartig. Direkter Paket-Download!",{"type":29,"tag":122,"props":5262,"children":5264},{"id":5263},"warum-die-mühe",[5265],{"type":56,"value":5266},"Warum die Mühe?",{"type":29,"tag":48,"props":5268,"children":5269},{},[5270,5272,5278,5280,5286],{"type":56,"value":5271},"Das ist eine sehr gute Frage. Der Hauptgrund ist das Paket-Caching. Bei der Ausführung in einer ",{"type":29,"tag":672,"props":5273,"children":5275},{"className":5274},[],[5276],{"type":56,"value":5277},"CI/CD",{"type":56,"value":5279},"-Umgebung oder einem ",{"type":29,"tag":672,"props":5281,"children":5283},{"className":5282},[],[5284],{"type":56,"value":5285},"docker build",{"type":56,"value":5287}," kann das Caching von Paketen einen massiven Leistungsschub bewirken.",{"type":29,"tag":1670,"props":5289,"children":5290},{},[],{"type":29,"tag":1189,"props":5292,"children":5293},{},[],{"type":29,"tag":90,"props":5295,"children":5297},{"id":5296},"release-pipeline",[5298],{"type":56,"value":5299},"Release-Pipeline",{"type":29,"tag":122,"props":5301,"children":5303},{"id":5302},"mit-manuellem-tagging",[5304],{"type":56,"value":5305},"Mit manuellem Tagging",{"type":29,"tag":48,"props":5307,"children":5308},{},[5309],{"type":56,"value":5310},"Dies ist eine einfache Pipeline, in der ein Git-Tag manuell erstellt und pushen wird.",{"type":29,"tag":48,"props":5312,"children":5313},{},[5314,5316,5321,5322,5327],{"type":56,"value":5315},"Bitte sicherstellen, dass Sie die ",{"type":29,"tag":672,"props":5317,"children":5319},{"className":5318},[],[5320],{"type":56,"value":3275},{"type":56,"value":3277},{"type":29,"tag":672,"props":5323,"children":5325},{"className":5324},[],[5326],{"type":56,"value":3283},{"type":56,"value":5328}," immer aktualisiert wird.",{"type":29,"tag":659,"props":5330,"children":5332},{"className":3021,"code":5331,"language":3023,"meta":7,"style":7},"git tag \u003Cversion>\ngit push --tags\n",[5333],{"type":29,"tag":672,"props":5334,"children":5335},{"__ignoreMap":7},[5336,5364],{"type":29,"tag":127,"props":5337,"children":5338},{"class":677,"line":678},[5339,5343,5347,5351,5356,5360],{"type":29,"tag":127,"props":5340,"children":5341},{"style":3033},[5342],{"type":56,"value":907},{"type":29,"tag":127,"props":5344,"children":5345},{"style":720},[5346],{"type":56,"value":3706},{"type":29,"tag":127,"props":5348,"children":5349},{"style":4942},[5350],{"type":56,"value":5063},{"type":29,"tag":127,"props":5352,"children":5353},{"style":720},[5354],{"type":56,"value":5355},"versio",{"type":29,"tag":127,"props":5357,"children":5358},{"style":688},[5359],{"type":56,"value":5073},{"type":29,"tag":127,"props":5361,"children":5362},{"style":4942},[5363],{"type":56,"value":5078},{"type":29,"tag":127,"props":5365,"children":5366},{"class":677,"line":342},[5367,5371,5375],{"type":29,"tag":127,"props":5368,"children":5369},{"style":3033},[5370],{"type":56,"value":907},{"type":29,"tag":127,"props":5372,"children":5373},{"style":720},[5374],{"type":56,"value":3723},{"type":29,"tag":127,"props":5376,"children":5377},{"style":2303},[5378],{"type":56,"value":3728},{"type":29,"tag":659,"props":5380,"children":5383},{"className":669,"code":5381,"filename":5382,"language":508,"meta":7,"style":7},"stages:\n  - release\n\ndeploy:\n  image: alpine/curl\n  stage: release\n  script:\n    - 'curl --fail-with-body --header \"Job-Token: $CI_JOB_TOKEN\" --data tag=$CI_COMMIT_TAG \"${CI_API_V4_URL}/projects/$CI_PROJECT_ID/packages/composer\"'\n  environment: production\n  rules:\n    if: $CI_COMMIT_TAG\n",".gitlab-ci.yml",[5384],{"type":29,"tag":672,"props":5385,"children":5386},{"__ignoreMap":7},[5387,5399,5412,5419,5431,5448,5464,5476,5489,5506,5518],{"type":29,"tag":127,"props":5388,"children":5389},{"class":677,"line":678},[5390,5395],{"type":29,"tag":127,"props":5391,"children":5392},{"style":682},[5393],{"type":56,"value":5394},"stages",{"type":29,"tag":127,"props":5396,"children":5397},{"style":688},[5398],{"type":56,"value":691},{"type":29,"tag":127,"props":5400,"children":5401},{"class":677,"line":342},[5402,5407],{"type":29,"tag":127,"props":5403,"children":5404},{"style":688},[5405],{"type":56,"value":5406},"  - ",{"type":29,"tag":127,"props":5408,"children":5409},{"style":720},[5410],{"type":56,"value":5411},"release\n",{"type":29,"tag":127,"props":5413,"children":5414},{"class":677,"line":706},[5415],{"type":29,"tag":127,"props":5416,"children":5417},{"emptyLinePlaceholder":500},[5418],{"type":56,"value":1399},{"type":29,"tag":127,"props":5420,"children":5421},{"class":677,"line":726},[5422,5427],{"type":29,"tag":127,"props":5423,"children":5424},{"style":682},[5425],{"type":56,"value":5426},"deploy",{"type":29,"tag":127,"props":5428,"children":5429},{"style":688},[5430],{"type":56,"value":691},{"type":29,"tag":127,"props":5432,"children":5433},{"class":677,"line":664},[5434,5439,5443],{"type":29,"tag":127,"props":5435,"children":5436},{"style":682},[5437],{"type":56,"value":5438},"  image",{"type":29,"tag":127,"props":5440,"children":5441},{"style":688},[5442],{"type":56,"value":717},{"type":29,"tag":127,"props":5444,"children":5445},{"style":720},[5446],{"type":56,"value":5447},"alpine/curl\n",{"type":29,"tag":127,"props":5449,"children":5450},{"class":677,"line":665},[5451,5456,5460],{"type":29,"tag":127,"props":5452,"children":5453},{"style":682},[5454],{"type":56,"value":5455},"  stage",{"type":29,"tag":127,"props":5457,"children":5458},{"style":688},[5459],{"type":56,"value":717},{"type":29,"tag":127,"props":5461,"children":5462},{"style":720},[5463],{"type":56,"value":5411},{"type":29,"tag":127,"props":5465,"children":5466},{"class":677,"line":666},[5467,5472],{"type":29,"tag":127,"props":5468,"children":5469},{"style":682},[5470],{"type":56,"value":5471},"  script",{"type":29,"tag":127,"props":5473,"children":5474},{"style":688},[5475],{"type":56,"value":691},{"type":29,"tag":127,"props":5477,"children":5478},{"class":677,"line":667},[5479,5484],{"type":29,"tag":127,"props":5480,"children":5481},{"style":688},[5482],{"type":56,"value":5483},"    - ",{"type":29,"tag":127,"props":5485,"children":5486},{"style":720},[5487],{"type":56,"value":5488},"'curl --fail-with-body --header \"Job-Token: $CI_JOB_TOKEN\" --data tag=$CI_COMMIT_TAG \"${CI_API_V4_URL}/projects/$CI_PROJECT_ID/packages/composer\"'\n",{"type":29,"tag":127,"props":5490,"children":5491},{"class":677,"line":668},[5492,5497,5501],{"type":29,"tag":127,"props":5493,"children":5494},{"style":682},[5495],{"type":56,"value":5496},"  environment",{"type":29,"tag":127,"props":5498,"children":5499},{"style":688},[5500],{"type":56,"value":717},{"type":29,"tag":127,"props":5502,"children":5503},{"style":720},[5504],{"type":56,"value":5505},"production\n",{"type":29,"tag":127,"props":5507,"children":5508},{"class":677,"line":1329},[5509,5514],{"type":29,"tag":127,"props":5510,"children":5511},{"style":682},[5512],{"type":56,"value":5513},"  rules",{"type":29,"tag":127,"props":5515,"children":5516},{"style":688},[5517],{"type":56,"value":691},{"type":29,"tag":127,"props":5519,"children":5520},{"class":677,"line":1342},[5521,5526,5530],{"type":29,"tag":127,"props":5522,"children":5523},{"style":682},[5524],{"type":56,"value":5525},"    if",{"type":29,"tag":127,"props":5527,"children":5528},{"style":688},[5529],{"type":56,"value":717},{"type":29,"tag":127,"props":5531,"children":5532},{"style":720},[5533],{"type":56,"value":5534},"$CI_COMMIT_TAG\n",{"type":29,"tag":122,"props":5536,"children":5538},{"id":5537},"mit-semantic-release",[5539],{"type":56,"value":5540},"Mit semantic-release",{"type":29,"tag":48,"props":5542,"children":5543},{},[5544],{"type":56,"value":5545},"Es wäre viel einfacher, wenn wir unsere Änderungen einfach pushen könnten und uns nicht um Versionierung und Tagging kümmern müssten.",{"type":29,"tag":48,"props":5547,"children":5548},{},[5549,5555],{"type":29,"tag":645,"props":5550,"children":5552},{"href":5551},"https://github.com/semantic-release/semantic-release",[5553],{"type":56,"value":5554},"semantic-release",{"type":56,"value":5556}," automatisiert den gesamten Workflow für Paket-Releases.",{"type":29,"tag":48,"props":5558,"children":5559},{},[5560,5562,5568],{"type":56,"value":5561},"Bitte befolgen Sie der ",{"type":29,"tag":645,"props":5563,"children":5565},{"href":5564},"https://github.com/semantic-release/gitlab?tab=readme-ov-file#gitlab-authentication",[5566],{"type":56,"value":5567},"Anleitung zur GitLab-Authentifizierung",{"type":56,"value":5569},", bevor Sie weiterlesen.",{"type":29,"tag":659,"props":5571,"children":5574},{"className":669,"code":5572,"filename":5573,"language":508,"meta":7,"style":7},"stages:\n  - release\n\nrelease:\n  stage: release\n  image:\n    name: ghcr.io/voxpupuli/semantic-release:25.0.0-latest\n    entrypoint: [\"\"]\n  interruptible: true\n  script:\n    - /container-entrypoint.sh\n  rules:\n    - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH\n      when: never\n    - if: $CI_COMMIT_BRANCH\n\n","\u003Cplugin-root>/.gitlab-ci.yml",[5575],{"type":29,"tag":672,"props":5576,"children":5577},{"__ignoreMap":7},[5578,5589,5600,5607,5619,5634,5645,5662,5685,5701,5712,5724,5735,5756,5773],{"type":29,"tag":127,"props":5579,"children":5580},{"class":677,"line":678},[5581,5585],{"type":29,"tag":127,"props":5582,"children":5583},{"style":682},[5584],{"type":56,"value":5394},{"type":29,"tag":127,"props":5586,"children":5587},{"style":688},[5588],{"type":56,"value":691},{"type":29,"tag":127,"props":5590,"children":5591},{"class":677,"line":342},[5592,5596],{"type":29,"tag":127,"props":5593,"children":5594},{"style":688},[5595],{"type":56,"value":5406},{"type":29,"tag":127,"props":5597,"children":5598},{"style":720},[5599],{"type":56,"value":5411},{"type":29,"tag":127,"props":5601,"children":5602},{"class":677,"line":706},[5603],{"type":29,"tag":127,"props":5604,"children":5605},{"emptyLinePlaceholder":500},[5606],{"type":56,"value":1399},{"type":29,"tag":127,"props":5608,"children":5609},{"class":677,"line":726},[5610,5615],{"type":29,"tag":127,"props":5611,"children":5612},{"style":682},[5613],{"type":56,"value":5614},"release",{"type":29,"tag":127,"props":5616,"children":5617},{"style":688},[5618],{"type":56,"value":691},{"type":29,"tag":127,"props":5620,"children":5621},{"class":677,"line":664},[5622,5626,5630],{"type":29,"tag":127,"props":5623,"children":5624},{"style":682},[5625],{"type":56,"value":5455},{"type":29,"tag":127,"props":5627,"children":5628},{"style":688},[5629],{"type":56,"value":717},{"type":29,"tag":127,"props":5631,"children":5632},{"style":720},[5633],{"type":56,"value":5411},{"type":29,"tag":127,"props":5635,"children":5636},{"class":677,"line":665},[5637,5641],{"type":29,"tag":127,"props":5638,"children":5639},{"style":682},[5640],{"type":56,"value":5438},{"type":29,"tag":127,"props":5642,"children":5643},{"style":688},[5644],{"type":56,"value":691},{"type":29,"tag":127,"props":5646,"children":5647},{"class":677,"line":666},[5648,5653,5657],{"type":29,"tag":127,"props":5649,"children":5650},{"style":682},[5651],{"type":56,"value":5652},"    name",{"type":29,"tag":127,"props":5654,"children":5655},{"style":688},[5656],{"type":56,"value":717},{"type":29,"tag":127,"props":5658,"children":5659},{"style":720},[5660],{"type":56,"value":5661},"ghcr.io/voxpupuli/semantic-release:25.0.0-latest\n",{"type":29,"tag":127,"props":5663,"children":5664},{"class":677,"line":667},[5665,5670,5675,5680],{"type":29,"tag":127,"props":5666,"children":5667},{"style":682},[5668],{"type":56,"value":5669},"    entrypoint",{"type":29,"tag":127,"props":5671,"children":5672},{"style":688},[5673],{"type":56,"value":5674},": [",{"type":29,"tag":127,"props":5676,"children":5677},{"style":720},[5678],{"type":56,"value":5679},"\"\"",{"type":29,"tag":127,"props":5681,"children":5682},{"style":688},[5683],{"type":56,"value":5684},"]\n",{"type":29,"tag":127,"props":5686,"children":5687},{"class":677,"line":668},[5688,5693,5697],{"type":29,"tag":127,"props":5689,"children":5690},{"style":682},[5691],{"type":56,"value":5692},"  interruptible",{"type":29,"tag":127,"props":5694,"children":5695},{"style":688},[5696],{"type":56,"value":717},{"type":29,"tag":127,"props":5698,"children":5699},{"style":2303},[5700],{"type":56,"value":2306},{"type":29,"tag":127,"props":5702,"children":5703},{"class":677,"line":1329},[5704,5708],{"type":29,"tag":127,"props":5705,"children":5706},{"style":682},[5707],{"type":56,"value":5471},{"type":29,"tag":127,"props":5709,"children":5710},{"style":688},[5711],{"type":56,"value":691},{"type":29,"tag":127,"props":5713,"children":5714},{"class":677,"line":1342},[5715,5719],{"type":29,"tag":127,"props":5716,"children":5717},{"style":688},[5718],{"type":56,"value":5483},{"type":29,"tag":127,"props":5720,"children":5721},{"style":720},[5722],{"type":56,"value":5723},"/container-entrypoint.sh\n",{"type":29,"tag":127,"props":5725,"children":5726},{"class":677,"line":118},[5727,5731],{"type":29,"tag":127,"props":5728,"children":5729},{"style":682},[5730],{"type":56,"value":5513},{"type":29,"tag":127,"props":5732,"children":5733},{"style":688},[5734],{"type":56,"value":691},{"type":29,"tag":127,"props":5736,"children":5737},{"class":677,"line":1367},[5738,5742,5747,5751],{"type":29,"tag":127,"props":5739,"children":5740},{"style":688},[5741],{"type":56,"value":5483},{"type":29,"tag":127,"props":5743,"children":5744},{"style":682},[5745],{"type":56,"value":5746},"if",{"type":29,"tag":127,"props":5748,"children":5749},{"style":688},[5750],{"type":56,"value":717},{"type":29,"tag":127,"props":5752,"children":5753},{"style":720},[5754],{"type":56,"value":5755},"$CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH\n",{"type":29,"tag":127,"props":5757,"children":5758},{"class":677,"line":1380},[5759,5764,5768],{"type":29,"tag":127,"props":5760,"children":5761},{"style":682},[5762],{"type":56,"value":5763},"      when",{"type":29,"tag":127,"props":5765,"children":5766},{"style":688},[5767],{"type":56,"value":717},{"type":29,"tag":127,"props":5769,"children":5770},{"style":720},[5771],{"type":56,"value":5772},"never\n",{"type":29,"tag":127,"props":5774,"children":5775},{"class":677,"line":1393},[5776,5780,5784,5788],{"type":29,"tag":127,"props":5777,"children":5778},{"style":688},[5779],{"type":56,"value":5483},{"type":29,"tag":127,"props":5781,"children":5782},{"style":682},[5783],{"type":56,"value":5746},{"type":29,"tag":127,"props":5785,"children":5786},{"style":688},[5787],{"type":56,"value":717},{"type":29,"tag":127,"props":5789,"children":5790},{"style":720},[5791],{"type":56,"value":5792},"$CI_COMMIT_BRANCH\n",{"type":29,"tag":659,"props":5794,"children":5797},{"className":1966,"code":5795,"filename":5796,"language":454,"meta":7,"style":7},"{\n  \"plugins\": [\n    \"@semantic-release/commit-analyzer\",\n    [\n      \"semantic-release-replace-plugin\",\n      {\n        \"replacements\": [\n          {\n            \"files\": [\"composer.json\"],\n            \"from\": \"version\\\": \\\".*\\\"\",\n            \"to\": \"version\\\": \\\"${nextRelease.version}\\\"\"\n          }\n        ]\n      }\n    ],\n    [\n      \"@semantic-release/git\",\n      {\n        \"assets\": [\"composer.json\"],\n        \"message\": \"chore(release): ${nextRelease.version} [skip ci]\\n\\n${nextRelease.notes}\"\n      }\n    ],\n    [\n      \"@semantic-release/exec\",\n      {\n        \"publishCmd\": \"curl --fail-with-body --header \\\"Job-Token: ${process.env.CI_JOB_TOKEN}\\\" --data tag=${nextRelease.gitTag} ${process.env.CI_API_V4_URL}/projects/${process.env.CI_PROJECT_ID}/packages/composer\"\n      }\n    ]\n  ]\n}\n","\u003Cplugin-root>/.releaserc.json",[5798],{"type":29,"tag":672,"props":5799,"children":5800},{"__ignoreMap":7},[5801,5808,5820,5832,5840,5852,5860,5872,5880,5902,5949,5991,5999,6007,6014,6021,6028,6040,6047,6067,6094,6101,6108,6115,6127,6134,6169,6176,6183,6191],{"type":29,"tag":127,"props":5802,"children":5803},{"class":677,"line":678},[5804],{"type":29,"tag":127,"props":5805,"children":5806},{"style":688},[5807],{"type":56,"value":1985},{"type":29,"tag":127,"props":5809,"children":5810},{"class":677,"line":342},[5811,5816],{"type":29,"tag":127,"props":5812,"children":5813},{"style":1991},[5814],{"type":56,"value":5815},"  \"plugins\"",{"type":29,"tag":127,"props":5817,"children":5818},{"style":688},[5819],{"type":56,"value":2226},{"type":29,"tag":127,"props":5821,"children":5822},{"class":677,"line":706},[5823,5828],{"type":29,"tag":127,"props":5824,"children":5825},{"style":2001},[5826],{"type":56,"value":5827},"    \"@semantic-release/commit-analyzer\"",{"type":29,"tag":127,"props":5829,"children":5830},{"style":688},[5831],{"type":56,"value":2009},{"type":29,"tag":127,"props":5833,"children":5834},{"class":677,"line":726},[5835],{"type":29,"tag":127,"props":5836,"children":5837},{"style":688},[5838],{"type":56,"value":5839},"    [\n",{"type":29,"tag":127,"props":5841,"children":5842},{"class":677,"line":664},[5843,5848],{"type":29,"tag":127,"props":5844,"children":5845},{"style":2001},[5846],{"type":56,"value":5847},"      \"semantic-release-replace-plugin\"",{"type":29,"tag":127,"props":5849,"children":5850},{"style":688},[5851],{"type":56,"value":2009},{"type":29,"tag":127,"props":5853,"children":5854},{"class":677,"line":665},[5855],{"type":29,"tag":127,"props":5856,"children":5857},{"style":688},[5858],{"type":56,"value":5859},"      {\n",{"type":29,"tag":127,"props":5861,"children":5862},{"class":677,"line":666},[5863,5868],{"type":29,"tag":127,"props":5864,"children":5865},{"style":1991},[5866],{"type":56,"value":5867},"        \"replacements\"",{"type":29,"tag":127,"props":5869,"children":5870},{"style":688},[5871],{"type":56,"value":2226},{"type":29,"tag":127,"props":5873,"children":5874},{"class":677,"line":667},[5875],{"type":29,"tag":127,"props":5876,"children":5877},{"style":688},[5878],{"type":56,"value":5879},"          {\n",{"type":29,"tag":127,"props":5881,"children":5882},{"class":677,"line":668},[5883,5888,5892,5897],{"type":29,"tag":127,"props":5884,"children":5885},{"style":1991},[5886],{"type":56,"value":5887},"            \"files\"",{"type":29,"tag":127,"props":5889,"children":5890},{"style":688},[5891],{"type":56,"value":5674},{"type":29,"tag":127,"props":5893,"children":5894},{"style":2001},[5895],{"type":56,"value":5896},"\"composer.json\"",{"type":29,"tag":127,"props":5898,"children":5899},{"style":688},[5900],{"type":56,"value":5901},"],\n",{"type":29,"tag":127,"props":5903,"children":5904},{"class":677,"line":1329},[5905,5910,5914,5919,5924,5928,5932,5937,5941,5945],{"type":29,"tag":127,"props":5906,"children":5907},{"style":1991},[5908],{"type":56,"value":5909},"            \"from\"",{"type":29,"tag":127,"props":5911,"children":5912},{"style":688},[5913],{"type":56,"value":717},{"type":29,"tag":127,"props":5915,"children":5916},{"style":2001},[5917],{"type":56,"value":5918},"\"version",{"type":29,"tag":127,"props":5920,"children":5921},{"style":2303},[5922],{"type":56,"value":5923},"\\\"",{"type":29,"tag":127,"props":5925,"children":5926},{"style":2001},[5927],{"type":56,"value":717},{"type":29,"tag":127,"props":5929,"children":5930},{"style":2303},[5931],{"type":56,"value":5923},{"type":29,"tag":127,"props":5933,"children":5934},{"style":2001},[5935],{"type":56,"value":5936},".*",{"type":29,"tag":127,"props":5938,"children":5939},{"style":2303},[5940],{"type":56,"value":5923},{"type":29,"tag":127,"props":5942,"children":5943},{"style":2001},[5944],{"type":56,"value":2611},{"type":29,"tag":127,"props":5946,"children":5947},{"style":688},[5948],{"type":56,"value":2009},{"type":29,"tag":127,"props":5950,"children":5951},{"class":677,"line":1342},[5952,5957,5961,5965,5969,5973,5977,5982,5986],{"type":29,"tag":127,"props":5953,"children":5954},{"style":1991},[5955],{"type":56,"value":5956},"            \"to\"",{"type":29,"tag":127,"props":5958,"children":5959},{"style":688},[5960],{"type":56,"value":717},{"type":29,"tag":127,"props":5962,"children":5963},{"style":2001},[5964],{"type":56,"value":5918},{"type":29,"tag":127,"props":5966,"children":5967},{"style":2303},[5968],{"type":56,"value":5923},{"type":29,"tag":127,"props":5970,"children":5971},{"style":2001},[5972],{"type":56,"value":717},{"type":29,"tag":127,"props":5974,"children":5975},{"style":2303},[5976],{"type":56,"value":5923},{"type":29,"tag":127,"props":5978,"children":5979},{"style":2001},[5980],{"type":56,"value":5981},"${nextRelease.version}",{"type":29,"tag":127,"props":5983,"children":5984},{"style":2303},[5985],{"type":56,"value":5923},{"type":29,"tag":127,"props":5987,"children":5988},{"style":2001},[5989],{"type":56,"value":5990},"\"\n",{"type":29,"tag":127,"props":5992,"children":5993},{"class":677,"line":118},[5994],{"type":29,"tag":127,"props":5995,"children":5996},{"style":688},[5997],{"type":56,"value":5998},"          }\n",{"type":29,"tag":127,"props":6000,"children":6001},{"class":677,"line":1367},[6002],{"type":29,"tag":127,"props":6003,"children":6004},{"style":688},[6005],{"type":56,"value":6006},"        ]\n",{"type":29,"tag":127,"props":6008,"children":6009},{"class":677,"line":1380},[6010],{"type":29,"tag":127,"props":6011,"children":6012},{"style":688},[6013],{"type":56,"value":2314},{"type":29,"tag":127,"props":6015,"children":6016},{"class":677,"line":1393},[6017],{"type":29,"tag":127,"props":6018,"children":6019},{"style":688},[6020],{"type":56,"value":2858},{"type":29,"tag":127,"props":6022,"children":6023},{"class":677,"line":1402},[6024],{"type":29,"tag":127,"props":6025,"children":6026},{"style":688},[6027],{"type":56,"value":5839},{"type":29,"tag":127,"props":6029,"children":6030},{"class":677,"line":1415},[6031,6036],{"type":29,"tag":127,"props":6032,"children":6033},{"style":2001},[6034],{"type":56,"value":6035},"      \"@semantic-release/git\"",{"type":29,"tag":127,"props":6037,"children":6038},{"style":688},[6039],{"type":56,"value":2009},{"type":29,"tag":127,"props":6041,"children":6042},{"class":677,"line":1428},[6043],{"type":29,"tag":127,"props":6044,"children":6045},{"style":688},[6046],{"type":56,"value":5859},{"type":29,"tag":127,"props":6048,"children":6049},{"class":677,"line":1437},[6050,6055,6059,6063],{"type":29,"tag":127,"props":6051,"children":6052},{"style":1991},[6053],{"type":56,"value":6054},"        \"assets\"",{"type":29,"tag":127,"props":6056,"children":6057},{"style":688},[6058],{"type":56,"value":5674},{"type":29,"tag":127,"props":6060,"children":6061},{"style":2001},[6062],{"type":56,"value":5896},{"type":29,"tag":127,"props":6064,"children":6065},{"style":688},[6066],{"type":56,"value":5901},{"type":29,"tag":127,"props":6068,"children":6069},{"class":677,"line":1450},[6070,6075,6079,6084,6089],{"type":29,"tag":127,"props":6071,"children":6072},{"style":1991},[6073],{"type":56,"value":6074},"        \"message\"",{"type":29,"tag":127,"props":6076,"children":6077},{"style":688},[6078],{"type":56,"value":717},{"type":29,"tag":127,"props":6080,"children":6081},{"style":2001},[6082],{"type":56,"value":6083},"\"chore(release): ${nextRelease.version} [skip ci]",{"type":29,"tag":127,"props":6085,"children":6086},{"style":2303},[6087],{"type":56,"value":6088},"\\n\\n",{"type":29,"tag":127,"props":6090,"children":6091},{"style":2001},[6092],{"type":56,"value":6093},"${nextRelease.notes}\"\n",{"type":29,"tag":127,"props":6095,"children":6096},{"class":677,"line":1463},[6097],{"type":29,"tag":127,"props":6098,"children":6099},{"style":688},[6100],{"type":56,"value":2314},{"type":29,"tag":127,"props":6102,"children":6103},{"class":677,"line":1476},[6104],{"type":29,"tag":127,"props":6105,"children":6106},{"style":688},[6107],{"type":56,"value":2858},{"type":29,"tag":127,"props":6109,"children":6110},{"class":677,"line":1484},[6111],{"type":29,"tag":127,"props":6112,"children":6113},{"style":688},[6114],{"type":56,"value":5839},{"type":29,"tag":127,"props":6116,"children":6117},{"class":677,"line":1497},[6118,6123],{"type":29,"tag":127,"props":6119,"children":6120},{"style":2001},[6121],{"type":56,"value":6122},"      \"@semantic-release/exec\"",{"type":29,"tag":127,"props":6124,"children":6125},{"style":688},[6126],{"type":56,"value":2009},{"type":29,"tag":127,"props":6128,"children":6129},{"class":677,"line":1510},[6130],{"type":29,"tag":127,"props":6131,"children":6132},{"style":688},[6133],{"type":56,"value":5859},{"type":29,"tag":127,"props":6135,"children":6136},{"class":677,"line":1523},[6137,6142,6146,6151,6155,6160,6164],{"type":29,"tag":127,"props":6138,"children":6139},{"style":1991},[6140],{"type":56,"value":6141},"        \"publishCmd\"",{"type":29,"tag":127,"props":6143,"children":6144},{"style":688},[6145],{"type":56,"value":717},{"type":29,"tag":127,"props":6147,"children":6148},{"style":2001},[6149],{"type":56,"value":6150},"\"curl --fail-with-body --header ",{"type":29,"tag":127,"props":6152,"children":6153},{"style":2303},[6154],{"type":56,"value":5923},{"type":29,"tag":127,"props":6156,"children":6157},{"style":2001},[6158],{"type":56,"value":6159},"Job-Token: ${process.env.CI_JOB_TOKEN}",{"type":29,"tag":127,"props":6161,"children":6162},{"style":2303},[6163],{"type":56,"value":5923},{"type":29,"tag":127,"props":6165,"children":6166},{"style":2001},[6167],{"type":56,"value":6168}," --data tag=${nextRelease.gitTag} ${process.env.CI_API_V4_URL}/projects/${process.env.CI_PROJECT_ID}/packages/composer\"\n",{"type":29,"tag":127,"props":6170,"children":6171},{"class":677,"line":1536},[6172],{"type":29,"tag":127,"props":6173,"children":6174},{"style":688},[6175],{"type":56,"value":2314},{"type":29,"tag":127,"props":6177,"children":6178},{"class":677,"line":1549},[6179],{"type":29,"tag":127,"props":6180,"children":6181},{"style":688},[6182],{"type":56,"value":2888},{"type":29,"tag":127,"props":6184,"children":6185},{"class":677,"line":2411},[6186],{"type":29,"tag":127,"props":6187,"children":6188},{"style":688},[6189],{"type":56,"value":6190},"  ]\n",{"type":29,"tag":127,"props":6192,"children":6193},{"class":677,"line":2419},[6194],{"type":29,"tag":127,"props":6195,"children":6196},{"style":688},[6197],{"type":56,"value":3013},{"type":29,"tag":48,"props":6199,"children":6200},{},[6201],{"type":56,"value":6202},"Dies wird:",{"type":29,"tag":965,"props":6204,"children":6205},{},[6206,6211,6223,6235,6240],{"type":29,"tag":814,"props":6207,"children":6208},{},[6209],{"type":56,"value":6210},"Die Commits seit dem letzten Release analysieren, um zu entscheiden, ob eine neue Version veröffentlicht werden soll",{"type":29,"tag":814,"props":6212,"children":6213},{},[6214,6216,6221],{"type":56,"value":6215},"Die Version in der ",{"type":29,"tag":672,"props":6217,"children":6219},{"className":6218},[],[6220],{"type":56,"value":3283},{"type":56,"value":6222}," aktualisieren",{"type":29,"tag":814,"props":6224,"children":6225},{},[6226,6228,6233],{"type":56,"value":6227},"Die ",{"type":29,"tag":672,"props":6229,"children":6231},{"className":6230},[],[6232],{"type":56,"value":3283},{"type":56,"value":6234}," zurück in das Repository committen",{"type":29,"tag":814,"props":6236,"children":6237},{},[6238],{"type":56,"value":6239},"Einen Tag erstellen",{"type":29,"tag":814,"props":6241,"children":6242},{},[6243],{"type":56,"value":6244},"Ein Composer-Paket von diesem Tag releasen",{"type":29,"tag":1838,"props":6246,"children":6247},{},[6248],{"type":56,"value":1842},{"title":7,"searchDepth":342,"depth":342,"links":6250},[6251,6257],{"id":1936,"depth":342,"text":1939,"children":6252},[6253,6254,6255,6256],{"id":1947,"depth":706,"text":1950},{"id":3249,"depth":706,"text":3252},{"id":3911,"depth":706,"text":3914},{"id":5263,"depth":706,"text":5266},{"id":5296,"depth":342,"text":5299,"children":6258},[6259,6260],{"id":5302,"depth":706,"text":5305},{"id":5537,"depth":706,"text":5540},{"_path":543,"_dir":515,"_draft":6,"_partial":6,"_locale":7,"title":544,"description":545,"author":518,"image":519,"releaseDate":533,"blogCategories":6262,"articleTags":6263,"tags":6264,"body":6265,"_type":346,"_id":549,"_source":348,"_file":550,"_stem":551,"_extension":351},[522,523],[523,536,537],[461,24],{"type":26,"children":6266,"toc":7337},[6267,6271,6282,6294,6300,6305,6334,6339,6344,6362,6373,6378,6399,6405,6425,6744,6755,6760,7302,7311,7315,7333],{"type":29,"tag":61,"props":6268,"children":6270},{"alt":7,"aspect-ratio":1861,"height":1862,"object-fit":1863,"src":6269},"/blog/shopware-plugin-build+release.png",[],{"type":29,"tag":48,"props":6272,"children":6273},{},[6274,6275,6280],{"type":56,"value":894},{"type":29,"tag":645,"props":6276,"children":6277},{"href":530},[6278],{"type":56,"value":6279},"vorherigen Post",{"type":56,"value":6281}," habe ich beschrieben, wie man ein Shopware 6 Plugin über die GitLab Package Registry ausliefert.",{"type":29,"tag":48,"props":6283,"children":6284},{},[6285,6287,6292],{"type":56,"value":6286},"Wenn wir unser Projekt mit dem ",{"type":29,"tag":645,"props":6288,"children":6290},{"href":6289},"https://developer.shopware.com/docs/products/cli/extension-commands/build.html#building-an-extension",[6291],{"type":56,"value":1928},{"type":56,"value":6293}," bauen,\nsucht das Tool in allen Plugins und prüft, ob sie gebaut werden müssen, und tut dies gegebenenfalls. Dies ist ein unnötiger Schritt.",{"type":29,"tag":90,"props":6295,"children":6297},{"id":6296},"manuelles-bauen",[6298],{"type":56,"value":6299},"Manuelles Bauen",{"type":29,"tag":48,"props":6301,"children":6302},{},[6303],{"type":56,"value":6304},"Das Bauen eines Plugins ist so einfach wie das Ausführen von:",{"type":29,"tag":659,"props":6306,"children":6308},{"className":3021,"code":6307,"language":3023,"meta":7,"style":7},"shopware-cli extension build .\n",[6309],{"type":29,"tag":672,"props":6310,"children":6311},{"__ignoreMap":7},[6312],{"type":29,"tag":127,"props":6313,"children":6314},{"class":677,"line":678},[6315,6319,6324,6329],{"type":29,"tag":127,"props":6316,"children":6317},{"style":3033},[6318],{"type":56,"value":1928},{"type":29,"tag":127,"props":6320,"children":6321},{"style":720},[6322],{"type":56,"value":6323}," extension",{"type":29,"tag":127,"props":6325,"children":6326},{"style":720},[6327],{"type":56,"value":6328}," build",{"type":29,"tag":127,"props":6330,"children":6331},{"style":720},[6332],{"type":56,"value":6333}," .\n",{"type":29,"tag":48,"props":6335,"children":6336},{},[6337],{"type":56,"value":6338},"Im Plugin-Root-Verzeichnis.",{"type":29,"tag":48,"props":6340,"children":6341},{},[6342],{"type":56,"value":6343},"Es gibt einige Anpassungen, die Sie vornehmen können, wie zum Beispiel:",{"type":29,"tag":810,"props":6345,"children":6346},{},[6347,6352,6357],{"type":29,"tag":814,"props":6348,"children":6349},{},[6350],{"type":56,"value":6351},"Einschränkung einer Shopware-Version",{"type":29,"tag":814,"props":6353,"children":6354},{},[6355],{"type":56,"value":6356},"Angabe zusätzlicher Bundles",{"type":29,"tag":814,"props":6358,"children":6359},{},[6360],{"type":56,"value":6361},"Verwendung von esbuild",{"type":29,"tag":48,"props":6363,"children":6364},{},[6365,6367,6372],{"type":56,"value":6366},"Detaillierte Konfigurationen finden Sie in der ",{"type":29,"tag":645,"props":6368,"children":6370},{"href":6369},"https://developer.shopware.com/docs/products/cli/extension-commands/build.html",[6371],{"type":56,"value":1881},{"type":56,"value":1651},{"type":29,"tag":48,"props":6374,"children":6375},{},[6376],{"type":56,"value":6377},"Der Build-Prozess erstellt die folgenden Verzeichnisse, die die kompilierten Dateien enthalten:",{"type":29,"tag":810,"props":6379,"children":6380},{},[6381,6390],{"type":29,"tag":814,"props":6382,"children":6383},{},[6384],{"type":29,"tag":672,"props":6385,"children":6387},{"className":6386},[],[6388],{"type":56,"value":6389},"src/Resources/app/storefront/dist/",{"type":29,"tag":814,"props":6391,"children":6392},{},[6393],{"type":29,"tag":672,"props":6394,"children":6396},{"className":6395},[],[6397],{"type":56,"value":6398},"src/Resources/public/static/",{"type":29,"tag":90,"props":6400,"children":6402},{"id":6401},"build-pipeline",[6403],{"type":56,"value":6404},"Build-Pipeline",{"type":29,"tag":48,"props":6406,"children":6407},{},[6408,6410,6415,6417,6423],{"type":56,"value":6409},"Wir verwenden das offizielle ",{"type":29,"tag":672,"props":6411,"children":6413},{"className":6412},[],[6414],{"type":56,"value":1928},{"type":56,"value":6416}," Docker-Image. Um den Prozess zu beschleunigen, nutzen wir das ",{"type":29,"tag":672,"props":6418,"children":6420},{"className":6419},[],[6421],{"type":56,"value":6422},"CI",{"type":56,"value":6424},"-Caching-System.",{"type":29,"tag":659,"props":6426,"children":6429},{"className":669,"code":6427,"filename":5573,"highlights":6428,"language":508,"meta":7,"style":7},"stages:\n  - build\n\nbuild:\n  image:\n    name: ghcr.io/shopware/shopware-cli:latest-php-8.2\n    entrypoint: [\"\"]\n  stage: build\n  variables:\n    COMPOSER_CACHE_DIR: ${CI_PROJECT_DIR}/.composer\n    npm_config_cache: ${CI_PROJECT_DIR}/.npm\n  script:\n    - shopware-cli extension build .\n  cache:\n    - key: $CI_JOB_NAME\n      paths:\n        - $COMPOSER_CACHE_DIR\n        - $npm_config_cache\n  rules:\n    - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH\n      when: never\n    - if: $CI_COMMIT_BRANCH\n",[665,1380,1393,1402,1415,1428],[6430],{"type":29,"tag":672,"props":6431,"children":6432},{"__ignoreMap":7},[6433,6444,6456,6463,6475,6486,6503,6522,6537,6549,6566,6583,6594,6605,6618,6640,6653,6667,6680,6691,6710,6725],{"type":29,"tag":127,"props":6434,"children":6435},{"class":677,"line":678},[6436,6440],{"type":29,"tag":127,"props":6437,"children":6438},{"style":682},[6439],{"type":56,"value":5394},{"type":29,"tag":127,"props":6441,"children":6442},{"style":688},[6443],{"type":56,"value":691},{"type":29,"tag":127,"props":6445,"children":6446},{"class":677,"line":342},[6447,6451],{"type":29,"tag":127,"props":6448,"children":6449},{"style":688},[6450],{"type":56,"value":5406},{"type":29,"tag":127,"props":6452,"children":6453},{"style":720},[6454],{"type":56,"value":6455},"build\n",{"type":29,"tag":127,"props":6457,"children":6458},{"class":677,"line":706},[6459],{"type":29,"tag":127,"props":6460,"children":6461},{"emptyLinePlaceholder":500},[6462],{"type":56,"value":1399},{"type":29,"tag":127,"props":6464,"children":6465},{"class":677,"line":726},[6466,6471],{"type":29,"tag":127,"props":6467,"children":6468},{"style":682},[6469],{"type":56,"value":6470},"build",{"type":29,"tag":127,"props":6472,"children":6473},{"style":688},[6474],{"type":56,"value":691},{"type":29,"tag":127,"props":6476,"children":6477},{"class":677,"line":664},[6478,6482],{"type":29,"tag":127,"props":6479,"children":6480},{"style":682},[6481],{"type":56,"value":5438},{"type":29,"tag":127,"props":6483,"children":6484},{"style":688},[6485],{"type":56,"value":691},{"type":29,"tag":127,"props":6487,"children":6489},{"class":6488,"line":665},[677,740],[6490,6494,6498],{"type":29,"tag":127,"props":6491,"children":6492},{"style":682},[6493],{"type":56,"value":5652},{"type":29,"tag":127,"props":6495,"children":6496},{"style":688},[6497],{"type":56,"value":717},{"type":29,"tag":127,"props":6499,"children":6500},{"style":720},[6501],{"type":56,"value":6502},"ghcr.io/shopware/shopware-cli:latest-php-8.2\n",{"type":29,"tag":127,"props":6504,"children":6505},{"class":677,"line":666},[6506,6510,6514,6518],{"type":29,"tag":127,"props":6507,"children":6508},{"style":682},[6509],{"type":56,"value":5669},{"type":29,"tag":127,"props":6511,"children":6512},{"style":688},[6513],{"type":56,"value":5674},{"type":29,"tag":127,"props":6515,"children":6516},{"style":720},[6517],{"type":56,"value":5679},{"type":29,"tag":127,"props":6519,"children":6520},{"style":688},[6521],{"type":56,"value":5684},{"type":29,"tag":127,"props":6523,"children":6524},{"class":677,"line":667},[6525,6529,6533],{"type":29,"tag":127,"props":6526,"children":6527},{"style":682},[6528],{"type":56,"value":5455},{"type":29,"tag":127,"props":6530,"children":6531},{"style":688},[6532],{"type":56,"value":717},{"type":29,"tag":127,"props":6534,"children":6535},{"style":720},[6536],{"type":56,"value":6455},{"type":29,"tag":127,"props":6538,"children":6539},{"class":677,"line":668},[6540,6545],{"type":29,"tag":127,"props":6541,"children":6542},{"style":682},[6543],{"type":56,"value":6544},"  variables",{"type":29,"tag":127,"props":6546,"children":6547},{"style":688},[6548],{"type":56,"value":691},{"type":29,"tag":127,"props":6550,"children":6551},{"class":677,"line":1329},[6552,6557,6561],{"type":29,"tag":127,"props":6553,"children":6554},{"style":682},[6555],{"type":56,"value":6556},"    COMPOSER_CACHE_DIR",{"type":29,"tag":127,"props":6558,"children":6559},{"style":688},[6560],{"type":56,"value":717},{"type":29,"tag":127,"props":6562,"children":6563},{"style":720},[6564],{"type":56,"value":6565},"${CI_PROJECT_DIR}/.composer\n",{"type":29,"tag":127,"props":6567,"children":6568},{"class":677,"line":1342},[6569,6574,6578],{"type":29,"tag":127,"props":6570,"children":6571},{"style":682},[6572],{"type":56,"value":6573},"    npm_config_cache",{"type":29,"tag":127,"props":6575,"children":6576},{"style":688},[6577],{"type":56,"value":717},{"type":29,"tag":127,"props":6579,"children":6580},{"style":720},[6581],{"type":56,"value":6582},"${CI_PROJECT_DIR}/.npm\n",{"type":29,"tag":127,"props":6584,"children":6585},{"class":677,"line":118},[6586,6590],{"type":29,"tag":127,"props":6587,"children":6588},{"style":682},[6589],{"type":56,"value":5471},{"type":29,"tag":127,"props":6591,"children":6592},{"style":688},[6593],{"type":56,"value":691},{"type":29,"tag":127,"props":6595,"children":6596},{"class":677,"line":1367},[6597,6601],{"type":29,"tag":127,"props":6598,"children":6599},{"style":688},[6600],{"type":56,"value":5483},{"type":29,"tag":127,"props":6602,"children":6603},{"style":720},[6604],{"type":56,"value":6307},{"type":29,"tag":127,"props":6606,"children":6608},{"class":6607,"line":1380},[677,740],[6609,6614],{"type":29,"tag":127,"props":6610,"children":6611},{"style":682},[6612],{"type":56,"value":6613},"  cache",{"type":29,"tag":127,"props":6615,"children":6616},{"style":688},[6617],{"type":56,"value":691},{"type":29,"tag":127,"props":6619,"children":6621},{"class":6620,"line":1393},[677,740],[6622,6626,6631,6635],{"type":29,"tag":127,"props":6623,"children":6624},{"style":688},[6625],{"type":56,"value":5483},{"type":29,"tag":127,"props":6627,"children":6628},{"style":682},[6629],{"type":56,"value":6630},"key",{"type":29,"tag":127,"props":6632,"children":6633},{"style":688},[6634],{"type":56,"value":717},{"type":29,"tag":127,"props":6636,"children":6637},{"style":720},[6638],{"type":56,"value":6639},"$CI_JOB_NAME\n",{"type":29,"tag":127,"props":6641,"children":6643},{"class":6642,"line":1402},[677,740],[6644,6649],{"type":29,"tag":127,"props":6645,"children":6646},{"style":682},[6647],{"type":56,"value":6648},"      paths",{"type":29,"tag":127,"props":6650,"children":6651},{"style":688},[6652],{"type":56,"value":691},{"type":29,"tag":127,"props":6654,"children":6656},{"class":6655,"line":1415},[677,740],[6657,6662],{"type":29,"tag":127,"props":6658,"children":6659},{"style":688},[6660],{"type":56,"value":6661},"        - ",{"type":29,"tag":127,"props":6663,"children":6664},{"style":720},[6665],{"type":56,"value":6666},"$COMPOSER_CACHE_DIR\n",{"type":29,"tag":127,"props":6668,"children":6670},{"class":6669,"line":1428},[677,740],[6671,6675],{"type":29,"tag":127,"props":6672,"children":6673},{"style":688},[6674],{"type":56,"value":6661},{"type":29,"tag":127,"props":6676,"children":6677},{"style":720},[6678],{"type":56,"value":6679},"$npm_config_cache\n",{"type":29,"tag":127,"props":6681,"children":6682},{"class":677,"line":1437},[6683,6687],{"type":29,"tag":127,"props":6684,"children":6685},{"style":682},[6686],{"type":56,"value":5513},{"type":29,"tag":127,"props":6688,"children":6689},{"style":688},[6690],{"type":56,"value":691},{"type":29,"tag":127,"props":6692,"children":6693},{"class":677,"line":1450},[6694,6698,6702,6706],{"type":29,"tag":127,"props":6695,"children":6696},{"style":688},[6697],{"type":56,"value":5483},{"type":29,"tag":127,"props":6699,"children":6700},{"style":682},[6701],{"type":56,"value":5746},{"type":29,"tag":127,"props":6703,"children":6704},{"style":688},[6705],{"type":56,"value":717},{"type":29,"tag":127,"props":6707,"children":6708},{"style":720},[6709],{"type":56,"value":5755},{"type":29,"tag":127,"props":6711,"children":6712},{"class":677,"line":1463},[6713,6717,6721],{"type":29,"tag":127,"props":6714,"children":6715},{"style":682},[6716],{"type":56,"value":5763},{"type":29,"tag":127,"props":6718,"children":6719},{"style":688},[6720],{"type":56,"value":717},{"type":29,"tag":127,"props":6722,"children":6723},{"style":720},[6724],{"type":56,"value":5772},{"type":29,"tag":127,"props":6726,"children":6727},{"class":677,"line":1476},[6728,6732,6736,6740],{"type":29,"tag":127,"props":6729,"children":6730},{"style":688},[6731],{"type":56,"value":5483},{"type":29,"tag":127,"props":6733,"children":6734},{"style":682},[6735],{"type":56,"value":5746},{"type":29,"tag":127,"props":6737,"children":6738},{"style":688},[6739],{"type":56,"value":717},{"type":29,"tag":127,"props":6741,"children":6742},{"style":720},[6743],{"type":56,"value":5792},{"type":29,"tag":48,"props":6745,"children":6746},{},[6747,6749,6754],{"type":56,"value":6748},"Kombinieren wir dies mit unserer Release-Pipeline aus dem ",{"type":29,"tag":645,"props":6750,"children":6752},{"href":6751},"/blog/shopware-plugin-gitlab-pipeline-release#mit-semantic-release",[6753],{"type":56,"value":6279},{"type":56,"value":1651},{"type":29,"tag":48,"props":6756,"children":6757},{},[6758],{"type":56,"value":6759},"Es ist wichtig, die gebauten Artefakte an den nächsten Job zu übergeben.",{"type":29,"tag":659,"props":6761,"children":6764},{"className":669,"code":6762,"filename":5573,"highlights":6763,"language":508,"meta":7,"style":7},"stages:\n  - release\n  - build\n\nbuild:\n  image:\n    name: ghcr.io/shopware/shopware-cli:latest-php-8.2\n    entrypoint: [\"\"]\n  stage: build\n  variables:\n    COMPOSER_CACHE_DIR: ${CI_PROJECT_DIR}/.composer\n    npm_config_cache: ${CI_PROJECT_DIR}/.npm\n  script:\n    - shopware-cli extension build .\n  cache:\n    - key: $CI_JOB_NAME\n      paths:\n        - $COMPOSER_CACHE_DIR\n        - $npm_config_cache\n  artifacts:\n    paths:\n      - src/Resources/public\n      - src/Storefront/Resources/public\n  rules:\n    - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH\n      when: never\n    - if: $CI_COMMIT_BRANCH\n\nrelease:\n  stage: release\n  image:\n    name: ghcr.io/voxpupuli/semantic-release:latest\n    entrypoint: [\"\"]\n  interruptible: true\n  script:\n    - /docker-entrypoint.sh\n  rules:\n    - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH\n      when: never\n    - if: $CI_COMMIT_BRANCH\n",[1450,1463,1476,1484],[6765],{"type":29,"tag":672,"props":6766,"children":6767},{"__ignoreMap":7},[6768,6779,6790,6801,6808,6819,6830,6845,6864,6879,6890,6905,6920,6931,6942,6953,6972,6983,6994,7005,7018,7031,7044,7057,7068,7087,7102,7121,7128,7139,7154,7165,7181,7200,7215,7226,7238,7249,7268,7283],{"type":29,"tag":127,"props":6769,"children":6770},{"class":677,"line":678},[6771,6775],{"type":29,"tag":127,"props":6772,"children":6773},{"style":682},[6774],{"type":56,"value":5394},{"type":29,"tag":127,"props":6776,"children":6777},{"style":688},[6778],{"type":56,"value":691},{"type":29,"tag":127,"props":6780,"children":6781},{"class":677,"line":342},[6782,6786],{"type":29,"tag":127,"props":6783,"children":6784},{"style":688},[6785],{"type":56,"value":5406},{"type":29,"tag":127,"props":6787,"children":6788},{"style":720},[6789],{"type":56,"value":5411},{"type":29,"tag":127,"props":6791,"children":6792},{"class":677,"line":706},[6793,6797],{"type":29,"tag":127,"props":6794,"children":6795},{"style":688},[6796],{"type":56,"value":5406},{"type":29,"tag":127,"props":6798,"children":6799},{"style":720},[6800],{"type":56,"value":6455},{"type":29,"tag":127,"props":6802,"children":6803},{"class":677,"line":726},[6804],{"type":29,"tag":127,"props":6805,"children":6806},{"emptyLinePlaceholder":500},[6807],{"type":56,"value":1399},{"type":29,"tag":127,"props":6809,"children":6810},{"class":677,"line":664},[6811,6815],{"type":29,"tag":127,"props":6812,"children":6813},{"style":682},[6814],{"type":56,"value":6470},{"type":29,"tag":127,"props":6816,"children":6817},{"style":688},[6818],{"type":56,"value":691},{"type":29,"tag":127,"props":6820,"children":6821},{"class":677,"line":665},[6822,6826],{"type":29,"tag":127,"props":6823,"children":6824},{"style":682},[6825],{"type":56,"value":5438},{"type":29,"tag":127,"props":6827,"children":6828},{"style":688},[6829],{"type":56,"value":691},{"type":29,"tag":127,"props":6831,"children":6832},{"class":677,"line":666},[6833,6837,6841],{"type":29,"tag":127,"props":6834,"children":6835},{"style":682},[6836],{"type":56,"value":5652},{"type":29,"tag":127,"props":6838,"children":6839},{"style":688},[6840],{"type":56,"value":717},{"type":29,"tag":127,"props":6842,"children":6843},{"style":720},[6844],{"type":56,"value":6502},{"type":29,"tag":127,"props":6846,"children":6847},{"class":677,"line":667},[6848,6852,6856,6860],{"type":29,"tag":127,"props":6849,"children":6850},{"style":682},[6851],{"type":56,"value":5669},{"type":29,"tag":127,"props":6853,"children":6854},{"style":688},[6855],{"type":56,"value":5674},{"type":29,"tag":127,"props":6857,"children":6858},{"style":720},[6859],{"type":56,"value":5679},{"type":29,"tag":127,"props":6861,"children":6862},{"style":688},[6863],{"type":56,"value":5684},{"type":29,"tag":127,"props":6865,"children":6866},{"class":677,"line":668},[6867,6871,6875],{"type":29,"tag":127,"props":6868,"children":6869},{"style":682},[6870],{"type":56,"value":5455},{"type":29,"tag":127,"props":6872,"children":6873},{"style":688},[6874],{"type":56,"value":717},{"type":29,"tag":127,"props":6876,"children":6877},{"style":720},[6878],{"type":56,"value":6455},{"type":29,"tag":127,"props":6880,"children":6881},{"class":677,"line":1329},[6882,6886],{"type":29,"tag":127,"props":6883,"children":6884},{"style":682},[6885],{"type":56,"value":6544},{"type":29,"tag":127,"props":6887,"children":6888},{"style":688},[6889],{"type":56,"value":691},{"type":29,"tag":127,"props":6891,"children":6892},{"class":677,"line":1342},[6893,6897,6901],{"type":29,"tag":127,"props":6894,"children":6895},{"style":682},[6896],{"type":56,"value":6556},{"type":29,"tag":127,"props":6898,"children":6899},{"style":688},[6900],{"type":56,"value":717},{"type":29,"tag":127,"props":6902,"children":6903},{"style":720},[6904],{"type":56,"value":6565},{"type":29,"tag":127,"props":6906,"children":6907},{"class":677,"line":118},[6908,6912,6916],{"type":29,"tag":127,"props":6909,"children":6910},{"style":682},[6911],{"type":56,"value":6573},{"type":29,"tag":127,"props":6913,"children":6914},{"style":688},[6915],{"type":56,"value":717},{"type":29,"tag":127,"props":6917,"children":6918},{"style":720},[6919],{"type":56,"value":6582},{"type":29,"tag":127,"props":6921,"children":6922},{"class":677,"line":1367},[6923,6927],{"type":29,"tag":127,"props":6924,"children":6925},{"style":682},[6926],{"type":56,"value":5471},{"type":29,"tag":127,"props":6928,"children":6929},{"style":688},[6930],{"type":56,"value":691},{"type":29,"tag":127,"props":6932,"children":6933},{"class":677,"line":1380},[6934,6938],{"type":29,"tag":127,"props":6935,"children":6936},{"style":688},[6937],{"type":56,"value":5483},{"type":29,"tag":127,"props":6939,"children":6940},{"style":720},[6941],{"type":56,"value":6307},{"type":29,"tag":127,"props":6943,"children":6944},{"class":677,"line":1393},[6945,6949],{"type":29,"tag":127,"props":6946,"children":6947},{"style":682},[6948],{"type":56,"value":6613},{"type":29,"tag":127,"props":6950,"children":6951},{"style":688},[6952],{"type":56,"value":691},{"type":29,"tag":127,"props":6954,"children":6955},{"class":677,"line":1402},[6956,6960,6964,6968],{"type":29,"tag":127,"props":6957,"children":6958},{"style":688},[6959],{"type":56,"value":5483},{"type":29,"tag":127,"props":6961,"children":6962},{"style":682},[6963],{"type":56,"value":6630},{"type":29,"tag":127,"props":6965,"children":6966},{"style":688},[6967],{"type":56,"value":717},{"type":29,"tag":127,"props":6969,"children":6970},{"style":720},[6971],{"type":56,"value":6639},{"type":29,"tag":127,"props":6973,"children":6974},{"class":677,"line":1415},[6975,6979],{"type":29,"tag":127,"props":6976,"children":6977},{"style":682},[6978],{"type":56,"value":6648},{"type":29,"tag":127,"props":6980,"children":6981},{"style":688},[6982],{"type":56,"value":691},{"type":29,"tag":127,"props":6984,"children":6985},{"class":677,"line":1428},[6986,6990],{"type":29,"tag":127,"props":6987,"children":6988},{"style":688},[6989],{"type":56,"value":6661},{"type":29,"tag":127,"props":6991,"children":6992},{"style":720},[6993],{"type":56,"value":6666},{"type":29,"tag":127,"props":6995,"children":6996},{"class":677,"line":1437},[6997,7001],{"type":29,"tag":127,"props":6998,"children":6999},{"style":688},[7000],{"type":56,"value":6661},{"type":29,"tag":127,"props":7002,"children":7003},{"style":720},[7004],{"type":56,"value":6679},{"type":29,"tag":127,"props":7006,"children":7008},{"class":7007,"line":1450},[677,740],[7009,7014],{"type":29,"tag":127,"props":7010,"children":7011},{"style":682},[7012],{"type":56,"value":7013},"  artifacts",{"type":29,"tag":127,"props":7015,"children":7016},{"style":688},[7017],{"type":56,"value":691},{"type":29,"tag":127,"props":7019,"children":7021},{"class":7020,"line":1463},[677,740],[7022,7027],{"type":29,"tag":127,"props":7023,"children":7024},{"style":682},[7025],{"type":56,"value":7026},"    paths",{"type":29,"tag":127,"props":7028,"children":7029},{"style":688},[7030],{"type":56,"value":691},{"type":29,"tag":127,"props":7032,"children":7034},{"class":7033,"line":1476},[677,740],[7035,7039],{"type":29,"tag":127,"props":7036,"children":7037},{"style":688},[7038],{"type":56,"value":746},{"type":29,"tag":127,"props":7040,"children":7041},{"style":720},[7042],{"type":56,"value":7043},"src/Resources/public\n",{"type":29,"tag":127,"props":7045,"children":7047},{"class":7046,"line":1484},[677,740],[7048,7052],{"type":29,"tag":127,"props":7049,"children":7050},{"style":688},[7051],{"type":56,"value":746},{"type":29,"tag":127,"props":7053,"children":7054},{"style":720},[7055],{"type":56,"value":7056},"src/Storefront/Resources/public\n",{"type":29,"tag":127,"props":7058,"children":7059},{"class":677,"line":1497},[7060,7064],{"type":29,"tag":127,"props":7061,"children":7062},{"style":682},[7063],{"type":56,"value":5513},{"type":29,"tag":127,"props":7065,"children":7066},{"style":688},[7067],{"type":56,"value":691},{"type":29,"tag":127,"props":7069,"children":7070},{"class":677,"line":1510},[7071,7075,7079,7083],{"type":29,"tag":127,"props":7072,"children":7073},{"style":688},[7074],{"type":56,"value":5483},{"type":29,"tag":127,"props":7076,"children":7077},{"style":682},[7078],{"type":56,"value":5746},{"type":29,"tag":127,"props":7080,"children":7081},{"style":688},[7082],{"type":56,"value":717},{"type":29,"tag":127,"props":7084,"children":7085},{"style":720},[7086],{"type":56,"value":5755},{"type":29,"tag":127,"props":7088,"children":7089},{"class":677,"line":1523},[7090,7094,7098],{"type":29,"tag":127,"props":7091,"children":7092},{"style":682},[7093],{"type":56,"value":5763},{"type":29,"tag":127,"props":7095,"children":7096},{"style":688},[7097],{"type":56,"value":717},{"type":29,"tag":127,"props":7099,"children":7100},{"style":720},[7101],{"type":56,"value":5772},{"type":29,"tag":127,"props":7103,"children":7104},{"class":677,"line":1536},[7105,7109,7113,7117],{"type":29,"tag":127,"props":7106,"children":7107},{"style":688},[7108],{"type":56,"value":5483},{"type":29,"tag":127,"props":7110,"children":7111},{"style":682},[7112],{"type":56,"value":5746},{"type":29,"tag":127,"props":7114,"children":7115},{"style":688},[7116],{"type":56,"value":717},{"type":29,"tag":127,"props":7118,"children":7119},{"style":720},[7120],{"type":56,"value":5792},{"type":29,"tag":127,"props":7122,"children":7123},{"class":677,"line":1549},[7124],{"type":29,"tag":127,"props":7125,"children":7126},{"emptyLinePlaceholder":500},[7127],{"type":56,"value":1399},{"type":29,"tag":127,"props":7129,"children":7130},{"class":677,"line":2411},[7131,7135],{"type":29,"tag":127,"props":7132,"children":7133},{"style":682},[7134],{"type":56,"value":5614},{"type":29,"tag":127,"props":7136,"children":7137},{"style":688},[7138],{"type":56,"value":691},{"type":29,"tag":127,"props":7140,"children":7141},{"class":677,"line":2419},[7142,7146,7150],{"type":29,"tag":127,"props":7143,"children":7144},{"style":682},[7145],{"type":56,"value":5455},{"type":29,"tag":127,"props":7147,"children":7148},{"style":688},[7149],{"type":56,"value":717},{"type":29,"tag":127,"props":7151,"children":7152},{"style":720},[7153],{"type":56,"value":5411},{"type":29,"tag":127,"props":7155,"children":7156},{"class":677,"line":2439},[7157,7161],{"type":29,"tag":127,"props":7158,"children":7159},{"style":682},[7160],{"type":56,"value":5438},{"type":29,"tag":127,"props":7162,"children":7163},{"style":688},[7164],{"type":56,"value":691},{"type":29,"tag":127,"props":7166,"children":7167},{"class":677,"line":2460},[7168,7172,7176],{"type":29,"tag":127,"props":7169,"children":7170},{"style":682},[7171],{"type":56,"value":5652},{"type":29,"tag":127,"props":7173,"children":7174},{"style":688},[7175],{"type":56,"value":717},{"type":29,"tag":127,"props":7177,"children":7178},{"style":720},[7179],{"type":56,"value":7180},"ghcr.io/voxpupuli/semantic-release:latest\n",{"type":29,"tag":127,"props":7182,"children":7183},{"class":677,"line":2472},[7184,7188,7192,7196],{"type":29,"tag":127,"props":7185,"children":7186},{"style":682},[7187],{"type":56,"value":5669},{"type":29,"tag":127,"props":7189,"children":7190},{"style":688},[7191],{"type":56,"value":5674},{"type":29,"tag":127,"props":7193,"children":7194},{"style":720},[7195],{"type":56,"value":5679},{"type":29,"tag":127,"props":7197,"children":7198},{"style":688},[7199],{"type":56,"value":5684},{"type":29,"tag":127,"props":7201,"children":7202},{"class":677,"line":2488},[7203,7207,7211],{"type":29,"tag":127,"props":7204,"children":7205},{"style":682},[7206],{"type":56,"value":5692},{"type":29,"tag":127,"props":7208,"children":7209},{"style":688},[7210],{"type":56,"value":717},{"type":29,"tag":127,"props":7212,"children":7213},{"style":2303},[7214],{"type":56,"value":2306},{"type":29,"tag":127,"props":7216,"children":7217},{"class":677,"line":2496},[7218,7222],{"type":29,"tag":127,"props":7219,"children":7220},{"style":682},[7221],{"type":56,"value":5471},{"type":29,"tag":127,"props":7223,"children":7224},{"style":688},[7225],{"type":56,"value":691},{"type":29,"tag":127,"props":7227,"children":7228},{"class":677,"line":1970},[7229,7233],{"type":29,"tag":127,"props":7230,"children":7231},{"style":688},[7232],{"type":56,"value":5483},{"type":29,"tag":127,"props":7234,"children":7235},{"style":720},[7236],{"type":56,"value":7237},"/docker-entrypoint.sh\n",{"type":29,"tag":127,"props":7239,"children":7240},{"class":677,"line":1971},[7241,7245],{"type":29,"tag":127,"props":7242,"children":7243},{"style":682},[7244],{"type":56,"value":5513},{"type":29,"tag":127,"props":7246,"children":7247},{"style":688},[7248],{"type":56,"value":691},{"type":29,"tag":127,"props":7250,"children":7251},{"class":677,"line":1972},[7252,7256,7260,7264],{"type":29,"tag":127,"props":7253,"children":7254},{"style":688},[7255],{"type":56,"value":5483},{"type":29,"tag":127,"props":7257,"children":7258},{"style":682},[7259],{"type":56,"value":5746},{"type":29,"tag":127,"props":7261,"children":7262},{"style":688},[7263],{"type":56,"value":717},{"type":29,"tag":127,"props":7265,"children":7266},{"style":720},[7267],{"type":56,"value":5755},{"type":29,"tag":127,"props":7269,"children":7270},{"class":677,"line":1973},[7271,7275,7279],{"type":29,"tag":127,"props":7272,"children":7273},{"style":682},[7274],{"type":56,"value":5763},{"type":29,"tag":127,"props":7276,"children":7277},{"style":688},[7278],{"type":56,"value":717},{"type":29,"tag":127,"props":7280,"children":7281},{"style":720},[7282],{"type":56,"value":5772},{"type":29,"tag":127,"props":7284,"children":7285},{"class":677,"line":2559},[7286,7290,7294,7298],{"type":29,"tag":127,"props":7287,"children":7288},{"style":688},[7289],{"type":56,"value":5483},{"type":29,"tag":127,"props":7291,"children":7292},{"style":682},[7293],{"type":56,"value":5746},{"type":29,"tag":127,"props":7295,"children":7296},{"style":688},[7297],{"type":56,"value":717},{"type":29,"tag":127,"props":7299,"children":7300},{"style":720},[7301],{"type":56,"value":5792},{"type":29,"tag":48,"props":7303,"children":7304},{},[7305],{"type":29,"tag":127,"props":7306,"children":7308},{"className":7307},[5257],[7309],{"type":56,"value":7310},"Das war's!",{"type":29,"tag":48,"props":7312,"children":7313},{},[7314],{"type":56,"value":6202},{"type":29,"tag":965,"props":7316,"children":7317},{},[7318,7323,7328],{"type":29,"tag":814,"props":7319,"children":7320},{},[7321],{"type":56,"value":7322},"Alle Assets bauen",{"type":29,"tag":814,"props":7324,"children":7325},{},[7326],{"type":56,"value":7327},"Sie an den zweiten Job übergeben",{"type":29,"tag":814,"props":7329,"children":7330},{},[7331],{"type":56,"value":7332},"Den Release-Prozess wie zuvor beschrieben ausführen",{"type":29,"tag":1838,"props":7334,"children":7335},{},[7336],{"type":56,"value":1842},{"title":7,"searchDepth":342,"depth":342,"links":7338},[7339,7340],{"id":6296,"depth":342,"text":6299},{"id":6401,"depth":342,"text":6404},{"_path":553,"_dir":515,"_draft":6,"_partial":6,"_locale":7,"title":554,"description":555,"author":518,"image":519,"releaseDate":533,"blogCategories":7342,"articleTags":7343,"tags":7344,"body":7345,"_type":346,"_id":559,"_source":348,"_file":560,"_stem":561,"_extension":351},[522,523],[523,536,537],[461,24],{"type":26,"children":7346,"toc":9617},[7347,7351,7356,7407,7413,7425,7437,7479,7492,7500,7512,7518,7523,7794,7799,7804,7809,7814,7827,7832,7857,7863,7875,8643,8648,8676,8681,8687,8692,9613],{"type":29,"tag":61,"props":7348,"children":7350},{"alt":7,"aspect-ratio":1861,"height":1862,"object-fit":1863,"src":7349},"/blog/shopware-plugin-test.png",[],{"type":29,"tag":48,"props":7352,"children":7353},{},[7354],{"type":56,"value":7355},"Wenn es um das Testen eines Shopware 6 Plugins geht, gibt es zwei Arten von Tests, die durchgeführt werden können:",{"type":29,"tag":965,"props":7357,"children":7358},{},[7359,7395],{"type":29,"tag":814,"props":7360,"children":7361},{},[7362,7364,7370,7372],{"type":56,"value":7363},"Testen des Codes selbst (",{"type":29,"tag":645,"props":7365,"children":7367},{"href":7366},"https://developer.shopware.com/docs/guides/plugins/plugins/testing/",[7368],{"type":56,"value":7369},"mehr in der offiziellen Dokumentation",{"type":56,"value":7371},")\n",{"type":29,"tag":965,"props":7373,"children":7374},{},[7375,7380,7385,7390],{"type":29,"tag":814,"props":7376,"children":7377},{},[7378],{"type":56,"value":7379},"PHP-Unit-Tests",{"type":29,"tag":814,"props":7381,"children":7382},{},[7383],{"type":56,"value":7384},"Jest-Unit-Tests in Shopwares Storefront",{"type":29,"tag":814,"props":7386,"children":7387},{},[7388],{"type":56,"value":7389},"Jest-Unit-Tests in Shopwares Administration",{"type":29,"tag":814,"props":7391,"children":7392},{},[7393],{"type":56,"value":7394},"End-to-End (E2E) Testing",{"type":29,"tag":814,"props":7396,"children":7397},{},[7398,7400,7405],{"type":56,"value":7399},"Sicherstellen einer hohen Code-Qualität (",{"type":29,"tag":645,"props":7401,"children":7403},{"href":7402},"https://developer.shopware.com/docs/products/cli/validation.html",[7404],{"type":56,"value":7369},{"type":56,"value":7406},")",{"type":29,"tag":90,"props":7408,"children":7410},{"id":7409},"code-qualität",[7411],{"type":56,"value":7412},"Code-Qualität",{"type":29,"tag":48,"props":7414,"children":7415},{},[7416,7418,7423],{"type":56,"value":7417},"Fangen wir mit der Code-Qualität an, da es einfacher ist, diese außerhalb einer ",{"type":29,"tag":672,"props":7419,"children":7421},{"className":7420},[],[7422],{"type":56,"value":5277},{"type":56,"value":7424},"-Umgebung auszuführen.",{"type":29,"tag":48,"props":7426,"children":7427},{},[7428,7430,7435],{"type":56,"value":7429},"Wir werden wieder das ",{"type":29,"tag":672,"props":7431,"children":7433},{"className":7432},[],[7434],{"type":56,"value":1928},{"type":56,"value":7436}," verwenden.",{"type":29,"tag":659,"props":7438,"children":7440},{"code":7439,"language":3023,"meta":7,"className":3021,"style":7},"shopware-cli extension validate --full --reporter summary .\n",[7441],{"type":29,"tag":672,"props":7442,"children":7443},{"__ignoreMap":7},[7444],{"type":29,"tag":127,"props":7445,"children":7446},{"class":677,"line":678},[7447,7451,7455,7460,7465,7470,7475],{"type":29,"tag":127,"props":7448,"children":7449},{"style":3033},[7450],{"type":56,"value":1928},{"type":29,"tag":127,"props":7452,"children":7453},{"style":720},[7454],{"type":56,"value":6323},{"type":29,"tag":127,"props":7456,"children":7457},{"style":720},[7458],{"type":56,"value":7459}," validate",{"type":29,"tag":127,"props":7461,"children":7462},{"style":2303},[7463],{"type":56,"value":7464}," --full",{"type":29,"tag":127,"props":7466,"children":7467},{"style":2303},[7468],{"type":56,"value":7469}," --reporter",{"type":29,"tag":127,"props":7471,"children":7472},{"style":720},[7473],{"type":56,"value":7474}," summary",{"type":29,"tag":127,"props":7476,"children":7477},{"style":720},[7478],{"type":56,"value":6333},{"type":29,"tag":48,"props":7480,"children":7481},{},[7482,7484,7490],{"type":56,"value":7483},"Dies wird alle Tests ausführen, die ",{"type":29,"tag":645,"props":7485,"children":7487},{"href":7486},"https://developer.shopware.com/docs/products/cli/validation.html#running-all-validation-tools",[7488],{"type":56,"value":7489},"hier",{"type":56,"value":7491}," beschrieben sind,\nund hoffentlich eine Ausgabe wie diese erzeugen:",{"type":29,"tag":659,"props":7493,"children":7495},{"code":7494},"✖ 0 problems (0 errors, 0 warnings)\n",[7496],{"type":29,"tag":672,"props":7497,"children":7498},{"__ignoreMap":7},[7499],{"type":56,"value":7494},{"type":29,"tag":48,"props":7501,"children":7502},{},[7503,7505,7510],{"type":56,"value":7504},"Falls Fehler auftreten, schaue in der Shopware-Dokumentation nach, wie diese zu beheben sind, und führe nur die fehlgeschlagenen Tests erneut aus, wie ",{"type":29,"tag":645,"props":7506,"children":7508},{"href":7507},"https://developer.shopware.com/docs/products/cli/validation.html#running-specific-tools",[7509],{"type":56,"value":7489},{"type":56,"value":7511}," beschrieben.",{"type":29,"tag":122,"props":7513,"children":7515},{"id":7514},"code-qualität-pipeline",[7516],{"type":56,"value":7517},"Code-Qualität Pipeline",{"type":29,"tag":48,"props":7519,"children":7520},{},[7521],{"type":56,"value":7522},"Nun werden wir das Ganze in GitLab ausführen.",{"type":29,"tag":659,"props":7524,"children":7527},{"code":7525,"filename":5573,"highlights":7526,"language":508,"meta":7,"className":669,"style":7},"stages:\n  - test\n\ncode-quality:\n   image:\n      name: ghcr.io/shopware/shopware-cli:latest-php-8.2\n      entrypoint: [\"\"]\n   stage: test\n   script:\n      - shopware-cli extension validate --full . | tee report.json\n   artifacts:\n      reports:\n         codequality: report.json\n   rules:\n      - if: $CI_PIPELINE_SOURCE == \"merge_request_event\"\n      - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH\n        when: never\n      - if: $CI_COMMIT_BRANCH\n",[665,1380,1393,1402,1415,1428],[7528],{"type":29,"tag":672,"props":7529,"children":7530},{"__ignoreMap":7},[7531,7542,7554,7561,7573,7585,7602,7622,7638,7650,7662,7674,7686,7703,7716,7737,7757,7774],{"type":29,"tag":127,"props":7532,"children":7533},{"class":677,"line":678},[7534,7538],{"type":29,"tag":127,"props":7535,"children":7536},{"style":682},[7537],{"type":56,"value":5394},{"type":29,"tag":127,"props":7539,"children":7540},{"style":688},[7541],{"type":56,"value":691},{"type":29,"tag":127,"props":7543,"children":7544},{"class":677,"line":342},[7545,7549],{"type":29,"tag":127,"props":7546,"children":7547},{"style":688},[7548],{"type":56,"value":5406},{"type":29,"tag":127,"props":7550,"children":7551},{"style":720},[7552],{"type":56,"value":7553},"test\n",{"type":29,"tag":127,"props":7555,"children":7556},{"class":677,"line":706},[7557],{"type":29,"tag":127,"props":7558,"children":7559},{"emptyLinePlaceholder":500},[7560],{"type":56,"value":1399},{"type":29,"tag":127,"props":7562,"children":7563},{"class":677,"line":726},[7564,7569],{"type":29,"tag":127,"props":7565,"children":7566},{"style":682},[7567],{"type":56,"value":7568},"code-quality",{"type":29,"tag":127,"props":7570,"children":7571},{"style":688},[7572],{"type":56,"value":691},{"type":29,"tag":127,"props":7574,"children":7575},{"class":677,"line":664},[7576,7581],{"type":29,"tag":127,"props":7577,"children":7578},{"style":682},[7579],{"type":56,"value":7580},"   image",{"type":29,"tag":127,"props":7582,"children":7583},{"style":688},[7584],{"type":56,"value":691},{"type":29,"tag":127,"props":7586,"children":7588},{"class":7587,"line":665},[677,740],[7589,7594,7598],{"type":29,"tag":127,"props":7590,"children":7591},{"style":682},[7592],{"type":56,"value":7593},"      name",{"type":29,"tag":127,"props":7595,"children":7596},{"style":688},[7597],{"type":56,"value":717},{"type":29,"tag":127,"props":7599,"children":7600},{"style":720},[7601],{"type":56,"value":6502},{"type":29,"tag":127,"props":7603,"children":7604},{"class":677,"line":666},[7605,7610,7614,7618],{"type":29,"tag":127,"props":7606,"children":7607},{"style":682},[7608],{"type":56,"value":7609},"      entrypoint",{"type":29,"tag":127,"props":7611,"children":7612},{"style":688},[7613],{"type":56,"value":5674},{"type":29,"tag":127,"props":7615,"children":7616},{"style":720},[7617],{"type":56,"value":5679},{"type":29,"tag":127,"props":7619,"children":7620},{"style":688},[7621],{"type":56,"value":5684},{"type":29,"tag":127,"props":7623,"children":7624},{"class":677,"line":667},[7625,7630,7634],{"type":29,"tag":127,"props":7626,"children":7627},{"style":682},[7628],{"type":56,"value":7629},"   stage",{"type":29,"tag":127,"props":7631,"children":7632},{"style":688},[7633],{"type":56,"value":717},{"type":29,"tag":127,"props":7635,"children":7636},{"style":720},[7637],{"type":56,"value":7553},{"type":29,"tag":127,"props":7639,"children":7640},{"class":677,"line":668},[7641,7646],{"type":29,"tag":127,"props":7642,"children":7643},{"style":682},[7644],{"type":56,"value":7645},"   script",{"type":29,"tag":127,"props":7647,"children":7648},{"style":688},[7649],{"type":56,"value":691},{"type":29,"tag":127,"props":7651,"children":7652},{"class":677,"line":1329},[7653,7657],{"type":29,"tag":127,"props":7654,"children":7655},{"style":688},[7656],{"type":56,"value":746},{"type":29,"tag":127,"props":7658,"children":7659},{"style":720},[7660],{"type":56,"value":7661},"shopware-cli extension validate --full . | tee report.json\n",{"type":29,"tag":127,"props":7663,"children":7664},{"class":677,"line":1342},[7665,7670],{"type":29,"tag":127,"props":7666,"children":7667},{"style":682},[7668],{"type":56,"value":7669},"   artifacts",{"type":29,"tag":127,"props":7671,"children":7672},{"style":688},[7673],{"type":56,"value":691},{"type":29,"tag":127,"props":7675,"children":7676},{"class":677,"line":118},[7677,7682],{"type":29,"tag":127,"props":7678,"children":7679},{"style":682},[7680],{"type":56,"value":7681},"      reports",{"type":29,"tag":127,"props":7683,"children":7684},{"style":688},[7685],{"type":56,"value":691},{"type":29,"tag":127,"props":7687,"children":7688},{"class":677,"line":1367},[7689,7694,7698],{"type":29,"tag":127,"props":7690,"children":7691},{"style":682},[7692],{"type":56,"value":7693},"         codequality",{"type":29,"tag":127,"props":7695,"children":7696},{"style":688},[7697],{"type":56,"value":717},{"type":29,"tag":127,"props":7699,"children":7700},{"style":720},[7701],{"type":56,"value":7702},"report.json\n",{"type":29,"tag":127,"props":7704,"children":7706},{"class":7705,"line":1380},[677,740],[7707,7712],{"type":29,"tag":127,"props":7708,"children":7709},{"style":682},[7710],{"type":56,"value":7711},"   rules",{"type":29,"tag":127,"props":7713,"children":7714},{"style":688},[7715],{"type":56,"value":691},{"type":29,"tag":127,"props":7717,"children":7719},{"class":7718,"line":1393},[677,740],[7720,7724,7728,7732],{"type":29,"tag":127,"props":7721,"children":7722},{"style":688},[7723],{"type":56,"value":746},{"type":29,"tag":127,"props":7725,"children":7726},{"style":682},[7727],{"type":56,"value":5746},{"type":29,"tag":127,"props":7729,"children":7730},{"style":688},[7731],{"type":56,"value":717},{"type":29,"tag":127,"props":7733,"children":7734},{"style":720},[7735],{"type":56,"value":7736},"$CI_PIPELINE_SOURCE == \"merge_request_event\"\n",{"type":29,"tag":127,"props":7738,"children":7740},{"class":7739,"line":1402},[677,740],[7741,7745,7749,7753],{"type":29,"tag":127,"props":7742,"children":7743},{"style":688},[7744],{"type":56,"value":746},{"type":29,"tag":127,"props":7746,"children":7747},{"style":682},[7748],{"type":56,"value":5746},{"type":29,"tag":127,"props":7750,"children":7751},{"style":688},[7752],{"type":56,"value":717},{"type":29,"tag":127,"props":7754,"children":7755},{"style":720},[7756],{"type":56,"value":5755},{"type":29,"tag":127,"props":7758,"children":7760},{"class":7759,"line":1415},[677,740],[7761,7766,7770],{"type":29,"tag":127,"props":7762,"children":7763},{"style":682},[7764],{"type":56,"value":7765},"        when",{"type":29,"tag":127,"props":7767,"children":7768},{"style":688},[7769],{"type":56,"value":717},{"type":29,"tag":127,"props":7771,"children":7772},{"style":720},[7773],{"type":56,"value":5772},{"type":29,"tag":127,"props":7775,"children":7777},{"class":7776,"line":1428},[677,740],[7778,7782,7786,7790],{"type":29,"tag":127,"props":7779,"children":7780},{"style":688},[7781],{"type":56,"value":746},{"type":29,"tag":127,"props":7783,"children":7784},{"style":682},[7785],{"type":56,"value":5746},{"type":29,"tag":127,"props":7787,"children":7788},{"style":688},[7789],{"type":56,"value":717},{"type":29,"tag":127,"props":7791,"children":7792},{"style":720},[7793],{"type":56,"value":5792},{"type":29,"tag":48,"props":7795,"children":7796},{},[7797],{"type":56,"value":7798},"Diese Pipeline wird auf dem Standard-Branch und bei Merge-Request-Pipelines ausgeführt.",{"type":29,"tag":48,"props":7800,"children":7801},{},[7802],{"type":56,"value":7803},"Das Ausführen auf dem Standard-Branch vor dem Bauen und Veröffentlichen verhindert, dass versehentlich ein Release mit geringer Qualität erstellt wird.",{"type":29,"tag":48,"props":7805,"children":7806},{},[7807],{"type":56,"value":7808},"Ein nettes Extra für die MR-Pipeline ist die Integration des Code-Quality-Reports!",{"type":29,"tag":90,"props":7810,"children":7812},{"id":7811},"php-unit-tests",[7813],{"type":56,"value":7379},{"type":29,"tag":48,"props":7815,"children":7816},{},[7817,7819,7825],{"type":56,"value":7818},"Zuerst müssen wir PHPUnit konfigurieren, indem wir der ",{"type":29,"tag":645,"props":7820,"children":7822},{"href":7821},"https://developer.shopware.com/docs/guides/plugins/plugins/testing/php-unit.html",[7823],{"type":56,"value":7824},"offiziellen Shopware-Dokumentation",{"type":56,"value":7826}," folgen.",{"type":29,"tag":48,"props":7828,"children":7829},{},[7830],{"type":56,"value":7831},"Wir werden uns hier nicht auf diesen Prozess konzentrieren. Wenn alles eingerichtet ist, sollten wir in der Lage sein, unseren Test wie folgt im Root-Verzeichnis unseres Shopware-Projekts auszuführen:",{"type":29,"tag":659,"props":7833,"children":7835},{"code":7834,"language":3023,"meta":7,"className":3021,"style":7},"./vendor/bin/phpunit --configuration=\"custom/static-plugins/SwagBasicExample\"\n",[7836],{"type":29,"tag":672,"props":7837,"children":7838},{"__ignoreMap":7},[7839],{"type":29,"tag":127,"props":7840,"children":7841},{"class":677,"line":678},[7842,7847,7852],{"type":29,"tag":127,"props":7843,"children":7844},{"style":3033},[7845],{"type":56,"value":7846},"./vendor/bin/phpunit",{"type":29,"tag":127,"props":7848,"children":7849},{"style":2303},[7850],{"type":56,"value":7851}," --configuration=",{"type":29,"tag":127,"props":7853,"children":7854},{"style":720},[7855],{"type":56,"value":7856},"\"custom/static-plugins/SwagBasicExample\"\n",{"type":29,"tag":122,"props":7858,"children":7860},{"id":7859},"phpunit-pipeline",[7861],{"type":56,"value":7862},"PHPUnit Pipeline",{"type":29,"tag":48,"props":7864,"children":7865},{},[7866,7868,7873],{"type":56,"value":7867},"Das Ausführen von PHPUnit für ein Plugin erfordert eine vollständige Shopware-Instanz. Glücklicherweise kann uns das ",{"type":29,"tag":672,"props":7869,"children":7871},{"className":7870},[],[7872],{"type":56,"value":1928},{"type":56,"value":7874}," dabei helfen.",{"type":29,"tag":659,"props":7876,"children":7879},{"code":7877,"filename":5573,"highlights":7878,"language":508,"meta":7,"className":669,"style":7},"stages:\n   - test\n\nphpunit:\n  stage: test\n  image:\n    name: ghcr.io/shopware/shopware-cli:latest-php-8.2\n    entrypoint: [\"\"]\n  services:\n    - name: mysql:8.3.0\n      alias: test_database\n      variables:\n        MYSQL_SKIP_TEST_DB: 'yes'\n        MYSQL_ALLOW_EMPTY_PASSWORD: yes\n  variables:\n    GIT_STRATEGY: none\n    SHOPWARE_ROOT: ${CI_PROJECT_DIR}/shopware\n    SHOPWARE_VERSION: 6.6.10.13\n    \n    APP_SECRET: def00000bb5acb32b54ff8ee130270586eec0e878f7337dc7a837acc31d3ff00f93a56b595448b4b29664847dd51991b3314ff65aeeeb761a133b0ec0e070433bff08e48\n    MESSENGER_TRANSPORT_DSN: sync://\n    DATABASE_URL: mysql://root@test_database/shopware\n    COMPOSER_CACHE_DIR: ${CI_PROJECT_DIR}/.composer\n\n    XDEBUG_MODE: coverage\n  before_script:\n    - apk add --no-cache php-8.2-xdebug\n    - shopware-cli project create shopware ${SHOPWARE_VERSION}\n    - cd $SHOPWARE_ROOT\n    - composer req --dev shopware/dev-tools phpunit/phpunit\n    - git clone \"https://${GITLAB_USERNAME}:${GITLAB_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git\" \"custom/plugins/${CI_PROJECT_NAME}\"\n    - cd custom/plugins/${CI_PROJECT_NAME}\n    - git checkout ${CI_COMMIT_SHA}\n    - cd ${SHOPWARE_ROOT}\n    - composer require $(composer -d custom/plugins/${CI_PROJECT_NAME} config name)\n    - cd custom/plugins/${CI_PROJECT_NAME}\n  script:\n    - ${SHOPWARE_ROOT}/vendor/bin/phpunit --coverage-text --coverage-cobertura=coverage.cobertura.xml\n\n  cache:\n    - key: $CI_JOB_NAME\n      paths:\n        - $COMPOSER_CACHE_DIR\n  coverage: /^\\s*Lines:\\s*\\d+.\\d+\\%/\n  artifacts:\n    reports:\n      coverage_report:\n        coverage_format: cobertura\n        path: coverage.cobertura.xml\n  rules:\n    - if: $CI_PIPELINE_SOURCE == \"merge_request_event\"\n    - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH\n      when: never\n    - if: $CI_COMMIT_BRANCH\n",[668,1329,1342,118,1367,1380,1402,1450,1463,1476,1484,1536,1549,2411,2419,2439,2460,2472,2488,2496,1970,1972],[7880],{"type":29,"tag":672,"props":7881,"children":7882},{"__ignoreMap":7},[7883,7894,7906,7913,7925,7940,7951,7966,7985,7998,8019,8037,8050,8068,8086,8097,8115,8132,8149,8156,8174,8192,8210,8226,8233,8250,8262,8275,8288,8301,8314,8327,8340,8353,8366,8379,8391,8402,8415,8422,8433,8452,8463,8474,8491,8502,8514,8526,8543,8560,8571,8590,8609,8624],{"type":29,"tag":127,"props":7884,"children":7885},{"class":677,"line":678},[7886,7890],{"type":29,"tag":127,"props":7887,"children":7888},{"style":682},[7889],{"type":56,"value":5394},{"type":29,"tag":127,"props":7891,"children":7892},{"style":688},[7893],{"type":56,"value":691},{"type":29,"tag":127,"props":7895,"children":7896},{"class":677,"line":342},[7897,7902],{"type":29,"tag":127,"props":7898,"children":7899},{"style":688},[7900],{"type":56,"value":7901},"   - ",{"type":29,"tag":127,"props":7903,"children":7904},{"style":720},[7905],{"type":56,"value":7553},{"type":29,"tag":127,"props":7907,"children":7908},{"class":677,"line":706},[7909],{"type":29,"tag":127,"props":7910,"children":7911},{"emptyLinePlaceholder":500},[7912],{"type":56,"value":1399},{"type":29,"tag":127,"props":7914,"children":7915},{"class":677,"line":726},[7916,7921],{"type":29,"tag":127,"props":7917,"children":7918},{"style":682},[7919],{"type":56,"value":7920},"phpunit",{"type":29,"tag":127,"props":7922,"children":7923},{"style":688},[7924],{"type":56,"value":691},{"type":29,"tag":127,"props":7926,"children":7927},{"class":677,"line":664},[7928,7932,7936],{"type":29,"tag":127,"props":7929,"children":7930},{"style":682},[7931],{"type":56,"value":5455},{"type":29,"tag":127,"props":7933,"children":7934},{"style":688},[7935],{"type":56,"value":717},{"type":29,"tag":127,"props":7937,"children":7938},{"style":720},[7939],{"type":56,"value":7553},{"type":29,"tag":127,"props":7941,"children":7942},{"class":677,"line":665},[7943,7947],{"type":29,"tag":127,"props":7944,"children":7945},{"style":682},[7946],{"type":56,"value":5438},{"type":29,"tag":127,"props":7948,"children":7949},{"style":688},[7950],{"type":56,"value":691},{"type":29,"tag":127,"props":7952,"children":7953},{"class":677,"line":666},[7954,7958,7962],{"type":29,"tag":127,"props":7955,"children":7956},{"style":682},[7957],{"type":56,"value":5652},{"type":29,"tag":127,"props":7959,"children":7960},{"style":688},[7961],{"type":56,"value":717},{"type":29,"tag":127,"props":7963,"children":7964},{"style":720},[7965],{"type":56,"value":6502},{"type":29,"tag":127,"props":7967,"children":7968},{"class":677,"line":667},[7969,7973,7977,7981],{"type":29,"tag":127,"props":7970,"children":7971},{"style":682},[7972],{"type":56,"value":5669},{"type":29,"tag":127,"props":7974,"children":7975},{"style":688},[7976],{"type":56,"value":5674},{"type":29,"tag":127,"props":7978,"children":7979},{"style":720},[7980],{"type":56,"value":5679},{"type":29,"tag":127,"props":7982,"children":7983},{"style":688},[7984],{"type":56,"value":5684},{"type":29,"tag":127,"props":7986,"children":7988},{"class":7987,"line":668},[677,740],[7989,7994],{"type":29,"tag":127,"props":7990,"children":7991},{"style":682},[7992],{"type":56,"value":7993},"  services",{"type":29,"tag":127,"props":7995,"children":7996},{"style":688},[7997],{"type":56,"value":691},{"type":29,"tag":127,"props":7999,"children":8001},{"class":8000,"line":1329},[677,740],[8002,8006,8010,8014],{"type":29,"tag":127,"props":8003,"children":8004},{"style":688},[8005],{"type":56,"value":5483},{"type":29,"tag":127,"props":8007,"children":8008},{"style":682},[8009],{"type":56,"value":1785},{"type":29,"tag":127,"props":8011,"children":8012},{"style":688},[8013],{"type":56,"value":717},{"type":29,"tag":127,"props":8015,"children":8016},{"style":720},[8017],{"type":56,"value":8018},"mysql:8.3.0\n",{"type":29,"tag":127,"props":8020,"children":8022},{"class":8021,"line":1342},[677,740],[8023,8028,8032],{"type":29,"tag":127,"props":8024,"children":8025},{"style":682},[8026],{"type":56,"value":8027},"      alias",{"type":29,"tag":127,"props":8029,"children":8030},{"style":688},[8031],{"type":56,"value":717},{"type":29,"tag":127,"props":8033,"children":8034},{"style":720},[8035],{"type":56,"value":8036},"test_database\n",{"type":29,"tag":127,"props":8038,"children":8040},{"class":8039,"line":118},[677,740],[8041,8046],{"type":29,"tag":127,"props":8042,"children":8043},{"style":682},[8044],{"type":56,"value":8045},"      variables",{"type":29,"tag":127,"props":8047,"children":8048},{"style":688},[8049],{"type":56,"value":691},{"type":29,"tag":127,"props":8051,"children":8053},{"class":8052,"line":1367},[677,740],[8054,8059,8063],{"type":29,"tag":127,"props":8055,"children":8056},{"style":682},[8057],{"type":56,"value":8058},"        MYSQL_SKIP_TEST_DB",{"type":29,"tag":127,"props":8060,"children":8061},{"style":688},[8062],{"type":56,"value":717},{"type":29,"tag":127,"props":8064,"children":8065},{"style":720},[8066],{"type":56,"value":8067},"'yes'\n",{"type":29,"tag":127,"props":8069,"children":8071},{"class":8070,"line":1380},[677,740],[8072,8077,8081],{"type":29,"tag":127,"props":8073,"children":8074},{"style":682},[8075],{"type":56,"value":8076},"        MYSQL_ALLOW_EMPTY_PASSWORD",{"type":29,"tag":127,"props":8078,"children":8079},{"style":688},[8080],{"type":56,"value":717},{"type":29,"tag":127,"props":8082,"children":8083},{"style":2303},[8084],{"type":56,"value":8085},"yes\n",{"type":29,"tag":127,"props":8087,"children":8088},{"class":677,"line":1393},[8089,8093],{"type":29,"tag":127,"props":8090,"children":8091},{"style":682},[8092],{"type":56,"value":6544},{"type":29,"tag":127,"props":8094,"children":8095},{"style":688},[8096],{"type":56,"value":691},{"type":29,"tag":127,"props":8098,"children":8100},{"class":8099,"line":1402},[677,740],[8101,8106,8110],{"type":29,"tag":127,"props":8102,"children":8103},{"style":682},[8104],{"type":56,"value":8105},"    GIT_STRATEGY",{"type":29,"tag":127,"props":8107,"children":8108},{"style":688},[8109],{"type":56,"value":717},{"type":29,"tag":127,"props":8111,"children":8112},{"style":720},[8113],{"type":56,"value":8114},"none\n",{"type":29,"tag":127,"props":8116,"children":8117},{"class":677,"line":1415},[8118,8123,8127],{"type":29,"tag":127,"props":8119,"children":8120},{"style":682},[8121],{"type":56,"value":8122},"    SHOPWARE_ROOT",{"type":29,"tag":127,"props":8124,"children":8125},{"style":688},[8126],{"type":56,"value":717},{"type":29,"tag":127,"props":8128,"children":8129},{"style":720},[8130],{"type":56,"value":8131},"${CI_PROJECT_DIR}/shopware\n",{"type":29,"tag":127,"props":8133,"children":8134},{"class":677,"line":1428},[8135,8140,8144],{"type":29,"tag":127,"props":8136,"children":8137},{"style":682},[8138],{"type":56,"value":8139},"    SHOPWARE_VERSION",{"type":29,"tag":127,"props":8141,"children":8142},{"style":688},[8143],{"type":56,"value":717},{"type":29,"tag":127,"props":8145,"children":8146},{"style":2303},[8147],{"type":56,"value":8148},"6.6.10.13\n",{"type":29,"tag":127,"props":8150,"children":8151},{"class":677,"line":1437},[8152],{"type":29,"tag":127,"props":8153,"children":8154},{"style":688},[8155],{"type":56,"value":1236},{"type":29,"tag":127,"props":8157,"children":8159},{"class":8158,"line":1450},[677,740],[8160,8165,8169],{"type":29,"tag":127,"props":8161,"children":8162},{"style":682},[8163],{"type":56,"value":8164},"    APP_SECRET",{"type":29,"tag":127,"props":8166,"children":8167},{"style":688},[8168],{"type":56,"value":717},{"type":29,"tag":127,"props":8170,"children":8171},{"style":720},[8172],{"type":56,"value":8173},"def00000bb5acb32b54ff8ee130270586eec0e878f7337dc7a837acc31d3ff00f93a56b595448b4b29664847dd51991b3314ff65aeeeb761a133b0ec0e070433bff08e48\n",{"type":29,"tag":127,"props":8175,"children":8177},{"class":8176,"line":1463},[677,740],[8178,8183,8187],{"type":29,"tag":127,"props":8179,"children":8180},{"style":682},[8181],{"type":56,"value":8182},"    MESSENGER_TRANSPORT_DSN",{"type":29,"tag":127,"props":8184,"children":8185},{"style":688},[8186],{"type":56,"value":717},{"type":29,"tag":127,"props":8188,"children":8189},{"style":720},[8190],{"type":56,"value":8191},"sync://\n",{"type":29,"tag":127,"props":8193,"children":8195},{"class":8194,"line":1476},[677,740],[8196,8201,8205],{"type":29,"tag":127,"props":8197,"children":8198},{"style":682},[8199],{"type":56,"value":8200},"    DATABASE_URL",{"type":29,"tag":127,"props":8202,"children":8203},{"style":688},[8204],{"type":56,"value":717},{"type":29,"tag":127,"props":8206,"children":8207},{"style":720},[8208],{"type":56,"value":8209},"mysql://root@test_database/shopware\n",{"type":29,"tag":127,"props":8211,"children":8213},{"class":8212,"line":1484},[677,740],[8214,8218,8222],{"type":29,"tag":127,"props":8215,"children":8216},{"style":682},[8217],{"type":56,"value":6556},{"type":29,"tag":127,"props":8219,"children":8220},{"style":688},[8221],{"type":56,"value":717},{"type":29,"tag":127,"props":8223,"children":8224},{"style":720},[8225],{"type":56,"value":6565},{"type":29,"tag":127,"props":8227,"children":8228},{"class":677,"line":1497},[8229],{"type":29,"tag":127,"props":8230,"children":8231},{"emptyLinePlaceholder":500},[8232],{"type":56,"value":1399},{"type":29,"tag":127,"props":8234,"children":8235},{"class":677,"line":1510},[8236,8241,8245],{"type":29,"tag":127,"props":8237,"children":8238},{"style":682},[8239],{"type":56,"value":8240},"    XDEBUG_MODE",{"type":29,"tag":127,"props":8242,"children":8243},{"style":688},[8244],{"type":56,"value":717},{"type":29,"tag":127,"props":8246,"children":8247},{"style":720},[8248],{"type":56,"value":8249},"coverage\n",{"type":29,"tag":127,"props":8251,"children":8252},{"class":677,"line":1523},[8253,8258],{"type":29,"tag":127,"props":8254,"children":8255},{"style":682},[8256],{"type":56,"value":8257},"  before_script",{"type":29,"tag":127,"props":8259,"children":8260},{"style":688},[8261],{"type":56,"value":691},{"type":29,"tag":127,"props":8263,"children":8265},{"class":8264,"line":1536},[677,740],[8266,8270],{"type":29,"tag":127,"props":8267,"children":8268},{"style":688},[8269],{"type":56,"value":5483},{"type":29,"tag":127,"props":8271,"children":8272},{"style":720},[8273],{"type":56,"value":8274},"apk add --no-cache php-8.2-xdebug\n",{"type":29,"tag":127,"props":8276,"children":8278},{"class":8277,"line":1549},[677,740],[8279,8283],{"type":29,"tag":127,"props":8280,"children":8281},{"style":688},[8282],{"type":56,"value":5483},{"type":29,"tag":127,"props":8284,"children":8285},{"style":720},[8286],{"type":56,"value":8287},"shopware-cli project create shopware ${SHOPWARE_VERSION}\n",{"type":29,"tag":127,"props":8289,"children":8291},{"class":8290,"line":2411},[677,740],[8292,8296],{"type":29,"tag":127,"props":8293,"children":8294},{"style":688},[8295],{"type":56,"value":5483},{"type":29,"tag":127,"props":8297,"children":8298},{"style":720},[8299],{"type":56,"value":8300},"cd $SHOPWARE_ROOT\n",{"type":29,"tag":127,"props":8302,"children":8304},{"class":8303,"line":2419},[677,740],[8305,8309],{"type":29,"tag":127,"props":8306,"children":8307},{"style":688},[8308],{"type":56,"value":5483},{"type":29,"tag":127,"props":8310,"children":8311},{"style":720},[8312],{"type":56,"value":8313},"composer req --dev shopware/dev-tools phpunit/phpunit\n",{"type":29,"tag":127,"props":8315,"children":8317},{"class":8316,"line":2439},[677,740],[8318,8322],{"type":29,"tag":127,"props":8319,"children":8320},{"style":688},[8321],{"type":56,"value":5483},{"type":29,"tag":127,"props":8323,"children":8324},{"style":720},[8325],{"type":56,"value":8326},"git clone \"https://${GITLAB_USERNAME}:${GITLAB_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git\" \"custom/plugins/${CI_PROJECT_NAME}\"\n",{"type":29,"tag":127,"props":8328,"children":8330},{"class":8329,"line":2460},[677,740],[8331,8335],{"type":29,"tag":127,"props":8332,"children":8333},{"style":688},[8334],{"type":56,"value":5483},{"type":29,"tag":127,"props":8336,"children":8337},{"style":720},[8338],{"type":56,"value":8339},"cd custom/plugins/${CI_PROJECT_NAME}\n",{"type":29,"tag":127,"props":8341,"children":8343},{"class":8342,"line":2472},[677,740],[8344,8348],{"type":29,"tag":127,"props":8345,"children":8346},{"style":688},[8347],{"type":56,"value":5483},{"type":29,"tag":127,"props":8349,"children":8350},{"style":720},[8351],{"type":56,"value":8352},"git checkout ${CI_COMMIT_SHA}\n",{"type":29,"tag":127,"props":8354,"children":8356},{"class":8355,"line":2488},[677,740],[8357,8361],{"type":29,"tag":127,"props":8358,"children":8359},{"style":688},[8360],{"type":56,"value":5483},{"type":29,"tag":127,"props":8362,"children":8363},{"style":720},[8364],{"type":56,"value":8365},"cd ${SHOPWARE_ROOT}\n",{"type":29,"tag":127,"props":8367,"children":8369},{"class":8368,"line":2496},[677,740],[8370,8374],{"type":29,"tag":127,"props":8371,"children":8372},{"style":688},[8373],{"type":56,"value":5483},{"type":29,"tag":127,"props":8375,"children":8376},{"style":720},[8377],{"type":56,"value":8378},"composer require $(composer -d custom/plugins/${CI_PROJECT_NAME} config name)\n",{"type":29,"tag":127,"props":8380,"children":8382},{"class":8381,"line":1970},[677,740],[8383,8387],{"type":29,"tag":127,"props":8384,"children":8385},{"style":688},[8386],{"type":56,"value":5483},{"type":29,"tag":127,"props":8388,"children":8389},{"style":720},[8390],{"type":56,"value":8339},{"type":29,"tag":127,"props":8392,"children":8393},{"class":677,"line":1971},[8394,8398],{"type":29,"tag":127,"props":8395,"children":8396},{"style":682},[8397],{"type":56,"value":5471},{"type":29,"tag":127,"props":8399,"children":8400},{"style":688},[8401],{"type":56,"value":691},{"type":29,"tag":127,"props":8403,"children":8405},{"class":8404,"line":1972},[677,740],[8406,8410],{"type":29,"tag":127,"props":8407,"children":8408},{"style":688},[8409],{"type":56,"value":5483},{"type":29,"tag":127,"props":8411,"children":8412},{"style":720},[8413],{"type":56,"value":8414},"${SHOPWARE_ROOT}/vendor/bin/phpunit --coverage-text --coverage-cobertura=coverage.cobertura.xml\n",{"type":29,"tag":127,"props":8416,"children":8417},{"class":677,"line":1973},[8418],{"type":29,"tag":127,"props":8419,"children":8420},{"emptyLinePlaceholder":500},[8421],{"type":56,"value":1399},{"type":29,"tag":127,"props":8423,"children":8424},{"class":677,"line":2559},[8425,8429],{"type":29,"tag":127,"props":8426,"children":8427},{"style":682},[8428],{"type":56,"value":6613},{"type":29,"tag":127,"props":8430,"children":8431},{"style":688},[8432],{"type":56,"value":691},{"type":29,"tag":127,"props":8434,"children":8435},{"class":677,"line":2568},[8436,8440,8444,8448],{"type":29,"tag":127,"props":8437,"children":8438},{"style":688},[8439],{"type":56,"value":5483},{"type":29,"tag":127,"props":8441,"children":8442},{"style":682},[8443],{"type":56,"value":6630},{"type":29,"tag":127,"props":8445,"children":8446},{"style":688},[8447],{"type":56,"value":717},{"type":29,"tag":127,"props":8449,"children":8450},{"style":720},[8451],{"type":56,"value":6639},{"type":29,"tag":127,"props":8453,"children":8454},{"class":677,"line":2581},[8455,8459],{"type":29,"tag":127,"props":8456,"children":8457},{"style":682},[8458],{"type":56,"value":6648},{"type":29,"tag":127,"props":8460,"children":8461},{"style":688},[8462],{"type":56,"value":691},{"type":29,"tag":127,"props":8464,"children":8465},{"class":677,"line":2594},[8466,8470],{"type":29,"tag":127,"props":8467,"children":8468},{"style":688},[8469],{"type":56,"value":6661},{"type":29,"tag":127,"props":8471,"children":8472},{"style":720},[8473],{"type":56,"value":6666},{"type":29,"tag":127,"props":8475,"children":8476},{"class":677,"line":2623},[8477,8482,8486],{"type":29,"tag":127,"props":8478,"children":8479},{"style":682},[8480],{"type":56,"value":8481},"  coverage",{"type":29,"tag":127,"props":8483,"children":8484},{"style":688},[8485],{"type":56,"value":717},{"type":29,"tag":127,"props":8487,"children":8488},{"style":720},[8489],{"type":56,"value":8490},"/^\\s*Lines:\\s*\\d+.\\d+\\%/\n",{"type":29,"tag":127,"props":8492,"children":8493},{"class":677,"line":2631},[8494,8498],{"type":29,"tag":127,"props":8495,"children":8496},{"style":682},[8497],{"type":56,"value":7013},{"type":29,"tag":127,"props":8499,"children":8500},{"style":688},[8501],{"type":56,"value":691},{"type":29,"tag":127,"props":8503,"children":8504},{"class":677,"line":2639},[8505,8510],{"type":29,"tag":127,"props":8506,"children":8507},{"style":682},[8508],{"type":56,"value":8509},"    reports",{"type":29,"tag":127,"props":8511,"children":8512},{"style":688},[8513],{"type":56,"value":691},{"type":29,"tag":127,"props":8515,"children":8516},{"class":677,"line":2660},[8517,8522],{"type":29,"tag":127,"props":8518,"children":8519},{"style":682},[8520],{"type":56,"value":8521},"      coverage_report",{"type":29,"tag":127,"props":8523,"children":8524},{"style":688},[8525],{"type":56,"value":691},{"type":29,"tag":127,"props":8527,"children":8528},{"class":677,"line":2673},[8529,8534,8538],{"type":29,"tag":127,"props":8530,"children":8531},{"style":682},[8532],{"type":56,"value":8533},"        coverage_format",{"type":29,"tag":127,"props":8535,"children":8536},{"style":688},[8537],{"type":56,"value":717},{"type":29,"tag":127,"props":8539,"children":8540},{"style":720},[8541],{"type":56,"value":8542},"cobertura\n",{"type":29,"tag":127,"props":8544,"children":8545},{"class":677,"line":2686},[8546,8551,8555],{"type":29,"tag":127,"props":8547,"children":8548},{"style":682},[8549],{"type":56,"value":8550},"        path",{"type":29,"tag":127,"props":8552,"children":8553},{"style":688},[8554],{"type":56,"value":717},{"type":29,"tag":127,"props":8556,"children":8557},{"style":720},[8558],{"type":56,"value":8559},"coverage.cobertura.xml\n",{"type":29,"tag":127,"props":8561,"children":8562},{"class":677,"line":2707},[8563,8567],{"type":29,"tag":127,"props":8564,"children":8565},{"style":682},[8566],{"type":56,"value":5513},{"type":29,"tag":127,"props":8568,"children":8569},{"style":688},[8570],{"type":56,"value":691},{"type":29,"tag":127,"props":8572,"children":8573},{"class":677,"line":2724},[8574,8578,8582,8586],{"type":29,"tag":127,"props":8575,"children":8576},{"style":688},[8577],{"type":56,"value":5483},{"type":29,"tag":127,"props":8579,"children":8580},{"style":682},[8581],{"type":56,"value":5746},{"type":29,"tag":127,"props":8583,"children":8584},{"style":688},[8585],{"type":56,"value":717},{"type":29,"tag":127,"props":8587,"children":8588},{"style":720},[8589],{"type":56,"value":7736},{"type":29,"tag":127,"props":8591,"children":8592},{"class":677,"line":2732},[8593,8597,8601,8605],{"type":29,"tag":127,"props":8594,"children":8595},{"style":688},[8596],{"type":56,"value":5483},{"type":29,"tag":127,"props":8598,"children":8599},{"style":682},[8600],{"type":56,"value":5746},{"type":29,"tag":127,"props":8602,"children":8603},{"style":688},[8604],{"type":56,"value":717},{"type":29,"tag":127,"props":8606,"children":8607},{"style":720},[8608],{"type":56,"value":5755},{"type":29,"tag":127,"props":8610,"children":8611},{"class":677,"line":2753},[8612,8616,8620],{"type":29,"tag":127,"props":8613,"children":8614},{"style":682},[8615],{"type":56,"value":5763},{"type":29,"tag":127,"props":8617,"children":8618},{"style":688},[8619],{"type":56,"value":717},{"type":29,"tag":127,"props":8621,"children":8622},{"style":720},[8623],{"type":56,"value":5772},{"type":29,"tag":127,"props":8625,"children":8626},{"class":677,"line":2770},[8627,8631,8635,8639],{"type":29,"tag":127,"props":8628,"children":8629},{"style":688},[8630],{"type":56,"value":5483},{"type":29,"tag":127,"props":8632,"children":8633},{"style":682},[8634],{"type":56,"value":5746},{"type":29,"tag":127,"props":8636,"children":8637},{"style":688},[8638],{"type":56,"value":717},{"type":29,"tag":127,"props":8640,"children":8641},{"style":720},[8642],{"type":56,"value":5792},{"type":29,"tag":48,"props":8644,"children":8645},{},[8646],{"type":56,"value":8647},"Lass uns das ein wenig erklären:",{"type":29,"tag":965,"props":8649,"children":8650},{},[8651,8656,8661,8666,8671],{"type":29,"tag":814,"props":8652,"children":8653},{},[8654],{"type":56,"value":8655},"Wir deaktivieren das automatische Klonen des Repositories (16)",{"type":29,"tag":814,"props":8657,"children":8658},{},[8659],{"type":56,"value":8660},"Wir binden einen Datenbank-Service ein (9-14)",{"type":29,"tag":814,"props":8662,"children":8663},{},[8664],{"type":56,"value":8665},"Wir setzen einige erforderliche Shopware-Umgebungsvariablen (20-23)",{"type":29,"tag":814,"props":8667,"children":8668},{},[8669],{"type":56,"value":8670},"Erstellen ein leeres Shopware-Projekt mit PHPUnit und Xdebug (27-36)",{"type":29,"tag":814,"props":8672,"children":8673},{},[8674],{"type":56,"value":8675},"Führen PHPUnit mit Code-Coverage-Generierung als Text und im Cobertura-Format aus (38)",{"type":29,"tag":48,"props":8677,"children":8678},{},[8679],{"type":56,"value":8680},"Wie die Code-Quality-Pipeline nutzt auch diese die Vorteile des GitLab-Coverage-Reportings voll aus.",{"type":29,"tag":90,"props":8682,"children":8684},{"id":8683},"alles-zusammenfügen",[8685],{"type":56,"value":8686},"Alles zusammenfügen",{"type":29,"tag":48,"props":8688,"children":8689},{},[8690],{"type":56,"value":8691},"Für diesen Teil lassen wir den Build- und Release-Teil weg.",{"type":29,"tag":659,"props":8693,"children":8695},{"code":8694,"filename":5573,"language":508,"meta":7,"className":669,"style":7},"stages:\n   - test\n\nphpunit:\n  stage: test\n  image:\n    name: ghcr.io/shopware/shopware-cli:latest-php-8.2\n    entrypoint: [\"\"]\n  services:\n    - name: mysql:8.3.0\n      alias: test_database\n      variables:\n        MYSQL_SKIP_TEST_DB: 'yes'\n        MYSQL_ALLOW_EMPTY_PASSWORD: yes\n  variables:\n    GIT_STRATEGY: none\n    SHOPWARE_ROOT: ${CI_PROJECT_DIR}/shopware\n    SHOPWARE_VERSION: 6.6.10.13\n    \n    APP_SECRET: def00000bb5acb32b54ff8ee130270586eec0e878f7337dc7a837acc31d3ff00f93a56b595448b4b29664847dd51991b3314ff65aeeeb761a133b0ec0e070433bff08e48\n    MESSENGER_TRANSPORT_DSN: sync://\n    DATABASE_URL: mysql://root@test_database/shopware\n    COMPOSER_CACHE_DIR: ${CI_PROJECT_DIR}/.composer\n\n    XDEBUG_MODE: coverage\n  before_script:\n    - apk add --no-cache php-8.2-xdebug\n    - shopware-cli project create shopware ${SHOPWARE_VERSION}\n    - cd $SHOPWARE_ROOT\n    - composer req --dev shopware/dev-tools phpunit/phpunit\n    - git clone \"https://${GITLAB_USERNAME}:${GITLAB_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git\" \"custom/plugins/${CI_PROJECT_NAME}\"\n    - cd custom/plugins/${CI_PROJECT_NAME}\n    - git checkout ${CI_COMMIT_SHA}\n    - cd ${SHOPWARE_ROOT}\n    - composer require $(composer -d custom/plugins/${CI_PROJECT_NAME} config name)\n    - cd custom/plugins/${CI_PROJECT_NAME}\n  script:\n    - ${SHOPWARE_ROOT}/vendor/bin/phpunit --coverage-text --coverage-cobertura=coverage.cobertura.xml\n\n  cache:\n    - key: $CI_JOB_NAME\n      paths:\n        - $COMPOSER_CACHE_DIR\n  coverage: /^\\s*Lines:\\s*\\d+.\\d+\\%/\n  artifacts:\n    reports:\n      coverage_report:\n        coverage_format: cobertura\n        path: coverage.cobertura.xml\n  rules:\n    - if: $CI_PIPELINE_SOURCE == \"merge_request_event\"\n    - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH\n      when: never\n    - if: $CI_COMMIT_BRANCH\n\ncode-quality:\n   image:\n      name: ghcr.io/shopware/shopware-cli:latest-php-8.2\n      entrypoint: [\"\"]\n   stage: test\n   script:\n      - shopware-cli extension validate --full . | tee report.json\n   artifacts:\n      reports:\n         codequality: report.json\n   rules:\n      - if: $CI_PIPELINE_SOURCE == \"merge_request_event\"\n      - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH\n        when: never\n      - if: $CI_COMMIT_BRANCH\n",[8696],{"type":29,"tag":672,"props":8697,"children":8698},{"__ignoreMap":7},[8699,8710,8721,8728,8739,8754,8765,8780,8799,8810,8829,8844,8855,8870,8885,8896,8911,8926,8941,8948,8963,8978,8993,9008,9015,9030,9041,9052,9063,9074,9085,9096,9107,9118,9129,9140,9151,9162,9173,9180,9191,9210,9221,9232,9247,9258,9269,9280,9295,9310,9321,9340,9359,9374,9393,9400,9411,9422,9437,9456,9471,9482,9493,9504,9515,9530,9541,9560,9579,9594],{"type":29,"tag":127,"props":8700,"children":8701},{"class":677,"line":678},[8702,8706],{"type":29,"tag":127,"props":8703,"children":8704},{"style":682},[8705],{"type":56,"value":5394},{"type":29,"tag":127,"props":8707,"children":8708},{"style":688},[8709],{"type":56,"value":691},{"type":29,"tag":127,"props":8711,"children":8712},{"class":677,"line":342},[8713,8717],{"type":29,"tag":127,"props":8714,"children":8715},{"style":688},[8716],{"type":56,"value":7901},{"type":29,"tag":127,"props":8718,"children":8719},{"style":720},[8720],{"type":56,"value":7553},{"type":29,"tag":127,"props":8722,"children":8723},{"class":677,"line":706},[8724],{"type":29,"tag":127,"props":8725,"children":8726},{"emptyLinePlaceholder":500},[8727],{"type":56,"value":1399},{"type":29,"tag":127,"props":8729,"children":8730},{"class":677,"line":726},[8731,8735],{"type":29,"tag":127,"props":8732,"children":8733},{"style":682},[8734],{"type":56,"value":7920},{"type":29,"tag":127,"props":8736,"children":8737},{"style":688},[8738],{"type":56,"value":691},{"type":29,"tag":127,"props":8740,"children":8741},{"class":677,"line":664},[8742,8746,8750],{"type":29,"tag":127,"props":8743,"children":8744},{"style":682},[8745],{"type":56,"value":5455},{"type":29,"tag":127,"props":8747,"children":8748},{"style":688},[8749],{"type":56,"value":717},{"type":29,"tag":127,"props":8751,"children":8752},{"style":720},[8753],{"type":56,"value":7553},{"type":29,"tag":127,"props":8755,"children":8756},{"class":677,"line":665},[8757,8761],{"type":29,"tag":127,"props":8758,"children":8759},{"style":682},[8760],{"type":56,"value":5438},{"type":29,"tag":127,"props":8762,"children":8763},{"style":688},[8764],{"type":56,"value":691},{"type":29,"tag":127,"props":8766,"children":8767},{"class":677,"line":666},[8768,8772,8776],{"type":29,"tag":127,"props":8769,"children":8770},{"style":682},[8771],{"type":56,"value":5652},{"type":29,"tag":127,"props":8773,"children":8774},{"style":688},[8775],{"type":56,"value":717},{"type":29,"tag":127,"props":8777,"children":8778},{"style":720},[8779],{"type":56,"value":6502},{"type":29,"tag":127,"props":8781,"children":8782},{"class":677,"line":667},[8783,8787,8791,8795],{"type":29,"tag":127,"props":8784,"children":8785},{"style":682},[8786],{"type":56,"value":5669},{"type":29,"tag":127,"props":8788,"children":8789},{"style":688},[8790],{"type":56,"value":5674},{"type":29,"tag":127,"props":8792,"children":8793},{"style":720},[8794],{"type":56,"value":5679},{"type":29,"tag":127,"props":8796,"children":8797},{"style":688},[8798],{"type":56,"value":5684},{"type":29,"tag":127,"props":8800,"children":8801},{"class":677,"line":668},[8802,8806],{"type":29,"tag":127,"props":8803,"children":8804},{"style":682},[8805],{"type":56,"value":7993},{"type":29,"tag":127,"props":8807,"children":8808},{"style":688},[8809],{"type":56,"value":691},{"type":29,"tag":127,"props":8811,"children":8812},{"class":677,"line":1329},[8813,8817,8821,8825],{"type":29,"tag":127,"props":8814,"children":8815},{"style":688},[8816],{"type":56,"value":5483},{"type":29,"tag":127,"props":8818,"children":8819},{"style":682},[8820],{"type":56,"value":1785},{"type":29,"tag":127,"props":8822,"children":8823},{"style":688},[8824],{"type":56,"value":717},{"type":29,"tag":127,"props":8826,"children":8827},{"style":720},[8828],{"type":56,"value":8018},{"type":29,"tag":127,"props":8830,"children":8831},{"class":677,"line":1342},[8832,8836,8840],{"type":29,"tag":127,"props":8833,"children":8834},{"style":682},[8835],{"type":56,"value":8027},{"type":29,"tag":127,"props":8837,"children":8838},{"style":688},[8839],{"type":56,"value":717},{"type":29,"tag":127,"props":8841,"children":8842},{"style":720},[8843],{"type":56,"value":8036},{"type":29,"tag":127,"props":8845,"children":8846},{"class":677,"line":118},[8847,8851],{"type":29,"tag":127,"props":8848,"children":8849},{"style":682},[8850],{"type":56,"value":8045},{"type":29,"tag":127,"props":8852,"children":8853},{"style":688},[8854],{"type":56,"value":691},{"type":29,"tag":127,"props":8856,"children":8857},{"class":677,"line":1367},[8858,8862,8866],{"type":29,"tag":127,"props":8859,"children":8860},{"style":682},[8861],{"type":56,"value":8058},{"type":29,"tag":127,"props":8863,"children":8864},{"style":688},[8865],{"type":56,"value":717},{"type":29,"tag":127,"props":8867,"children":8868},{"style":720},[8869],{"type":56,"value":8067},{"type":29,"tag":127,"props":8871,"children":8872},{"class":677,"line":1380},[8873,8877,8881],{"type":29,"tag":127,"props":8874,"children":8875},{"style":682},[8876],{"type":56,"value":8076},{"type":29,"tag":127,"props":8878,"children":8879},{"style":688},[8880],{"type":56,"value":717},{"type":29,"tag":127,"props":8882,"children":8883},{"style":2303},[8884],{"type":56,"value":8085},{"type":29,"tag":127,"props":8886,"children":8887},{"class":677,"line":1393},[8888,8892],{"type":29,"tag":127,"props":8889,"children":8890},{"style":682},[8891],{"type":56,"value":6544},{"type":29,"tag":127,"props":8893,"children":8894},{"style":688},[8895],{"type":56,"value":691},{"type":29,"tag":127,"props":8897,"children":8898},{"class":677,"line":1402},[8899,8903,8907],{"type":29,"tag":127,"props":8900,"children":8901},{"style":682},[8902],{"type":56,"value":8105},{"type":29,"tag":127,"props":8904,"children":8905},{"style":688},[8906],{"type":56,"value":717},{"type":29,"tag":127,"props":8908,"children":8909},{"style":720},[8910],{"type":56,"value":8114},{"type":29,"tag":127,"props":8912,"children":8913},{"class":677,"line":1415},[8914,8918,8922],{"type":29,"tag":127,"props":8915,"children":8916},{"style":682},[8917],{"type":56,"value":8122},{"type":29,"tag":127,"props":8919,"children":8920},{"style":688},[8921],{"type":56,"value":717},{"type":29,"tag":127,"props":8923,"children":8924},{"style":720},[8925],{"type":56,"value":8131},{"type":29,"tag":127,"props":8927,"children":8928},{"class":677,"line":1428},[8929,8933,8937],{"type":29,"tag":127,"props":8930,"children":8931},{"style":682},[8932],{"type":56,"value":8139},{"type":29,"tag":127,"props":8934,"children":8935},{"style":688},[8936],{"type":56,"value":717},{"type":29,"tag":127,"props":8938,"children":8939},{"style":2303},[8940],{"type":56,"value":8148},{"type":29,"tag":127,"props":8942,"children":8943},{"class":677,"line":1437},[8944],{"type":29,"tag":127,"props":8945,"children":8946},{"style":688},[8947],{"type":56,"value":1236},{"type":29,"tag":127,"props":8949,"children":8950},{"class":677,"line":1450},[8951,8955,8959],{"type":29,"tag":127,"props":8952,"children":8953},{"style":682},[8954],{"type":56,"value":8164},{"type":29,"tag":127,"props":8956,"children":8957},{"style":688},[8958],{"type":56,"value":717},{"type":29,"tag":127,"props":8960,"children":8961},{"style":720},[8962],{"type":56,"value":8173},{"type":29,"tag":127,"props":8964,"children":8965},{"class":677,"line":1463},[8966,8970,8974],{"type":29,"tag":127,"props":8967,"children":8968},{"style":682},[8969],{"type":56,"value":8182},{"type":29,"tag":127,"props":8971,"children":8972},{"style":688},[8973],{"type":56,"value":717},{"type":29,"tag":127,"props":8975,"children":8976},{"style":720},[8977],{"type":56,"value":8191},{"type":29,"tag":127,"props":8979,"children":8980},{"class":677,"line":1476},[8981,8985,8989],{"type":29,"tag":127,"props":8982,"children":8983},{"style":682},[8984],{"type":56,"value":8200},{"type":29,"tag":127,"props":8986,"children":8987},{"style":688},[8988],{"type":56,"value":717},{"type":29,"tag":127,"props":8990,"children":8991},{"style":720},[8992],{"type":56,"value":8209},{"type":29,"tag":127,"props":8994,"children":8995},{"class":677,"line":1484},[8996,9000,9004],{"type":29,"tag":127,"props":8997,"children":8998},{"style":682},[8999],{"type":56,"value":6556},{"type":29,"tag":127,"props":9001,"children":9002},{"style":688},[9003],{"type":56,"value":717},{"type":29,"tag":127,"props":9005,"children":9006},{"style":720},[9007],{"type":56,"value":6565},{"type":29,"tag":127,"props":9009,"children":9010},{"class":677,"line":1497},[9011],{"type":29,"tag":127,"props":9012,"children":9013},{"emptyLinePlaceholder":500},[9014],{"type":56,"value":1399},{"type":29,"tag":127,"props":9016,"children":9017},{"class":677,"line":1510},[9018,9022,9026],{"type":29,"tag":127,"props":9019,"children":9020},{"style":682},[9021],{"type":56,"value":8240},{"type":29,"tag":127,"props":9023,"children":9024},{"style":688},[9025],{"type":56,"value":717},{"type":29,"tag":127,"props":9027,"children":9028},{"style":720},[9029],{"type":56,"value":8249},{"type":29,"tag":127,"props":9031,"children":9032},{"class":677,"line":1523},[9033,9037],{"type":29,"tag":127,"props":9034,"children":9035},{"style":682},[9036],{"type":56,"value":8257},{"type":29,"tag":127,"props":9038,"children":9039},{"style":688},[9040],{"type":56,"value":691},{"type":29,"tag":127,"props":9042,"children":9043},{"class":677,"line":1536},[9044,9048],{"type":29,"tag":127,"props":9045,"children":9046},{"style":688},[9047],{"type":56,"value":5483},{"type":29,"tag":127,"props":9049,"children":9050},{"style":720},[9051],{"type":56,"value":8274},{"type":29,"tag":127,"props":9053,"children":9054},{"class":677,"line":1549},[9055,9059],{"type":29,"tag":127,"props":9056,"children":9057},{"style":688},[9058],{"type":56,"value":5483},{"type":29,"tag":127,"props":9060,"children":9061},{"style":720},[9062],{"type":56,"value":8287},{"type":29,"tag":127,"props":9064,"children":9065},{"class":677,"line":2411},[9066,9070],{"type":29,"tag":127,"props":9067,"children":9068},{"style":688},[9069],{"type":56,"value":5483},{"type":29,"tag":127,"props":9071,"children":9072},{"style":720},[9073],{"type":56,"value":8300},{"type":29,"tag":127,"props":9075,"children":9076},{"class":677,"line":2419},[9077,9081],{"type":29,"tag":127,"props":9078,"children":9079},{"style":688},[9080],{"type":56,"value":5483},{"type":29,"tag":127,"props":9082,"children":9083},{"style":720},[9084],{"type":56,"value":8313},{"type":29,"tag":127,"props":9086,"children":9087},{"class":677,"line":2439},[9088,9092],{"type":29,"tag":127,"props":9089,"children":9090},{"style":688},[9091],{"type":56,"value":5483},{"type":29,"tag":127,"props":9093,"children":9094},{"style":720},[9095],{"type":56,"value":8326},{"type":29,"tag":127,"props":9097,"children":9098},{"class":677,"line":2460},[9099,9103],{"type":29,"tag":127,"props":9100,"children":9101},{"style":688},[9102],{"type":56,"value":5483},{"type":29,"tag":127,"props":9104,"children":9105},{"style":720},[9106],{"type":56,"value":8339},{"type":29,"tag":127,"props":9108,"children":9109},{"class":677,"line":2472},[9110,9114],{"type":29,"tag":127,"props":9111,"children":9112},{"style":688},[9113],{"type":56,"value":5483},{"type":29,"tag":127,"props":9115,"children":9116},{"style":720},[9117],{"type":56,"value":8352},{"type":29,"tag":127,"props":9119,"children":9120},{"class":677,"line":2488},[9121,9125],{"type":29,"tag":127,"props":9122,"children":9123},{"style":688},[9124],{"type":56,"value":5483},{"type":29,"tag":127,"props":9126,"children":9127},{"style":720},[9128],{"type":56,"value":8365},{"type":29,"tag":127,"props":9130,"children":9131},{"class":677,"line":2496},[9132,9136],{"type":29,"tag":127,"props":9133,"children":9134},{"style":688},[9135],{"type":56,"value":5483},{"type":29,"tag":127,"props":9137,"children":9138},{"style":720},[9139],{"type":56,"value":8378},{"type":29,"tag":127,"props":9141,"children":9142},{"class":677,"line":1970},[9143,9147],{"type":29,"tag":127,"props":9144,"children":9145},{"style":688},[9146],{"type":56,"value":5483},{"type":29,"tag":127,"props":9148,"children":9149},{"style":720},[9150],{"type":56,"value":8339},{"type":29,"tag":127,"props":9152,"children":9153},{"class":677,"line":1971},[9154,9158],{"type":29,"tag":127,"props":9155,"children":9156},{"style":682},[9157],{"type":56,"value":5471},{"type":29,"tag":127,"props":9159,"children":9160},{"style":688},[9161],{"type":56,"value":691},{"type":29,"tag":127,"props":9163,"children":9164},{"class":677,"line":1972},[9165,9169],{"type":29,"tag":127,"props":9166,"children":9167},{"style":688},[9168],{"type":56,"value":5483},{"type":29,"tag":127,"props":9170,"children":9171},{"style":720},[9172],{"type":56,"value":8414},{"type":29,"tag":127,"props":9174,"children":9175},{"class":677,"line":1973},[9176],{"type":29,"tag":127,"props":9177,"children":9178},{"emptyLinePlaceholder":500},[9179],{"type":56,"value":1399},{"type":29,"tag":127,"props":9181,"children":9182},{"class":677,"line":2559},[9183,9187],{"type":29,"tag":127,"props":9184,"children":9185},{"style":682},[9186],{"type":56,"value":6613},{"type":29,"tag":127,"props":9188,"children":9189},{"style":688},[9190],{"type":56,"value":691},{"type":29,"tag":127,"props":9192,"children":9193},{"class":677,"line":2568},[9194,9198,9202,9206],{"type":29,"tag":127,"props":9195,"children":9196},{"style":688},[9197],{"type":56,"value":5483},{"type":29,"tag":127,"props":9199,"children":9200},{"style":682},[9201],{"type":56,"value":6630},{"type":29,"tag":127,"props":9203,"children":9204},{"style":688},[9205],{"type":56,"value":717},{"type":29,"tag":127,"props":9207,"children":9208},{"style":720},[9209],{"type":56,"value":6639},{"type":29,"tag":127,"props":9211,"children":9212},{"class":677,"line":2581},[9213,9217],{"type":29,"tag":127,"props":9214,"children":9215},{"style":682},[9216],{"type":56,"value":6648},{"type":29,"tag":127,"props":9218,"children":9219},{"style":688},[9220],{"type":56,"value":691},{"type":29,"tag":127,"props":9222,"children":9223},{"class":677,"line":2594},[9224,9228],{"type":29,"tag":127,"props":9225,"children":9226},{"style":688},[9227],{"type":56,"value":6661},{"type":29,"tag":127,"props":9229,"children":9230},{"style":720},[9231],{"type":56,"value":6666},{"type":29,"tag":127,"props":9233,"children":9234},{"class":677,"line":2623},[9235,9239,9243],{"type":29,"tag":127,"props":9236,"children":9237},{"style":682},[9238],{"type":56,"value":8481},{"type":29,"tag":127,"props":9240,"children":9241},{"style":688},[9242],{"type":56,"value":717},{"type":29,"tag":127,"props":9244,"children":9245},{"style":720},[9246],{"type":56,"value":8490},{"type":29,"tag":127,"props":9248,"children":9249},{"class":677,"line":2631},[9250,9254],{"type":29,"tag":127,"props":9251,"children":9252},{"style":682},[9253],{"type":56,"value":7013},{"type":29,"tag":127,"props":9255,"children":9256},{"style":688},[9257],{"type":56,"value":691},{"type":29,"tag":127,"props":9259,"children":9260},{"class":677,"line":2639},[9261,9265],{"type":29,"tag":127,"props":9262,"children":9263},{"style":682},[9264],{"type":56,"value":8509},{"type":29,"tag":127,"props":9266,"children":9267},{"style":688},[9268],{"type":56,"value":691},{"type":29,"tag":127,"props":9270,"children":9271},{"class":677,"line":2660},[9272,9276],{"type":29,"tag":127,"props":9273,"children":9274},{"style":682},[9275],{"type":56,"value":8521},{"type":29,"tag":127,"props":9277,"children":9278},{"style":688},[9279],{"type":56,"value":691},{"type":29,"tag":127,"props":9281,"children":9282},{"class":677,"line":2673},[9283,9287,9291],{"type":29,"tag":127,"props":9284,"children":9285},{"style":682},[9286],{"type":56,"value":8533},{"type":29,"tag":127,"props":9288,"children":9289},{"style":688},[9290],{"type":56,"value":717},{"type":29,"tag":127,"props":9292,"children":9293},{"style":720},[9294],{"type":56,"value":8542},{"type":29,"tag":127,"props":9296,"children":9297},{"class":677,"line":2686},[9298,9302,9306],{"type":29,"tag":127,"props":9299,"children":9300},{"style":682},[9301],{"type":56,"value":8550},{"type":29,"tag":127,"props":9303,"children":9304},{"style":688},[9305],{"type":56,"value":717},{"type":29,"tag":127,"props":9307,"children":9308},{"style":720},[9309],{"type":56,"value":8559},{"type":29,"tag":127,"props":9311,"children":9312},{"class":677,"line":2707},[9313,9317],{"type":29,"tag":127,"props":9314,"children":9315},{"style":682},[9316],{"type":56,"value":5513},{"type":29,"tag":127,"props":9318,"children":9319},{"style":688},[9320],{"type":56,"value":691},{"type":29,"tag":127,"props":9322,"children":9323},{"class":677,"line":2724},[9324,9328,9332,9336],{"type":29,"tag":127,"props":9325,"children":9326},{"style":688},[9327],{"type":56,"value":5483},{"type":29,"tag":127,"props":9329,"children":9330},{"style":682},[9331],{"type":56,"value":5746},{"type":29,"tag":127,"props":9333,"children":9334},{"style":688},[9335],{"type":56,"value":717},{"type":29,"tag":127,"props":9337,"children":9338},{"style":720},[9339],{"type":56,"value":7736},{"type":29,"tag":127,"props":9341,"children":9342},{"class":677,"line":2732},[9343,9347,9351,9355],{"type":29,"tag":127,"props":9344,"children":9345},{"style":688},[9346],{"type":56,"value":5483},{"type":29,"tag":127,"props":9348,"children":9349},{"style":682},[9350],{"type":56,"value":5746},{"type":29,"tag":127,"props":9352,"children":9353},{"style":688},[9354],{"type":56,"value":717},{"type":29,"tag":127,"props":9356,"children":9357},{"style":720},[9358],{"type":56,"value":5755},{"type":29,"tag":127,"props":9360,"children":9361},{"class":677,"line":2753},[9362,9366,9370],{"type":29,"tag":127,"props":9363,"children":9364},{"style":682},[9365],{"type":56,"value":5763},{"type":29,"tag":127,"props":9367,"children":9368},{"style":688},[9369],{"type":56,"value":717},{"type":29,"tag":127,"props":9371,"children":9372},{"style":720},[9373],{"type":56,"value":5772},{"type":29,"tag":127,"props":9375,"children":9376},{"class":677,"line":2770},[9377,9381,9385,9389],{"type":29,"tag":127,"props":9378,"children":9379},{"style":688},[9380],{"type":56,"value":5483},{"type":29,"tag":127,"props":9382,"children":9383},{"style":682},[9384],{"type":56,"value":5746},{"type":29,"tag":127,"props":9386,"children":9387},{"style":688},[9388],{"type":56,"value":717},{"type":29,"tag":127,"props":9390,"children":9391},{"style":720},[9392],{"type":56,"value":5792},{"type":29,"tag":127,"props":9394,"children":9395},{"class":677,"line":2778},[9396],{"type":29,"tag":127,"props":9397,"children":9398},{"emptyLinePlaceholder":500},[9399],{"type":56,"value":1399},{"type":29,"tag":127,"props":9401,"children":9402},{"class":677,"line":2791},[9403,9407],{"type":29,"tag":127,"props":9404,"children":9405},{"style":682},[9406],{"type":56,"value":7568},{"type":29,"tag":127,"props":9408,"children":9409},{"style":688},[9410],{"type":56,"value":691},{"type":29,"tag":127,"props":9412,"children":9413},{"class":677,"line":2804},[9414,9418],{"type":29,"tag":127,"props":9415,"children":9416},{"style":682},[9417],{"type":56,"value":7580},{"type":29,"tag":127,"props":9419,"children":9420},{"style":688},[9421],{"type":56,"value":691},{"type":29,"tag":127,"props":9423,"children":9424},{"class":677,"line":2822},[9425,9429,9433],{"type":29,"tag":127,"props":9426,"children":9427},{"style":682},[9428],{"type":56,"value":7593},{"type":29,"tag":127,"props":9430,"children":9431},{"style":688},[9432],{"type":56,"value":717},{"type":29,"tag":127,"props":9434,"children":9435},{"style":720},[9436],{"type":56,"value":6502},{"type":29,"tag":127,"props":9438,"children":9439},{"class":677,"line":2830},[9440,9444,9448,9452],{"type":29,"tag":127,"props":9441,"children":9442},{"style":682},[9443],{"type":56,"value":7609},{"type":29,"tag":127,"props":9445,"children":9446},{"style":688},[9447],{"type":56,"value":5674},{"type":29,"tag":127,"props":9449,"children":9450},{"style":720},[9451],{"type":56,"value":5679},{"type":29,"tag":127,"props":9453,"children":9454},{"style":688},[9455],{"type":56,"value":5684},{"type":29,"tag":127,"props":9457,"children":9458},{"class":677,"line":2843},[9459,9463,9467],{"type":29,"tag":127,"props":9460,"children":9461},{"style":682},[9462],{"type":56,"value":7629},{"type":29,"tag":127,"props":9464,"children":9465},{"style":688},[9466],{"type":56,"value":717},{"type":29,"tag":127,"props":9468,"children":9469},{"style":720},[9470],{"type":56,"value":7553},{"type":29,"tag":127,"props":9472,"children":9473},{"class":677,"line":2852},[9474,9478],{"type":29,"tag":127,"props":9475,"children":9476},{"style":682},[9477],{"type":56,"value":7645},{"type":29,"tag":127,"props":9479,"children":9480},{"style":688},[9481],{"type":56,"value":691},{"type":29,"tag":127,"props":9483,"children":9484},{"class":677,"line":2861},[9485,9489],{"type":29,"tag":127,"props":9486,"children":9487},{"style":688},[9488],{"type":56,"value":746},{"type":29,"tag":127,"props":9490,"children":9491},{"style":720},[9492],{"type":56,"value":7661},{"type":29,"tag":127,"props":9494,"children":9495},{"class":677,"line":2874},[9496,9500],{"type":29,"tag":127,"props":9497,"children":9498},{"style":682},[9499],{"type":56,"value":7669},{"type":29,"tag":127,"props":9501,"children":9502},{"style":688},[9503],{"type":56,"value":691},{"type":29,"tag":127,"props":9505,"children":9506},{"class":677,"line":2882},[9507,9511],{"type":29,"tag":127,"props":9508,"children":9509},{"style":682},[9510],{"type":56,"value":7681},{"type":29,"tag":127,"props":9512,"children":9513},{"style":688},[9514],{"type":56,"value":691},{"type":29,"tag":127,"props":9516,"children":9517},{"class":677,"line":2891},[9518,9522,9526],{"type":29,"tag":127,"props":9519,"children":9520},{"style":682},[9521],{"type":56,"value":7693},{"type":29,"tag":127,"props":9523,"children":9524},{"style":688},[9525],{"type":56,"value":717},{"type":29,"tag":127,"props":9527,"children":9528},{"style":720},[9529],{"type":56,"value":7702},{"type":29,"tag":127,"props":9531,"children":9532},{"class":677,"line":2899},[9533,9537],{"type":29,"tag":127,"props":9534,"children":9535},{"style":682},[9536],{"type":56,"value":7711},{"type":29,"tag":127,"props":9538,"children":9539},{"style":688},[9540],{"type":56,"value":691},{"type":29,"tag":127,"props":9542,"children":9543},{"class":677,"line":2912},[9544,9548,9552,9556],{"type":29,"tag":127,"props":9545,"children":9546},{"style":688},[9547],{"type":56,"value":746},{"type":29,"tag":127,"props":9549,"children":9550},{"style":682},[9551],{"type":56,"value":5746},{"type":29,"tag":127,"props":9553,"children":9554},{"style":688},[9555],{"type":56,"value":717},{"type":29,"tag":127,"props":9557,"children":9558},{"style":720},[9559],{"type":56,"value":7736},{"type":29,"tag":127,"props":9561,"children":9562},{"class":677,"line":2925},[9563,9567,9571,9575],{"type":29,"tag":127,"props":9564,"children":9565},{"style":688},[9566],{"type":56,"value":746},{"type":29,"tag":127,"props":9568,"children":9569},{"style":682},[9570],{"type":56,"value":5746},{"type":29,"tag":127,"props":9572,"children":9573},{"style":688},[9574],{"type":56,"value":717},{"type":29,"tag":127,"props":9576,"children":9577},{"style":720},[9578],{"type":56,"value":5755},{"type":29,"tag":127,"props":9580,"children":9581},{"class":677,"line":2946},[9582,9586,9590],{"type":29,"tag":127,"props":9583,"children":9584},{"style":682},[9585],{"type":56,"value":7765},{"type":29,"tag":127,"props":9587,"children":9588},{"style":688},[9589],{"type":56,"value":717},{"type":29,"tag":127,"props":9591,"children":9592},{"style":720},[9593],{"type":56,"value":5772},{"type":29,"tag":127,"props":9595,"children":9596},{"class":677,"line":2959},[9597,9601,9605,9609],{"type":29,"tag":127,"props":9598,"children":9599},{"style":688},[9600],{"type":56,"value":746},{"type":29,"tag":127,"props":9602,"children":9603},{"style":682},[9604],{"type":56,"value":5746},{"type":29,"tag":127,"props":9606,"children":9607},{"style":688},[9608],{"type":56,"value":717},{"type":29,"tag":127,"props":9610,"children":9611},{"style":720},[9612],{"type":56,"value":5792},{"type":29,"tag":1838,"props":9614,"children":9615},{},[9616],{"type":56,"value":1842},{"title":7,"searchDepth":342,"depth":342,"links":9618},[9619,9622,9625],{"id":7409,"depth":342,"text":7412,"children":9620},[9621],{"id":7514,"depth":706,"text":7517},{"id":7811,"depth":342,"text":7379,"children":9623},[9624],{"id":7859,"depth":706,"text":7862},{"id":8683,"depth":342,"text":8686},{"_path":563,"_dir":515,"_draft":6,"_partial":6,"_locale":7,"title":564,"description":565,"author":518,"image":519,"releaseDate":566,"blogCategories":9627,"articleTags":9628,"tags":9629,"body":9630,"_type":346,"_id":570,"_source":348,"_file":571,"_stem":572,"_extension":351},[522,523],[523,536],[24],{"type":26,"children":9631,"toc":11090},[9632,9637,9642,9647,9652,9657,9675,9680,9721,9727,9740,9753,9758,9764,9775,9788,9797,9803,9808,9920,10438,10473,10486,10489,10494,10655,10668,10674,10679,10749,10754,10760,10765,10778,10791,10825,10852,10864,10883,10896,10899,10904,10917,10937,10942,10947,11067,11086],{"type":29,"tag":48,"props":9633,"children":9634},{},[9635],{"type":56,"value":9636},"Die Verwaltung eines Servers mit mehreren Diensten kann knifflig sein. Nicht jede Software ist miteinander kompatibel. Beispielsweise gibt es Anforderungen an Datenbank- oder PHP-Versionen.",{"type":29,"tag":48,"props":9638,"children":9639},{},[9640],{"type":56,"value":9641},"Außerdem sollte die Software auf dem neuesten Stand sein, um mögliche Sicherheitsrisiken zu minimieren.",{"type":29,"tag":48,"props":9643,"children":9644},{},[9645],{"type":56,"value":9646},"Es gibt viele Möglichkeiten, damit umzugehen, wie etwa Ansible, Chef usw.",{"type":29,"tag":48,"props":9648,"children":9649},{},[9650],{"type":56,"value":9651},"Unser Ziel war eine einfach zu bedienende, automatisierte und kostenlose Lösung.",{"type":29,"tag":48,"props":9653,"children":9654},{},[9655],{"type":56,"value":9656},"Hier sind die Ziele:",{"type":29,"tag":810,"props":9658,"children":9659},{},[9660,9665,9670],{"type":29,"tag":814,"props":9661,"children":9662},{},[9663],{"type":56,"value":9664},"den GitOps-Ansatz nutzen, um die Konfiguration zu speichern und per Versionskontrolle nachvollziehbar zu machen",{"type":29,"tag":814,"props":9666,"children":9667},{},[9668],{"type":56,"value":9669},"Container verwenden, um die Software auszuführen",{"type":29,"tag":814,"props":9671,"children":9672},{},[9673],{"type":56,"value":9674},"Sicherheitsupdates automatisch ausspielen und Minor-/Major-Updates per Opt-in steuern",{"type":29,"tag":48,"props":9676,"children":9677},{},[9678],{"type":56,"value":9679},"Wir haben uns am Ende für den folgenden Stack entschieden:",{"type":29,"tag":810,"props":9681,"children":9682},{},[9683,9699,9710],{"type":29,"tag":814,"props":9684,"children":9685},{},[9686,9691,9693,9697],{"type":29,"tag":645,"props":9687,"children":9689},{"href":9688},"https://www.docker.com/",[9690],{"type":56,"value":378},{"type":56,"value":9692}," und ",{"type":29,"tag":645,"props":9694,"children":9695},{"href":912},[9696],{"type":56,"value":915},{"type":56,"value":9698}," zum Verwalten der Software",{"type":29,"tag":814,"props":9700,"children":9701},{},[9702,9708],{"type":29,"tag":645,"props":9703,"children":9705},{"href":9704},"https://about.gitlab.com/",[9706],{"type":56,"value":9707},"GitLab",{"type":56,"value":9709}," zum Speichern aller Compose-Dateien",{"type":29,"tag":814,"props":9711,"children":9712},{},[9713,9719],{"type":29,"tag":645,"props":9714,"children":9716},{"href":9715},"https://docs.renovatebot.com",[9717],{"type":56,"value":9718},"Renovate Bot",{"type":56,"value":9720},", um die Software aktuell zu halten",{"type":29,"tag":90,"props":9722,"children":9724},{"id":9723},"über-den-stack",[9725],{"type":56,"value":9726},"Über den Stack",{"type":29,"tag":48,"props":9728,"children":9729},{},[9730,9732,9738],{"type":56,"value":9731},"Wir verwenden Docker bereits seit einiger Zeit in der Produktion. Je nach Situation erstellen wir die Compose-Datei direkt auf dem Server, verwalten sie über Portainer oder übertragen sie per ",{"type":29,"tag":672,"props":9733,"children":9735},{"className":9734},[],[9736],{"type":56,"value":9737},"scp",{"type":56,"value":9739}," in eine Pipeline.",{"type":29,"tag":48,"props":9741,"children":9742},{},[9743,9745,9751],{"type":56,"value":9744},"GitLab ist unser primäres Tool für die Versionskontrolle. Zusätzlich kümmert sich ein ",{"type":29,"tag":645,"props":9746,"children":9748},{"href":9747},"https://docs.gitlab.com/runner/",[9749],{"type":56,"value":9750},"GitLab Runner",{"type":56,"value":9752}," um das Ausführen der Pipelines.",{"type":29,"tag":48,"props":9754,"children":9755},{},[9756],{"type":56,"value":9757},"Renovate automatisiert Abhängigkeitsupdates. PHP, Go, Python, Docker – um nur ein paar zu nennen. Wir nutzen es bereits in verschiedenen Projekten.",{"type":29,"tag":90,"props":9759,"children":9761},{"id":9760},"container-mit-docker-und-docker-compose",[9762],{"type":56,"value":9763},"Container mit Docker und Docker Compose",{"type":29,"tag":48,"props":9765,"children":9766},{},[9767,9769,9774],{"type":56,"value":9768},"Der Hauptgrund, warum wir Docker gewählt haben, ist die Möglichkeit, auf einen remoten Docker-Host zuzugreifen und Docker-Befehle ausführen zu können.\nWeitere Informationen findest du in der ",{"type":29,"tag":645,"props":9770,"children":9772},{"href":9771},"https://docs.docker.com/reference/cli/docker/#host",[9773],{"type":56,"value":1881},{"type":56,"value":1651},{"type":29,"tag":48,"props":9776,"children":9777},{},[9778,9780,9786],{"type":56,"value":9779},"Wir verwenden ",{"type":29,"tag":672,"props":9781,"children":9783},{"className":9782},[],[9784],{"type":56,"value":9785},"ssh",{"type":56,"value":9787},", um auf unseren Zielserver zuzugreifen.",{"type":29,"tag":48,"props":9789,"children":9790},{},[9791],{"type":29,"tag":672,"props":9792,"children":9794},{"className":9793},[],[9795],{"type":56,"value":9796},"DOCKER_HOST=ssh://[username@]\u003CIP or host>[:port] docker compose up --wait",{"type":29,"tag":90,"props":9798,"children":9800},{"id":9799},"gitops-mit-gitlab",[9801],{"type":56,"value":9802},"GitOps mit GitLab",{"type":29,"tag":48,"props":9804,"children":9805},{},[9806],{"type":56,"value":9807},"Die Idee hinter GitOps ist, ein Git-Repository zur Ablage der Konfiguration zu verwenden. Hier ein Beispiel:",{"type":29,"tag":659,"props":9809,"children":9811},{"className":3021,"code":9810,"language":3023,"meta":7,"style":7},".\n├──.gitlab-ci.yml             # Pipeline-Definition\n├── renovate.json             # Renovate-Konfiguration\n├── nextcloud\n│   ├── docker-compose.yml   # Nextcloud Datei-Hosting und Zusammenarbeit\n└── traefik\n    └── docker-compose.yml   # Traefik Reverse-Proxy-Konfiguration\n\n",[9812],{"type":29,"tag":672,"props":9813,"children":9814},{"__ignoreMap":7},[9815,9824,9837,9855,9867,9890,9903],{"type":29,"tag":127,"props":9816,"children":9817},{"class":677,"line":678},[9818],{"type":29,"tag":127,"props":9819,"children":9821},{"style":9820},"--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#66D9EF",[9822],{"type":56,"value":9823},".\n",{"type":29,"tag":127,"props":9825,"children":9826},{"class":677,"line":342},[9827,9832],{"type":29,"tag":127,"props":9828,"children":9829},{"style":3033},[9830],{"type":56,"value":9831},"├──.gitlab-ci.yml",{"type":29,"tag":127,"props":9833,"children":9834},{"style":1796},[9835],{"type":56,"value":9836},"             # Pipeline-Definition\n",{"type":29,"tag":127,"props":9838,"children":9839},{"class":677,"line":706},[9840,9845,9850],{"type":29,"tag":127,"props":9841,"children":9842},{"style":3033},[9843],{"type":56,"value":9844},"├──",{"type":29,"tag":127,"props":9846,"children":9847},{"style":720},[9848],{"type":56,"value":9849}," renovate.json",{"type":29,"tag":127,"props":9851,"children":9852},{"style":1796},[9853],{"type":56,"value":9854},"             # Renovate-Konfiguration\n",{"type":29,"tag":127,"props":9856,"children":9857},{"class":677,"line":726},[9858,9862],{"type":29,"tag":127,"props":9859,"children":9860},{"style":3033},[9861],{"type":56,"value":9844},{"type":29,"tag":127,"props":9863,"children":9864},{"style":720},[9865],{"type":56,"value":9866}," nextcloud\n",{"type":29,"tag":127,"props":9868,"children":9869},{"class":677,"line":664},[9870,9875,9880,9885],{"type":29,"tag":127,"props":9871,"children":9872},{"style":3033},[9873],{"type":56,"value":9874},"│",{"type":29,"tag":127,"props":9876,"children":9877},{"style":720},[9878],{"type":56,"value":9879},"   ├──",{"type":29,"tag":127,"props":9881,"children":9882},{"style":720},[9883],{"type":56,"value":9884}," docker-compose.yml",{"type":29,"tag":127,"props":9886,"children":9887},{"style":1796},[9888],{"type":56,"value":9889},"   # Nextcloud Datei-Hosting und Zusammenarbeit\n",{"type":29,"tag":127,"props":9891,"children":9892},{"class":677,"line":665},[9893,9898],{"type":29,"tag":127,"props":9894,"children":9895},{"style":3033},[9896],{"type":56,"value":9897},"└──",{"type":29,"tag":127,"props":9899,"children":9900},{"style":720},[9901],{"type":56,"value":9902}," traefik\n",{"type":29,"tag":127,"props":9904,"children":9905},{"class":677,"line":666},[9906,9911,9915],{"type":29,"tag":127,"props":9907,"children":9908},{"style":3033},[9909],{"type":56,"value":9910},"    └──",{"type":29,"tag":127,"props":9912,"children":9913},{"style":720},[9914],{"type":56,"value":9884},{"type":29,"tag":127,"props":9916,"children":9917},{"style":1796},[9918],{"type":56,"value":9919},"   # Traefik Reverse-Proxy-Konfiguration\n",{"type":29,"tag":659,"props":9921,"children":9924},{"className":669,"code":9922,"filename":9923,"language":508,"meta":7,"style":7},"volumes:\n  nextcloud:\n  db:\n\nservices:\n  db:\n    image: mariadb:11.8\n    restart: unless-stopped\n    volumes:\n      - db:/var/lib/mysql\n    environment:\n      - MARIADB_ROOT_PASSWORD=${NEXTCLOUD_MARIADB_ROOT_PASSWORD:?error}\n      - MARIADB_PASSWORD=${NEXTCLOUD_MARIADB_PASSWORD:?error}\n      - MARIADB_DATABASE=nextcloud\n      - MARIADB_USER=nextcloud\n    command:\n      - --transaction-isolation=READ-COMMITTED\n      - --log-bin=binlog\n      - --binlog-format=ROW\n    healthcheck:\n      test: [\"CMD\", \"healthcheck.sh\", \"--connect\", \"--innodb_initialized\"]\n      interval: 15s\n      timeout: 5s\n      retries: 6\n\n  nextcloud:\n    image: nextcloud:32.0.0\n    restart: unless-stopped\n    depends_on:\n      db:\n        condition: service_healthy\n    volumes:\n      - nextcloud:/var/www/html\n    environment:\n      - MYSQL_PASSWORD=${NEXTCLOUD_MARIADB_PASSWORD:?error}\n      - MYSQL_DATABASE=nextcloud\n      - MYSQL_USER=nextcloud\n      - MYSQL_HOST=db\n","nextcloud/docker-compose.yaml",[9925],{"type":29,"tag":672,"props":9926,"children":9927},{"__ignoreMap":7},[9928,9939,9951,9963,9970,9981,9992,10008,10024,10035,10047,10059,10071,10083,10095,10107,10118,10130,10142,10154,10166,10215,10232,10249,10266,10273,10284,10300,10315,10327,10339,10356,10367,10379,10390,10402,10414,10426],{"type":29,"tag":127,"props":9929,"children":9930},{"class":677,"line":678},[9931,9935],{"type":29,"tag":127,"props":9932,"children":9933},{"style":682},[9934],{"type":56,"value":1212},{"type":29,"tag":127,"props":9936,"children":9937},{"style":688},[9938],{"type":56,"value":691},{"type":29,"tag":127,"props":9940,"children":9941},{"class":677,"line":342},[9942,9947],{"type":29,"tag":127,"props":9943,"children":9944},{"style":682},[9945],{"type":56,"value":9946},"  nextcloud",{"type":29,"tag":127,"props":9948,"children":9949},{"style":688},[9950],{"type":56,"value":691},{"type":29,"tag":127,"props":9952,"children":9953},{"class":677,"line":706},[9954,9959],{"type":29,"tag":127,"props":9955,"children":9956},{"style":682},[9957],{"type":56,"value":9958},"  db",{"type":29,"tag":127,"props":9960,"children":9961},{"style":688},[9962],{"type":56,"value":691},{"type":29,"tag":127,"props":9964,"children":9965},{"class":677,"line":726},[9966],{"type":29,"tag":127,"props":9967,"children":9968},{"emptyLinePlaceholder":500},[9969],{"type":56,"value":1399},{"type":29,"tag":127,"props":9971,"children":9972},{"class":677,"line":664},[9973,9977],{"type":29,"tag":127,"props":9974,"children":9975},{"style":682},[9976],{"type":56,"value":685},{"type":29,"tag":127,"props":9978,"children":9979},{"style":688},[9980],{"type":56,"value":691},{"type":29,"tag":127,"props":9982,"children":9983},{"class":677,"line":665},[9984,9988],{"type":29,"tag":127,"props":9985,"children":9986},{"style":682},[9987],{"type":56,"value":9958},{"type":29,"tag":127,"props":9989,"children":9990},{"style":688},[9991],{"type":56,"value":691},{"type":29,"tag":127,"props":9993,"children":9994},{"class":677,"line":666},[9995,9999,10003],{"type":29,"tag":127,"props":9996,"children":9997},{"style":682},[9998],{"type":56,"value":712},{"type":29,"tag":127,"props":10000,"children":10001},{"style":688},[10002],{"type":56,"value":717},{"type":29,"tag":127,"props":10004,"children":10005},{"style":720},[10006],{"type":56,"value":10007},"mariadb:11.8\n",{"type":29,"tag":127,"props":10009,"children":10010},{"class":677,"line":667},[10011,10015,10019],{"type":29,"tag":127,"props":10012,"children":10013},{"style":682},[10014],{"type":56,"value":1284},{"type":29,"tag":127,"props":10016,"children":10017},{"style":688},[10018],{"type":56,"value":717},{"type":29,"tag":127,"props":10020,"children":10021},{"style":720},[10022],{"type":56,"value":10023},"unless-stopped\n",{"type":29,"tag":127,"props":10025,"children":10026},{"class":677,"line":668},[10027,10031],{"type":29,"tag":127,"props":10028,"children":10029},{"style":682},[10030],{"type":56,"value":1529},{"type":29,"tag":127,"props":10032,"children":10033},{"style":688},[10034],{"type":56,"value":691},{"type":29,"tag":127,"props":10036,"children":10037},{"class":677,"line":1329},[10038,10042],{"type":29,"tag":127,"props":10039,"children":10040},{"style":688},[10041],{"type":56,"value":746},{"type":29,"tag":127,"props":10043,"children":10044},{"style":720},[10045],{"type":56,"value":10046},"db:/var/lib/mysql\n",{"type":29,"tag":127,"props":10048,"children":10049},{"class":677,"line":1342},[10050,10055],{"type":29,"tag":127,"props":10051,"children":10052},{"style":682},[10053],{"type":56,"value":10054},"    environment",{"type":29,"tag":127,"props":10056,"children":10057},{"style":688},[10058],{"type":56,"value":691},{"type":29,"tag":127,"props":10060,"children":10061},{"class":677,"line":118},[10062,10066],{"type":29,"tag":127,"props":10063,"children":10064},{"style":688},[10065],{"type":56,"value":746},{"type":29,"tag":127,"props":10067,"children":10068},{"style":720},[10069],{"type":56,"value":10070},"MARIADB_ROOT_PASSWORD=${NEXTCLOUD_MARIADB_ROOT_PASSWORD:?error}\n",{"type":29,"tag":127,"props":10072,"children":10073},{"class":677,"line":1367},[10074,10078],{"type":29,"tag":127,"props":10075,"children":10076},{"style":688},[10077],{"type":56,"value":746},{"type":29,"tag":127,"props":10079,"children":10080},{"style":720},[10081],{"type":56,"value":10082},"MARIADB_PASSWORD=${NEXTCLOUD_MARIADB_PASSWORD:?error}\n",{"type":29,"tag":127,"props":10084,"children":10085},{"class":677,"line":1380},[10086,10090],{"type":29,"tag":127,"props":10087,"children":10088},{"style":688},[10089],{"type":56,"value":746},{"type":29,"tag":127,"props":10091,"children":10092},{"style":720},[10093],{"type":56,"value":10094},"MARIADB_DATABASE=nextcloud\n",{"type":29,"tag":127,"props":10096,"children":10097},{"class":677,"line":1393},[10098,10102],{"type":29,"tag":127,"props":10099,"children":10100},{"style":688},[10101],{"type":56,"value":746},{"type":29,"tag":127,"props":10103,"children":10104},{"style":720},[10105],{"type":56,"value":10106},"MARIADB_USER=nextcloud\n",{"type":29,"tag":127,"props":10108,"children":10109},{"class":677,"line":1402},[10110,10114],{"type":29,"tag":127,"props":10111,"children":10112},{"style":682},[10113],{"type":56,"value":1335},{"type":29,"tag":127,"props":10115,"children":10116},{"style":688},[10117],{"type":56,"value":691},{"type":29,"tag":127,"props":10119,"children":10120},{"class":677,"line":1415},[10121,10125],{"type":29,"tag":127,"props":10122,"children":10123},{"style":688},[10124],{"type":56,"value":746},{"type":29,"tag":127,"props":10126,"children":10127},{"style":720},[10128],{"type":56,"value":10129},"--transaction-isolation=READ-COMMITTED\n",{"type":29,"tag":127,"props":10131,"children":10132},{"class":677,"line":1428},[10133,10137],{"type":29,"tag":127,"props":10134,"children":10135},{"style":688},[10136],{"type":56,"value":746},{"type":29,"tag":127,"props":10138,"children":10139},{"style":720},[10140],{"type":56,"value":10141},"--log-bin=binlog\n",{"type":29,"tag":127,"props":10143,"children":10144},{"class":677,"line":1437},[10145,10149],{"type":29,"tag":127,"props":10146,"children":10147},{"style":688},[10148],{"type":56,"value":746},{"type":29,"tag":127,"props":10150,"children":10151},{"style":720},[10152],{"type":56,"value":10153},"--binlog-format=ROW\n",{"type":29,"tag":127,"props":10155,"children":10156},{"class":677,"line":1450},[10157,10162],{"type":29,"tag":127,"props":10158,"children":10159},{"style":682},[10160],{"type":56,"value":10161},"    healthcheck",{"type":29,"tag":127,"props":10163,"children":10164},{"style":688},[10165],{"type":56,"value":691},{"type":29,"tag":127,"props":10167,"children":10168},{"class":677,"line":1463},[10169,10174,10178,10183,10188,10193,10197,10202,10206,10211],{"type":29,"tag":127,"props":10170,"children":10171},{"style":682},[10172],{"type":56,"value":10173},"      test",{"type":29,"tag":127,"props":10175,"children":10176},{"style":688},[10177],{"type":56,"value":5674},{"type":29,"tag":127,"props":10179,"children":10180},{"style":720},[10181],{"type":56,"value":10182},"\"CMD\"",{"type":29,"tag":127,"props":10184,"children":10185},{"style":688},[10186],{"type":56,"value":10187},", ",{"type":29,"tag":127,"props":10189,"children":10190},{"style":720},[10191],{"type":56,"value":10192},"\"healthcheck.sh\"",{"type":29,"tag":127,"props":10194,"children":10195},{"style":688},[10196],{"type":56,"value":10187},{"type":29,"tag":127,"props":10198,"children":10199},{"style":720},[10200],{"type":56,"value":10201},"\"--connect\"",{"type":29,"tag":127,"props":10203,"children":10204},{"style":688},[10205],{"type":56,"value":10187},{"type":29,"tag":127,"props":10207,"children":10208},{"style":720},[10209],{"type":56,"value":10210},"\"--innodb_initialized\"",{"type":29,"tag":127,"props":10212,"children":10213},{"style":688},[10214],{"type":56,"value":5684},{"type":29,"tag":127,"props":10216,"children":10217},{"class":677,"line":1476},[10218,10223,10227],{"type":29,"tag":127,"props":10219,"children":10220},{"style":682},[10221],{"type":56,"value":10222},"      interval",{"type":29,"tag":127,"props":10224,"children":10225},{"style":688},[10226],{"type":56,"value":717},{"type":29,"tag":127,"props":10228,"children":10229},{"style":720},[10230],{"type":56,"value":10231},"15s\n",{"type":29,"tag":127,"props":10233,"children":10234},{"class":677,"line":1484},[10235,10240,10244],{"type":29,"tag":127,"props":10236,"children":10237},{"style":682},[10238],{"type":56,"value":10239},"      timeout",{"type":29,"tag":127,"props":10241,"children":10242},{"style":688},[10243],{"type":56,"value":717},{"type":29,"tag":127,"props":10245,"children":10246},{"style":720},[10247],{"type":56,"value":10248},"5s\n",{"type":29,"tag":127,"props":10250,"children":10251},{"class":677,"line":1497},[10252,10257,10261],{"type":29,"tag":127,"props":10253,"children":10254},{"style":682},[10255],{"type":56,"value":10256},"      retries",{"type":29,"tag":127,"props":10258,"children":10259},{"style":688},[10260],{"type":56,"value":717},{"type":29,"tag":127,"props":10262,"children":10263},{"style":2303},[10264],{"type":56,"value":10265},"6\n",{"type":29,"tag":127,"props":10267,"children":10268},{"class":677,"line":1510},[10269],{"type":29,"tag":127,"props":10270,"children":10271},{"emptyLinePlaceholder":500},[10272],{"type":56,"value":1399},{"type":29,"tag":127,"props":10274,"children":10275},{"class":677,"line":1523},[10276,10280],{"type":29,"tag":127,"props":10277,"children":10278},{"style":682},[10279],{"type":56,"value":9946},{"type":29,"tag":127,"props":10281,"children":10282},{"style":688},[10283],{"type":56,"value":691},{"type":29,"tag":127,"props":10285,"children":10286},{"class":677,"line":1536},[10287,10291,10295],{"type":29,"tag":127,"props":10288,"children":10289},{"style":682},[10290],{"type":56,"value":712},{"type":29,"tag":127,"props":10292,"children":10293},{"style":688},[10294],{"type":56,"value":717},{"type":29,"tag":127,"props":10296,"children":10297},{"style":720},[10298],{"type":56,"value":10299},"nextcloud:32.0.0\n",{"type":29,"tag":127,"props":10301,"children":10302},{"class":677,"line":1549},[10303,10307,10311],{"type":29,"tag":127,"props":10304,"children":10305},{"style":682},[10306],{"type":56,"value":1284},{"type":29,"tag":127,"props":10308,"children":10309},{"style":688},[10310],{"type":56,"value":717},{"type":29,"tag":127,"props":10312,"children":10313},{"style":720},[10314],{"type":56,"value":10023},{"type":29,"tag":127,"props":10316,"children":10317},{"class":677,"line":2411},[10318,10323],{"type":29,"tag":127,"props":10319,"children":10320},{"style":682},[10321],{"type":56,"value":10322},"    depends_on",{"type":29,"tag":127,"props":10324,"children":10325},{"style":688},[10326],{"type":56,"value":691},{"type":29,"tag":127,"props":10328,"children":10329},{"class":677,"line":2419},[10330,10335],{"type":29,"tag":127,"props":10331,"children":10332},{"style":682},[10333],{"type":56,"value":10334},"      db",{"type":29,"tag":127,"props":10336,"children":10337},{"style":688},[10338],{"type":56,"value":691},{"type":29,"tag":127,"props":10340,"children":10341},{"class":677,"line":2439},[10342,10347,10351],{"type":29,"tag":127,"props":10343,"children":10344},{"style":682},[10345],{"type":56,"value":10346},"        condition",{"type":29,"tag":127,"props":10348,"children":10349},{"style":688},[10350],{"type":56,"value":717},{"type":29,"tag":127,"props":10352,"children":10353},{"style":720},[10354],{"type":56,"value":10355},"service_healthy\n",{"type":29,"tag":127,"props":10357,"children":10358},{"class":677,"line":2460},[10359,10363],{"type":29,"tag":127,"props":10360,"children":10361},{"style":682},[10362],{"type":56,"value":1529},{"type":29,"tag":127,"props":10364,"children":10365},{"style":688},[10366],{"type":56,"value":691},{"type":29,"tag":127,"props":10368,"children":10369},{"class":677,"line":2472},[10370,10374],{"type":29,"tag":127,"props":10371,"children":10372},{"style":688},[10373],{"type":56,"value":746},{"type":29,"tag":127,"props":10375,"children":10376},{"style":720},[10377],{"type":56,"value":10378},"nextcloud:/var/www/html\n",{"type":29,"tag":127,"props":10380,"children":10381},{"class":677,"line":2488},[10382,10386],{"type":29,"tag":127,"props":10383,"children":10384},{"style":682},[10385],{"type":56,"value":10054},{"type":29,"tag":127,"props":10387,"children":10388},{"style":688},[10389],{"type":56,"value":691},{"type":29,"tag":127,"props":10391,"children":10392},{"class":677,"line":2496},[10393,10397],{"type":29,"tag":127,"props":10394,"children":10395},{"style":688},[10396],{"type":56,"value":746},{"type":29,"tag":127,"props":10398,"children":10399},{"style":720},[10400],{"type":56,"value":10401},"MYSQL_PASSWORD=${NEXTCLOUD_MARIADB_PASSWORD:?error}\n",{"type":29,"tag":127,"props":10403,"children":10404},{"class":677,"line":1970},[10405,10409],{"type":29,"tag":127,"props":10406,"children":10407},{"style":688},[10408],{"type":56,"value":746},{"type":29,"tag":127,"props":10410,"children":10411},{"style":720},[10412],{"type":56,"value":10413},"MYSQL_DATABASE=nextcloud\n",{"type":29,"tag":127,"props":10415,"children":10416},{"class":677,"line":1971},[10417,10421],{"type":29,"tag":127,"props":10418,"children":10419},{"style":688},[10420],{"type":56,"value":746},{"type":29,"tag":127,"props":10422,"children":10423},{"style":720},[10424],{"type":56,"value":10425},"MYSQL_USER=nextcloud\n",{"type":29,"tag":127,"props":10427,"children":10428},{"class":677,"line":1972},[10429,10433],{"type":29,"tag":127,"props":10430,"children":10431},{"style":688},[10432],{"type":56,"value":746},{"type":29,"tag":127,"props":10434,"children":10435},{"style":720},[10436],{"type":56,"value":10437},"MYSQL_HOST=db\n",{"type":29,"tag":659,"props":10439,"children":10443},{"className":10440,"code":10441,"language":10442,"meta":7,"style":7},"language-dotenv shiki shiki-themes github-dark github-dark monokai","NEXTCLOUD_MARIADB_ROOT_PASSWORD=\nNEXTCLOUD_MARIADB_PASSWORD=\n","dotenv",[10444],{"type":29,"tag":672,"props":10445,"children":10446},{"__ignoreMap":7},[10447,10461],{"type":29,"tag":127,"props":10448,"children":10449},{"class":677,"line":678},[10450,10456],{"type":29,"tag":127,"props":10451,"children":10453},{"style":10452},"--shiki-default:#FFAB70;--shiki-dark:#FFAB70;--shiki-sepia:#F8F8F2",[10454],{"type":56,"value":10455},"NEXTCLOUD_MARIADB_ROOT_PASSWORD",{"type":29,"tag":127,"props":10457,"children":10458},{"style":4942},[10459],{"type":56,"value":10460},"=\n",{"type":29,"tag":127,"props":10462,"children":10463},{"class":677,"line":342},[10464,10469],{"type":29,"tag":127,"props":10465,"children":10466},{"style":10452},[10467],{"type":56,"value":10468},"NEXTCLOUD_MARIADB_PASSWORD",{"type":29,"tag":127,"props":10470,"children":10471},{"style":4942},[10472],{"type":56,"value":10460},{"type":29,"tag":48,"props":10474,"children":10475},{},[10476,10478,10484],{"type":56,"value":10477},"Werden als ",{"type":29,"tag":645,"props":10479,"children":10481},{"href":10480},"https://docs.gitlab.com/ci/variables/",[10482],{"type":56,"value":10483},"CI/CD-Variablen",{"type":56,"value":10485}," gespeichert.",{"type":29,"tag":1189,"props":10487,"children":10488},{},[],{"type":29,"tag":48,"props":10490,"children":10491},{},[10492],{"type":56,"value":10493},"Um den Stack zu deployen, haben wir folgende Pipeline:",{"type":29,"tag":659,"props":10495,"children":10497},{"className":669,"code":10496,"filename":5382,"language":508,"meta":7,"style":7},"stages:\n  - deploy\n\ndeploy:\n  stage: deploy\n  image: docker:28\n  variables:\n    DOCKER_HOST: ssh://[username@]\u003CIP or host>[:port]\n  script:\n    - for file in $(find . -type f -name docker-compose.yml); do docker compose -f $file up --remove-orphans --wait; done\n  rules:\n    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH\n\n",[10498],{"type":29,"tag":672,"props":10499,"children":10500},{"__ignoreMap":7},[10501,10512,10524,10531,10542,10557,10573,10584,10601,10612,10624,10635],{"type":29,"tag":127,"props":10502,"children":10503},{"class":677,"line":678},[10504,10508],{"type":29,"tag":127,"props":10505,"children":10506},{"style":682},[10507],{"type":56,"value":5394},{"type":29,"tag":127,"props":10509,"children":10510},{"style":688},[10511],{"type":56,"value":691},{"type":29,"tag":127,"props":10513,"children":10514},{"class":677,"line":342},[10515,10519],{"type":29,"tag":127,"props":10516,"children":10517},{"style":688},[10518],{"type":56,"value":5406},{"type":29,"tag":127,"props":10520,"children":10521},{"style":720},[10522],{"type":56,"value":10523},"deploy\n",{"type":29,"tag":127,"props":10525,"children":10526},{"class":677,"line":706},[10527],{"type":29,"tag":127,"props":10528,"children":10529},{"emptyLinePlaceholder":500},[10530],{"type":56,"value":1399},{"type":29,"tag":127,"props":10532,"children":10533},{"class":677,"line":726},[10534,10538],{"type":29,"tag":127,"props":10535,"children":10536},{"style":682},[10537],{"type":56,"value":5426},{"type":29,"tag":127,"props":10539,"children":10540},{"style":688},[10541],{"type":56,"value":691},{"type":29,"tag":127,"props":10543,"children":10544},{"class":677,"line":664},[10545,10549,10553],{"type":29,"tag":127,"props":10546,"children":10547},{"style":682},[10548],{"type":56,"value":5455},{"type":29,"tag":127,"props":10550,"children":10551},{"style":688},[10552],{"type":56,"value":717},{"type":29,"tag":127,"props":10554,"children":10555},{"style":720},[10556],{"type":56,"value":10523},{"type":29,"tag":127,"props":10558,"children":10559},{"class":677,"line":665},[10560,10564,10568],{"type":29,"tag":127,"props":10561,"children":10562},{"style":682},[10563],{"type":56,"value":5438},{"type":29,"tag":127,"props":10565,"children":10566},{"style":688},[10567],{"type":56,"value":717},{"type":29,"tag":127,"props":10569,"children":10570},{"style":720},[10571],{"type":56,"value":10572},"docker:28\n",{"type":29,"tag":127,"props":10574,"children":10575},{"class":677,"line":666},[10576,10580],{"type":29,"tag":127,"props":10577,"children":10578},{"style":682},[10579],{"type":56,"value":6544},{"type":29,"tag":127,"props":10581,"children":10582},{"style":688},[10583],{"type":56,"value":691},{"type":29,"tag":127,"props":10585,"children":10586},{"class":677,"line":667},[10587,10592,10596],{"type":29,"tag":127,"props":10588,"children":10589},{"style":682},[10590],{"type":56,"value":10591},"    DOCKER_HOST",{"type":29,"tag":127,"props":10593,"children":10594},{"style":688},[10595],{"type":56,"value":717},{"type":29,"tag":127,"props":10597,"children":10598},{"style":720},[10599],{"type":56,"value":10600},"ssh://[username@]\u003CIP or host>[:port]\n",{"type":29,"tag":127,"props":10602,"children":10603},{"class":677,"line":668},[10604,10608],{"type":29,"tag":127,"props":10605,"children":10606},{"style":682},[10607],{"type":56,"value":5471},{"type":29,"tag":127,"props":10609,"children":10610},{"style":688},[10611],{"type":56,"value":691},{"type":29,"tag":127,"props":10613,"children":10614},{"class":677,"line":1329},[10615,10619],{"type":29,"tag":127,"props":10616,"children":10617},{"style":688},[10618],{"type":56,"value":5483},{"type":29,"tag":127,"props":10620,"children":10621},{"style":720},[10622],{"type":56,"value":10623},"for file in $(find . -type f -name docker-compose.yml); do docker compose -f $file up --remove-orphans --wait; done\n",{"type":29,"tag":127,"props":10625,"children":10626},{"class":677,"line":1342},[10627,10631],{"type":29,"tag":127,"props":10628,"children":10629},{"style":682},[10630],{"type":56,"value":5513},{"type":29,"tag":127,"props":10632,"children":10633},{"style":688},[10634],{"type":56,"value":691},{"type":29,"tag":127,"props":10636,"children":10637},{"class":677,"line":118},[10638,10642,10646,10650],{"type":29,"tag":127,"props":10639,"children":10640},{"style":688},[10641],{"type":56,"value":5483},{"type":29,"tag":127,"props":10643,"children":10644},{"style":682},[10645],{"type":56,"value":5746},{"type":29,"tag":127,"props":10647,"children":10648},{"style":688},[10649],{"type":56,"value":717},{"type":29,"tag":127,"props":10651,"children":10652},{"style":720},[10653],{"type":56,"value":10654},"$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH\n",{"type":29,"tag":48,"props":10656,"children":10657},{},[10658,10660,10666],{"type":56,"value":10659},"Die Pipeline läuft bei jedem Commit auf dem Standard-Branch, iteriert über alle ",{"type":29,"tag":672,"props":10661,"children":10663},{"className":10662},[],[10664],{"type":56,"value":10665},"docker-compose.yml",{"type":56,"value":10667},"-Dateien und deployt sie.",{"type":29,"tag":90,"props":10669,"children":10671},{"id":10670},"halte-deine-software-aktuell-mit-renovate-bot",[10672],{"type":56,"value":10673},"Halte deine Software aktuell mit Renovate-Bot",{"type":29,"tag":48,"props":10675,"children":10676},{},[10677],{"type":56,"value":10678},"Hier kommt Renovate ins Spiel.",{"type":29,"tag":659,"props":10680,"children":10683},{"className":1966,"code":10681,"filename":10682,"language":454,"meta":7,"style":7},"{\n  \"$schema\": \"https://docs.renovatebot.com/renovate-schema.json\",\n  \"extends\": [\n    \"config:best-practices\"\n  ]\n}\n","renovate.json",[10684],{"type":29,"tag":672,"props":10685,"children":10686},{"__ignoreMap":7},[10687,10694,10715,10727,10735,10742],{"type":29,"tag":127,"props":10688,"children":10689},{"class":677,"line":678},[10690],{"type":29,"tag":127,"props":10691,"children":10692},{"style":688},[10693],{"type":56,"value":1985},{"type":29,"tag":127,"props":10695,"children":10696},{"class":677,"line":342},[10697,10702,10706,10711],{"type":29,"tag":127,"props":10698,"children":10699},{"style":1991},[10700],{"type":56,"value":10701},"  \"$schema\"",{"type":29,"tag":127,"props":10703,"children":10704},{"style":688},[10705],{"type":56,"value":717},{"type":29,"tag":127,"props":10707,"children":10708},{"style":2001},[10709],{"type":56,"value":10710},"\"https://docs.renovatebot.com/renovate-schema.json\"",{"type":29,"tag":127,"props":10712,"children":10713},{"style":688},[10714],{"type":56,"value":2009},{"type":29,"tag":127,"props":10716,"children":10717},{"class":677,"line":706},[10718,10723],{"type":29,"tag":127,"props":10719,"children":10720},{"style":1991},[10721],{"type":56,"value":10722},"  \"extends\"",{"type":29,"tag":127,"props":10724,"children":10725},{"style":688},[10726],{"type":56,"value":2226},{"type":29,"tag":127,"props":10728,"children":10729},{"class":677,"line":726},[10730],{"type":29,"tag":127,"props":10731,"children":10732},{"style":2001},[10733],{"type":56,"value":10734},"    \"config:best-practices\"\n",{"type":29,"tag":127,"props":10736,"children":10737},{"class":677,"line":664},[10738],{"type":29,"tag":127,"props":10739,"children":10740},{"style":688},[10741],{"type":56,"value":6190},{"type":29,"tag":127,"props":10743,"children":10744},{"class":677,"line":665},[10745],{"type":29,"tag":127,"props":10746,"children":10747},{"style":688},[10748],{"type":56,"value":3013},{"type":29,"tag":48,"props":10750,"children":10751},{},[10752],{"type":56,"value":10753},"Renovate erstellt für jedes Update einen Merge-Request. Super!",{"type":29,"tag":90,"props":10755,"children":10757},{"id":10756},"automatisierte-sicherheitsupdates-und-opt-in-für-minor-major-versionen",[10758],{"type":56,"value":10759},"Automatisierte Sicherheitsupdates und Opt-in für Minor-/Major-Versionen",{"type":29,"tag":48,"props":10761,"children":10762},{},[10763],{"type":56,"value":10764},"Die aktuelle Konfiguration erstellt für jedes Update einen Merge-Request, aber wir möchten, dass Sicherheitsupdates ohne Benutzerinteraktion erfolgen.",{"type":29,"tag":48,"props":10766,"children":10767},{},[10768,10770,10776],{"type":56,"value":10769},"Es ist wichtig zu verstehen, wie Docker-Images versioniert bzw. getaggt werden. Es hängt vom jeweiligen Image ab, aber nehmen wir die offizielle ",{"type":29,"tag":645,"props":10771,"children":10773},{"href":10772},"https://hub.docker.com/_/mariadb",[10774],{"type":56,"value":10775},"MariaDB",{"type":56,"value":10777}," als Beispiel.",{"type":29,"tag":48,"props":10779,"children":10780},{},[10781,10783,10789],{"type":56,"value":10782},"Es gibt ",{"type":29,"tag":672,"props":10784,"children":10786},{"className":10785},[],[10787],{"type":56,"value":10788},"11.8.3-noble, 11.8-noble, 11-noble, lts-noble, 11.8.3, 11.8, 11, lts",{"type":56,"value":10790},", die alle auf dasselbe Image verweisen.",{"type":29,"tag":48,"props":10792,"children":10793},{},[10794,10800,10802,10808,10810,10816,10817,10823],{"type":29,"tag":672,"props":10795,"children":10797},{"className":10796},[],[10798],{"type":56,"value":10799},"11.8.3-noble",{"type":56,"value":10801}," bedeutet, dass wir MariaDB in Version ",{"type":29,"tag":672,"props":10803,"children":10805},{"className":10804},[],[10806],{"type":56,"value":10807},"11.8.3",{"type":56,"value":10809}," auf Basis von Ubuntu Noble erhalten.\n",{"type":29,"tag":672,"props":10811,"children":10813},{"className":10812},[],[10814],{"type":56,"value":10815},"11.8-noble",{"type":56,"value":10801},{"type":29,"tag":672,"props":10818,"children":10820},{"className":10819},[],[10821],{"type":56,"value":10822},"11.8.\u003Clatest_patch>",{"type":56,"value":10824}," auf Basis von Ubuntu Noble erhalten.",{"type":29,"tag":48,"props":10826,"children":10827},{},[10828,10830,10836,10838,10843,10845,10850],{"type":56,"value":10829},"Wenn eine neue Version von MariaDB veröffentlicht wird, z. B. ",{"type":29,"tag":672,"props":10831,"children":10833},{"className":10832},[],[10834],{"type":56,"value":10835},"11.8.4-noble",{"type":56,"value":10837},", wird ein neuer Tag ",{"type":29,"tag":672,"props":10839,"children":10841},{"className":10840},[],[10842],{"type":56,"value":10835},{"type":56,"value":10844}," veröffentlicht, aber der Tag ",{"type":29,"tag":672,"props":10846,"children":10848},{"className":10847},[],[10849],{"type":56,"value":10815},{"type":56,"value":10851}," wird aktualisiert.",{"type":29,"tag":48,"props":10853,"children":10854},{},[10855,10857,10862],{"type":56,"value":10856},"Gleiches gilt für das Ubuntu-Update. Der Tag ",{"type":29,"tag":672,"props":10858,"children":10860},{"className":10859},[],[10861],{"type":56,"value":10799},{"type":56,"value":10863}," kann aktualisiert werden, wenn das Image mit dem neuesten Ubuntu-Image erneut gebaut wird.",{"type":29,"tag":48,"props":10865,"children":10866},{},[10867,10873,10875,10881],{"type":29,"tag":672,"props":10868,"children":10870},{"className":10869},[],[10871],{"type":56,"value":10872},"docker compose up",{"type":56,"value":10874}," mit ",{"type":29,"tag":672,"props":10876,"children":10878},{"className":10877},[],[10879],{"type":56,"value":10880},"mariadb:11.8-noble",{"type":56,"value":10882}," wird nichts bewirken, weil Docker sich dieser Änderung nicht bewusst ist.",{"type":29,"tag":48,"props":10884,"children":10885},{},[10886,10888,10894],{"type":56,"value":10887},"Im Beispiel oben verweisen wir auf ",{"type":29,"tag":672,"props":10889,"children":10891},{"className":10890},[],[10892],{"type":56,"value":10893},"mariadb:11.8",{"type":56,"value":10895},", weil wir die neueste Patch-Version auf Basis des neuesten Betriebssystems verwenden möchten.",{"type":29,"tag":1189,"props":10897,"children":10898},{},[],{"type":29,"tag":48,"props":10900,"children":10901},{},[10902],{"type":56,"value":10903},"Wie soll Docker mitgeteilt werden, dass es eine neue Version gibt?",{"type":29,"tag":48,"props":10905,"children":10906},{},[10907,10909,10915],{"type":56,"value":10908},"Die Hauptidee ist, das Docker-Image zusätzlich mit einem ",{"type":29,"tag":645,"props":10910,"children":10912},{"href":10911},"https://docs.docker.com/dhi/core-concepts/digests/",[10913],{"type":56,"value":10914},"Digest",{"type":56,"value":10916}," anzugeben.",{"type":29,"tag":48,"props":10918,"children":10919},{},[10920,10922,10927,10929,10935],{"type":56,"value":10921},"Wenn Renovate das erste Mal läuft, findet es den Verweis auf ",{"type":29,"tag":672,"props":10923,"children":10925},{"className":10924},[],[10926],{"type":56,"value":10893},{"type":56,"value":10928}," und erstellt einen Merge-Request, um den Digest auf so etwas wie ",{"type":29,"tag":672,"props":10930,"children":10932},{"className":10931},[],[10933],{"type":56,"value":10934},"mariadb:11.8@sha256:ae6119716edac6998ae85508431b3d2e666530ddf4e94c61a10710caec9b0f71",{"type":56,"value":10936}," festzulegen.",{"type":29,"tag":48,"props":10938,"children":10939},{},[10940],{"type":56,"value":10941},"Es überwacht das auch, sodass bei jedem Update des Images der Digest wechselt und Renovate einen Merge-Request erstellt.",{"type":29,"tag":48,"props":10943,"children":10944},{},[10945],{"type":56,"value":10946},"Damit diese Updates automatisch gemergt werden, müssen wir ein paar Anpassungen vornehmen.",{"type":29,"tag":659,"props":10948,"children":10951},{"className":1966,"code":10949,"filename":10682,"highlights":10950,"language":454,"meta":7,"style":7},"{\n  \"$schema\": \"https://docs.renovatebot.com/renovate-schema.json\",\n  \"extends\": [\n    \"config:best-practices\",\n    \"default:automergeDigest\"\n  ],\n  \"automergeType\": \"branch\",\n  \"ignoreTests\": true\n}\n",[664,665,666,667],[10952],{"type":29,"tag":672,"props":10953,"children":10954},{"__ignoreMap":7},[10955,10962,10981,10992,11004,11013,11021,11043,11060],{"type":29,"tag":127,"props":10956,"children":10957},{"class":677,"line":678},[10958],{"type":29,"tag":127,"props":10959,"children":10960},{"style":688},[10961],{"type":56,"value":1985},{"type":29,"tag":127,"props":10963,"children":10964},{"class":677,"line":342},[10965,10969,10973,10977],{"type":29,"tag":127,"props":10966,"children":10967},{"style":1991},[10968],{"type":56,"value":10701},{"type":29,"tag":127,"props":10970,"children":10971},{"style":688},[10972],{"type":56,"value":717},{"type":29,"tag":127,"props":10974,"children":10975},{"style":2001},[10976],{"type":56,"value":10710},{"type":29,"tag":127,"props":10978,"children":10979},{"style":688},[10980],{"type":56,"value":2009},{"type":29,"tag":127,"props":10982,"children":10983},{"class":677,"line":706},[10984,10988],{"type":29,"tag":127,"props":10985,"children":10986},{"style":1991},[10987],{"type":56,"value":10722},{"type":29,"tag":127,"props":10989,"children":10990},{"style":688},[10991],{"type":56,"value":2226},{"type":29,"tag":127,"props":10993,"children":10994},{"class":677,"line":726},[10995,11000],{"type":29,"tag":127,"props":10996,"children":10997},{"style":2001},[10998],{"type":56,"value":10999},"    \"config:best-practices\"",{"type":29,"tag":127,"props":11001,"children":11002},{"style":688},[11003],{"type":56,"value":2009},{"type":29,"tag":127,"props":11005,"children":11007},{"class":11006,"line":664},[677,740],[11008],{"type":29,"tag":127,"props":11009,"children":11010},{"style":2001},[11011],{"type":56,"value":11012},"    \"default:automergeDigest\"\n",{"type":29,"tag":127,"props":11014,"children":11016},{"class":11015,"line":665},[677,740],[11017],{"type":29,"tag":127,"props":11018,"children":11019},{"style":688},[11020],{"type":56,"value":2565},{"type":29,"tag":127,"props":11022,"children":11024},{"class":11023,"line":666},[677,740],[11025,11030,11034,11039],{"type":29,"tag":127,"props":11026,"children":11027},{"style":1991},[11028],{"type":56,"value":11029},"  \"automergeType\"",{"type":29,"tag":127,"props":11031,"children":11032},{"style":688},[11033],{"type":56,"value":717},{"type":29,"tag":127,"props":11035,"children":11036},{"style":2001},[11037],{"type":56,"value":11038},"\"branch\"",{"type":29,"tag":127,"props":11040,"children":11041},{"style":688},[11042],{"type":56,"value":2009},{"type":29,"tag":127,"props":11044,"children":11046},{"class":11045,"line":667},[677,740],[11047,11052,11056],{"type":29,"tag":127,"props":11048,"children":11049},{"style":1991},[11050],{"type":56,"value":11051},"  \"ignoreTests\"",{"type":29,"tag":127,"props":11053,"children":11054},{"style":688},[11055],{"type":56,"value":717},{"type":29,"tag":127,"props":11057,"children":11058},{"style":2303},[11059],{"type":56,"value":2306},{"type":29,"tag":127,"props":11061,"children":11062},{"class":677,"line":668},[11063],{"type":29,"tag":127,"props":11064,"children":11065},{"style":688},[11066],{"type":56,"value":3013},{"type":29,"tag":48,"props":11068,"children":11069},{},[11070,11072,11078,11079,11085],{"type":56,"value":11071},"Das weist Renovate an, die Digest-Updates automatisch zu mergen, ohne einen Merge-Request zu erstellen. Das reduziert das \"Rauschen\", weil es keine Merge-Request-Benachrichtigung gibt.\nMehr dazu findest du unter ",{"type":29,"tag":645,"props":11073,"children":11075},{"href":11074},"https://docs.renovatebot.com/key-concepts/automerge/#branch-vs-pr-automerging",[11076],{"type":56,"value":11077},"automergeType",{"type":56,"value":9692},{"type":29,"tag":645,"props":11080,"children":11082},{"href":11081},"https://docs.renovatebot.com/key-concepts/automerge/#absence-of-tests",[11083],{"type":56,"value":11084},"ignoreTests",{"type":56,"value":1651},{"type":29,"tag":1838,"props":11087,"children":11088},{},[11089],{"type":56,"value":1842},{"title":7,"searchDepth":342,"depth":342,"links":11091},[11092,11093,11094,11095,11096],{"id":9723,"depth":342,"text":9726},{"id":9760,"depth":342,"text":9763},{"id":9799,"depth":342,"text":9802},{"id":10670,"depth":342,"text":10673},{"id":10756,"depth":342,"text":10759},{"_path":574,"_dir":515,"_draft":6,"_partial":6,"_locale":7,"title":575,"description":576,"author":518,"image":519,"releaseDate":577,"blogCategories":11098,"articleTags":11099,"tags":11100,"body":11101,"_type":346,"_id":582,"_source":348,"_file":583,"_stem":584,"_extension":351},[579,523],[523,536],[461,24],{"type":26,"children":11102,"toc":11626},[11103,11107,11118,11124,11137,11146,11177,11183,11211,11216,11246,11552,11557,11622],{"type":29,"tag":61,"props":11104,"children":11106},{"alt":7,"aspect-ratio":1861,"height":1862,"object-fit":1863,"src":11105},"/blog/shopware-renovate.png",[],{"type":29,"tag":48,"props":11108,"children":11109},{},[11110,11116],{"type":29,"tag":645,"props":11111,"children":11113},{"href":11112},"https://docs.renovatebot.com/",[11114],{"type":56,"value":11115},"Renovate",{"type":56,"value":11117}," ist ein Tool zur Verfolgung von Projektabhängigkeiten und zur Erstellung von Merge-/Pull-Requests für diese. Es funktioniert perfekt für die meisten gängigen Paketmanager, aber...",{"type":29,"tag":90,"props":11119,"children":11121},{"id":11120},"shopware-versionierungsschema",[11122],{"type":56,"value":11123},"Shopware Versionierungsschema",{"type":29,"tag":48,"props":11125,"children":11126},{},[11127,11129,11135],{"type":56,"value":11128},"Shopware verwendet ein benutzerdefiniertes Versionierungsschema. Sie können den ",{"type":29,"tag":645,"props":11130,"children":11132},{"href":11131},"https://www.shopware.com/de/news/shopware-6-versionierungs-strategie/",[11133],{"type":56,"value":11134},"offiziellen Artikel",{"type":56,"value":11136}," lesen, aber kurz gesagt:",{"type":29,"tag":11138,"props":11139,"children":11140},"blockquote",{},[11141],{"type":29,"tag":48,"props":11142,"children":11143},{},[11144],{"type":56,"value":11145},"Shopware implementierte SemVer als \"SemVer with benefits\".",{"type":29,"tag":11138,"props":11147,"children":11148},{},[11149,11154,11172],{"type":29,"tag":48,"props":11150,"children":11151},{},[11152],{"type":56,"value":11153},"Eine SemVer-konforme Version hat drei Zahlen: Major, Minor und Patch. Diese werden nach folgendem Regelsatz erhöht:",{"type":29,"tag":810,"props":11155,"children":11156},{},[11157,11162,11167],{"type":29,"tag":814,"props":11158,"children":11159},{},[11160],{"type":56,"value":11161},"MAJOR: Inkompatible API-Änderungen werden vorgenommen",{"type":29,"tag":814,"props":11163,"children":11164},{},[11165],{"type":56,"value":11166},"MINOR: Funktionalität wird auf rückwärtskompatible Weise hinzugefügt",{"type":29,"tag":814,"props":11168,"children":11169},{},[11170],{"type":56,"value":11171},"PATCH: Rückwärtskompatible Fehlerbehebungen werden vorgenommen",{"type":29,"tag":48,"props":11173,"children":11174},{},[11175],{"type":56,"value":11176},"Der \"with benefits\"-Teil ist: Wir behalten die große Marketing-Nummer. Also ist Shopware 6 immer noch das Produkt, aber es gibt eine Shopware 6.3.0.0. Wobei 3.0.0 der SemVer-Teil ist.",{"type":29,"tag":90,"props":11178,"children":11180},{"id":11179},"renovate-konfiguration",[11181],{"type":56,"value":11182},"Renovate-Konfiguration",{"type":29,"tag":48,"props":11184,"children":11185},{},[11186,11187,11193,11195,11201,11203,11209],{"type":56,"value":6227},{"type":29,"tag":672,"props":11188,"children":11190},{"className":11189},[],[11191],{"type":56,"value":11192},"\"große Marketing-Nummer\"",{"type":56,"value":11194}," oder ",{"type":29,"tag":672,"props":11196,"children":11198},{"className":11197},[],[11199],{"type":56,"value":11200},"\"Generation\"",{"type":56,"value":11202}," wird in Renovate als ",{"type":29,"tag":672,"props":11204,"children":11206},{"className":11205},[],[11207],{"type":56,"value":11208},"compatibility",{"type":56,"value":11210}," dargestellt.",{"type":29,"tag":48,"props":11212,"children":11213},{},[11214],{"type":56,"value":11215},"Die folgende Konfiguration wird:",{"type":29,"tag":965,"props":11217,"children":11218},{},[11219,11224,11236,11241],{"type":29,"tag":814,"props":11220,"children":11221},{},[11222],{"type":56,"value":11223},"Alle shopware-spezifischen Updates gruppieren",{"type":29,"tag":814,"props":11225,"children":11226},{},[11227,11229,11234],{"type":56,"value":11228},"Die Updates als ",{"type":29,"tag":672,"props":11230,"children":11232},{"className":11231},[],[11233],{"type":56,"value":461},{"type":56,"value":11235}," gruppieren",{"type":29,"tag":814,"props":11237,"children":11238},{},[11239],{"type":56,"value":11240},"Renovate mitteilen, wie die Version extrahiert werden soll",{"type":29,"tag":814,"props":11242,"children":11243},{},[11244],{"type":56,"value":11245},"Renovate mitteilen, wo Changelog-Informationen zu finden sind",{"type":29,"tag":659,"props":11247,"children":11249},{"className":1966,"code":11248,"filename":10682,"language":454,"meta":7,"style":7},"{\n  \"$schema\": \"https://docs.renovatebot.com/renovate-schema.json\",\n  \"packageRules\": [\n    {\n      \"description\": \"Follow Shopware version schema\",\n      \"matchDatasources\": [\n        \"packagist\"\n      ],\n      \"matchPackageNames\": [\n        \"shopware/core\",\n        \"shopware/administration\",\n        \"shopware/elasticsearch\",\n        \"shopware/storefront\"\n      ],\n      \"groupName\": \"shopware\",\n      \"versioning\": \"regex:(?\u003Ccompatibility>\\\\d+)\\\\.(?\u003Cmajor>\\\\d+)(\\\\.(?\u003Cminor>\\\\d+))?(\\\\.(?\u003Cpatch>\\\\d+))?$\",\n      \"sourceUrl\": \"https://github.com/shopware/shopware\"\n    }\n  ]\n}\n",[11250],{"type":29,"tag":672,"props":11251,"children":11252},{"__ignoreMap":7},[11253,11260,11279,11291,11298,11319,11331,11339,11347,11359,11370,11382,11394,11402,11409,11430,11514,11531,11538,11545],{"type":29,"tag":127,"props":11254,"children":11255},{"class":677,"line":678},[11256],{"type":29,"tag":127,"props":11257,"children":11258},{"style":688},[11259],{"type":56,"value":1985},{"type":29,"tag":127,"props":11261,"children":11262},{"class":677,"line":342},[11263,11267,11271,11275],{"type":29,"tag":127,"props":11264,"children":11265},{"style":1991},[11266],{"type":56,"value":10701},{"type":29,"tag":127,"props":11268,"children":11269},{"style":688},[11270],{"type":56,"value":717},{"type":29,"tag":127,"props":11272,"children":11273},{"style":2001},[11274],{"type":56,"value":10710},{"type":29,"tag":127,"props":11276,"children":11277},{"style":688},[11278],{"type":56,"value":2009},{"type":29,"tag":127,"props":11280,"children":11281},{"class":677,"line":706},[11282,11287],{"type":29,"tag":127,"props":11283,"children":11284},{"style":1991},[11285],{"type":56,"value":11286},"  \"packageRules\"",{"type":29,"tag":127,"props":11288,"children":11289},{"style":688},[11290],{"type":56,"value":2226},{"type":29,"tag":127,"props":11292,"children":11293},{"class":677,"line":726},[11294],{"type":29,"tag":127,"props":11295,"children":11296},{"style":688},[11297],{"type":56,"value":2234},{"type":29,"tag":127,"props":11299,"children":11300},{"class":677,"line":664},[11301,11306,11310,11315],{"type":29,"tag":127,"props":11302,"children":11303},{"style":1991},[11304],{"type":56,"value":11305},"      \"description\"",{"type":29,"tag":127,"props":11307,"children":11308},{"style":688},[11309],{"type":56,"value":717},{"type":29,"tag":127,"props":11311,"children":11312},{"style":2001},[11313],{"type":56,"value":11314},"\"Follow Shopware version schema\"",{"type":29,"tag":127,"props":11316,"children":11317},{"style":688},[11318],{"type":56,"value":2009},{"type":29,"tag":127,"props":11320,"children":11321},{"class":677,"line":665},[11322,11327],{"type":29,"tag":127,"props":11323,"children":11324},{"style":1991},[11325],{"type":56,"value":11326},"      \"matchDatasources\"",{"type":29,"tag":127,"props":11328,"children":11329},{"style":688},[11330],{"type":56,"value":2226},{"type":29,"tag":127,"props":11332,"children":11333},{"class":677,"line":666},[11334],{"type":29,"tag":127,"props":11335,"children":11336},{"style":2001},[11337],{"type":56,"value":11338},"        \"packagist\"\n",{"type":29,"tag":127,"props":11340,"children":11341},{"class":677,"line":667},[11342],{"type":29,"tag":127,"props":11343,"children":11344},{"style":688},[11345],{"type":56,"value":11346},"      ],\n",{"type":29,"tag":127,"props":11348,"children":11349},{"class":677,"line":668},[11350,11355],{"type":29,"tag":127,"props":11351,"children":11352},{"style":1991},[11353],{"type":56,"value":11354},"      \"matchPackageNames\"",{"type":29,"tag":127,"props":11356,"children":11357},{"style":688},[11358],{"type":56,"value":2226},{"type":29,"tag":127,"props":11360,"children":11361},{"class":677,"line":1329},[11362,11366],{"type":29,"tag":127,"props":11363,"children":11364},{"style":2001},[11365],{"type":56,"value":3425},{"type":29,"tag":127,"props":11367,"children":11368},{"style":688},[11369],{"type":56,"value":2009},{"type":29,"tag":127,"props":11371,"children":11372},{"class":677,"line":1342},[11373,11378],{"type":29,"tag":127,"props":11374,"children":11375},{"style":2001},[11376],{"type":56,"value":11377},"        \"shopware/administration\"",{"type":29,"tag":127,"props":11379,"children":11380},{"style":688},[11381],{"type":56,"value":2009},{"type":29,"tag":127,"props":11383,"children":11384},{"class":677,"line":118},[11385,11390],{"type":29,"tag":127,"props":11386,"children":11387},{"style":2001},[11388],{"type":56,"value":11389},"        \"shopware/elasticsearch\"",{"type":29,"tag":127,"props":11391,"children":11392},{"style":688},[11393],{"type":56,"value":2009},{"type":29,"tag":127,"props":11395,"children":11396},{"class":677,"line":1367},[11397],{"type":29,"tag":127,"props":11398,"children":11399},{"style":2001},[11400],{"type":56,"value":11401},"        \"shopware/storefront\"\n",{"type":29,"tag":127,"props":11403,"children":11404},{"class":677,"line":1380},[11405],{"type":29,"tag":127,"props":11406,"children":11407},{"style":688},[11408],{"type":56,"value":11346},{"type":29,"tag":127,"props":11410,"children":11411},{"class":677,"line":1393},[11412,11417,11421,11426],{"type":29,"tag":127,"props":11413,"children":11414},{"style":1991},[11415],{"type":56,"value":11416},"      \"groupName\"",{"type":29,"tag":127,"props":11418,"children":11419},{"style":688},[11420],{"type":56,"value":717},{"type":29,"tag":127,"props":11422,"children":11423},{"style":2001},[11424],{"type":56,"value":11425},"\"shopware\"",{"type":29,"tag":127,"props":11427,"children":11428},{"style":688},[11429],{"type":56,"value":2009},{"type":29,"tag":127,"props":11431,"children":11432},{"class":677,"line":1402},[11433,11438,11442,11447,11451,11456,11460,11465,11469,11474,11478,11483,11487,11492,11496,11501,11505,11510],{"type":29,"tag":127,"props":11434,"children":11435},{"style":1991},[11436],{"type":56,"value":11437},"      \"versioning\"",{"type":29,"tag":127,"props":11439,"children":11440},{"style":688},[11441],{"type":56,"value":717},{"type":29,"tag":127,"props":11443,"children":11444},{"style":2001},[11445],{"type":56,"value":11446},"\"regex:(?\u003Ccompatibility>",{"type":29,"tag":127,"props":11448,"children":11449},{"style":2303},[11450],{"type":56,"value":2606},{"type":29,"tag":127,"props":11452,"children":11453},{"style":2001},[11454],{"type":56,"value":11455},"d+)",{"type":29,"tag":127,"props":11457,"children":11458},{"style":2303},[11459],{"type":56,"value":2606},{"type":29,"tag":127,"props":11461,"children":11462},{"style":2001},[11463],{"type":56,"value":11464},".(?\u003Cmajor>",{"type":29,"tag":127,"props":11466,"children":11467},{"style":2303},[11468],{"type":56,"value":2606},{"type":29,"tag":127,"props":11470,"children":11471},{"style":2001},[11472],{"type":56,"value":11473},"d+)(",{"type":29,"tag":127,"props":11475,"children":11476},{"style":2303},[11477],{"type":56,"value":2606},{"type":29,"tag":127,"props":11479,"children":11480},{"style":2001},[11481],{"type":56,"value":11482},".(?\u003Cminor>",{"type":29,"tag":127,"props":11484,"children":11485},{"style":2303},[11486],{"type":56,"value":2606},{"type":29,"tag":127,"props":11488,"children":11489},{"style":2001},[11490],{"type":56,"value":11491},"d+))?(",{"type":29,"tag":127,"props":11493,"children":11494},{"style":2303},[11495],{"type":56,"value":2606},{"type":29,"tag":127,"props":11497,"children":11498},{"style":2001},[11499],{"type":56,"value":11500},".(?\u003Cpatch>",{"type":29,"tag":127,"props":11502,"children":11503},{"style":2303},[11504],{"type":56,"value":2606},{"type":29,"tag":127,"props":11506,"children":11507},{"style":2001},[11508],{"type":56,"value":11509},"d+))?$\"",{"type":29,"tag":127,"props":11511,"children":11512},{"style":688},[11513],{"type":56,"value":2009},{"type":29,"tag":127,"props":11515,"children":11516},{"class":677,"line":1415},[11517,11522,11526],{"type":29,"tag":127,"props":11518,"children":11519},{"style":1991},[11520],{"type":56,"value":11521},"      \"sourceUrl\"",{"type":29,"tag":127,"props":11523,"children":11524},{"style":688},[11525],{"type":56,"value":717},{"type":29,"tag":127,"props":11527,"children":11528},{"style":2001},[11529],{"type":56,"value":11530},"\"https://github.com/shopware/shopware\"\n",{"type":29,"tag":127,"props":11532,"children":11533},{"class":677,"line":1428},[11534],{"type":29,"tag":127,"props":11535,"children":11536},{"style":688},[11537],{"type":56,"value":2556},{"type":29,"tag":127,"props":11539,"children":11540},{"class":677,"line":1437},[11541],{"type":29,"tag":127,"props":11542,"children":11543},{"style":688},[11544],{"type":56,"value":6190},{"type":29,"tag":127,"props":11546,"children":11547},{"class":677,"line":1450},[11548],{"type":29,"tag":127,"props":11549,"children":11550},{"style":688},[11551],{"type":56,"value":3013},{"type":29,"tag":48,"props":11553,"children":11554},{},[11555],{"type":56,"value":11556},"Dies sollte zur Erstellung folgender Merge-/Pull-Requests führen:",{"type":29,"tag":810,"props":11558,"children":11559},{},[11560,11593],{"type":29,"tag":814,"props":11561,"children":11562},{},[11563,11565,11571,11572,11578,11579,11585,11586,11592],{"type":56,"value":11564},"fix(deps): update shopware (",{"type":29,"tag":672,"props":11566,"children":11568},{"className":11567},[],[11569],{"type":56,"value":11570},"shopware/administration",{"type":56,"value":10187},{"type":29,"tag":672,"props":11573,"children":11575},{"className":11574},[],[11576],{"type":56,"value":11577},"shopware/core",{"type":56,"value":10187},{"type":29,"tag":672,"props":11580,"children":11582},{"className":11581},[],[11583],{"type":56,"value":11584},"shopware/elasticsearch",{"type":56,"value":10187},{"type":29,"tag":672,"props":11587,"children":11589},{"className":11588},[],[11590],{"type":56,"value":11591},"shopware/storefront",{"type":56,"value":7406},{"type":29,"tag":814,"props":11594,"children":11595},{},[11596,11598,11603,11604,11609,11610,11615,11616,11621],{"type":56,"value":11597},"fix(deps): update shopware to v7 (major) (",{"type":29,"tag":672,"props":11599,"children":11601},{"className":11600},[],[11602],{"type":56,"value":11570},{"type":56,"value":10187},{"type":29,"tag":672,"props":11605,"children":11607},{"className":11606},[],[11608],{"type":56,"value":11577},{"type":56,"value":10187},{"type":29,"tag":672,"props":11611,"children":11613},{"className":11612},[],[11614],{"type":56,"value":11584},{"type":56,"value":10187},{"type":29,"tag":672,"props":11617,"children":11619},{"className":11618},[],[11620],{"type":56,"value":11591},{"type":56,"value":7406},{"type":29,"tag":1838,"props":11623,"children":11624},{},[11625],{"type":56,"value":1842},{"title":7,"searchDepth":342,"depth":342,"links":11627},[11628,11629],{"id":11120,"depth":342,"text":11123},{"id":11179,"depth":342,"text":11182},{"_path":586,"_dir":515,"_draft":6,"_partial":6,"_locale":7,"title":587,"description":588,"author":518,"image":519,"releaseDate":589,"blogCategories":11631,"articleTags":11632,"tags":11633,"body":11634,"_type":346,"_id":594,"_source":348,"_file":595,"_stem":596,"_extension":351},[522,591],[523],[24],{"type":26,"children":11635,"toc":14536},[11636,11640,11646,11656,11907,11912,11918,11923,11928,11933,12032,12038,12043,12282,12288,12293,12311,12318,12334,12662,12667,12730,12736,12751,12775,13147,13151,13187,13190,13198,13201,13204,13210,13223,13233,13246,13249,13256,13650,13654,13679,13682,13685,13695,13701,14057,14061,14074,14077,14082,14512,14516,14532],{"type":29,"tag":61,"props":11637,"children":11639},{"alt":7,"aspect-ratio":1861,"height":1862,"object-fit":1863,"src":11638},"/blog/gitlab-traefik.png",[],{"type":29,"tag":90,"props":11641,"children":11643},{"id":11642},"der-einfachste-weg-gitlab-zu-installieren",[11644],{"type":56,"value":11645},"Der einfachste Weg, GitLab zu installieren",{"type":29,"tag":48,"props":11647,"children":11648},{},[11649,11651],{"type":56,"value":11650},"GitLab bietet offizielle Anweisungen zur Installation mit Docker und Docker Compose. Sie finden diese in der ",{"type":29,"tag":645,"props":11652,"children":11654},{"href":11653},"https://docs.gitlab.com/install/docker/installation/#install-gitlab-by-using-docker-compose",[11655],{"type":56,"value":1881},{"type":29,"tag":659,"props":11657,"children":11660},{"className":669,"code":11658,"filename":11659,"language":508,"meta":7,"style":7},"services:\n  gitlab:\n    image: gitlab/gitlab-ee:\u003Cversion>-ce.0\n    container_name: gitlab\n    restart: always\n    hostname: '\u003Cgitlab.example.com>'\n    environment:\n      GITLAB_OMNIBUS_CONFIG: |\n        # Add any other gitlab.rb configuration here, each on its own line\n        external_url 'https://\u003Cgitlab.example.com>'\n    ports:\n      - '80:80'\n      - '443:443'\n      - '22:22'\n    volumes:\n      - '$GITLAB_HOME/config:/etc/gitlab'\n      - '$GITLAB_HOME/logs:/var/log/gitlab'\n      - '$GITLAB_HOME/data:/var/opt/gitlab'\n    shm_size: '256m'\n","gitlab/docker-compose.yaml",[11661],{"type":29,"tag":672,"props":11662,"children":11663},{"__ignoreMap":7},[11664,11675,11687,11703,11719,11734,11751,11762,11779,11787,11795,11807,11819,11831,11843,11854,11866,11878,11890],{"type":29,"tag":127,"props":11665,"children":11666},{"class":677,"line":678},[11667,11671],{"type":29,"tag":127,"props":11668,"children":11669},{"style":682},[11670],{"type":56,"value":685},{"type":29,"tag":127,"props":11672,"children":11673},{"style":688},[11674],{"type":56,"value":691},{"type":29,"tag":127,"props":11676,"children":11677},{"class":677,"line":342},[11678,11683],{"type":29,"tag":127,"props":11679,"children":11680},{"style":682},[11681],{"type":56,"value":11682},"  gitlab",{"type":29,"tag":127,"props":11684,"children":11685},{"style":688},[11686],{"type":56,"value":691},{"type":29,"tag":127,"props":11688,"children":11689},{"class":677,"line":706},[11690,11694,11698],{"type":29,"tag":127,"props":11691,"children":11692},{"style":682},[11693],{"type":56,"value":712},{"type":29,"tag":127,"props":11695,"children":11696},{"style":688},[11697],{"type":56,"value":717},{"type":29,"tag":127,"props":11699,"children":11700},{"style":720},[11701],{"type":56,"value":11702},"gitlab/gitlab-ee:\u003Cversion>-ce.0\n",{"type":29,"tag":127,"props":11704,"children":11705},{"class":677,"line":726},[11706,11710,11714],{"type":29,"tag":127,"props":11707,"children":11708},{"style":682},[11709],{"type":56,"value":1267},{"type":29,"tag":127,"props":11711,"children":11712},{"style":688},[11713],{"type":56,"value":717},{"type":29,"tag":127,"props":11715,"children":11716},{"style":720},[11717],{"type":56,"value":11718},"gitlab\n",{"type":29,"tag":127,"props":11720,"children":11721},{"class":677,"line":664},[11722,11726,11730],{"type":29,"tag":127,"props":11723,"children":11724},{"style":682},[11725],{"type":56,"value":1284},{"type":29,"tag":127,"props":11727,"children":11728},{"style":688},[11729],{"type":56,"value":717},{"type":29,"tag":127,"props":11731,"children":11732},{"style":720},[11733],{"type":56,"value":1293},{"type":29,"tag":127,"props":11735,"children":11736},{"class":677,"line":665},[11737,11742,11746],{"type":29,"tag":127,"props":11738,"children":11739},{"style":682},[11740],{"type":56,"value":11741},"    hostname",{"type":29,"tag":127,"props":11743,"children":11744},{"style":688},[11745],{"type":56,"value":717},{"type":29,"tag":127,"props":11747,"children":11748},{"style":720},[11749],{"type":56,"value":11750},"'\u003Cgitlab.example.com>'\n",{"type":29,"tag":127,"props":11752,"children":11753},{"class":677,"line":666},[11754,11758],{"type":29,"tag":127,"props":11755,"children":11756},{"style":682},[11757],{"type":56,"value":10054},{"type":29,"tag":127,"props":11759,"children":11760},{"style":688},[11761],{"type":56,"value":691},{"type":29,"tag":127,"props":11763,"children":11764},{"class":677,"line":667},[11765,11770,11774],{"type":29,"tag":127,"props":11766,"children":11767},{"style":682},[11768],{"type":56,"value":11769},"      GITLAB_OMNIBUS_CONFIG",{"type":29,"tag":127,"props":11771,"children":11772},{"style":688},[11773],{"type":56,"value":717},{"type":29,"tag":127,"props":11775,"children":11776},{"style":4942},[11777],{"type":56,"value":11778},"|\n",{"type":29,"tag":127,"props":11780,"children":11781},{"class":677,"line":668},[11782],{"type":29,"tag":127,"props":11783,"children":11784},{"style":720},[11785],{"type":56,"value":11786},"        # Add any other gitlab.rb configuration here, each on its own line\n",{"type":29,"tag":127,"props":11788,"children":11789},{"class":677,"line":1329},[11790],{"type":29,"tag":127,"props":11791,"children":11792},{"style":720},[11793],{"type":56,"value":11794},"        external_url 'https://\u003Cgitlab.example.com>'\n",{"type":29,"tag":127,"props":11796,"children":11797},{"class":677,"line":1342},[11798,11803],{"type":29,"tag":127,"props":11799,"children":11800},{"style":682},[11801],{"type":56,"value":11802},"    ports",{"type":29,"tag":127,"props":11804,"children":11805},{"style":688},[11806],{"type":56,"value":691},{"type":29,"tag":127,"props":11808,"children":11809},{"class":677,"line":118},[11810,11814],{"type":29,"tag":127,"props":11811,"children":11812},{"style":688},[11813],{"type":56,"value":746},{"type":29,"tag":127,"props":11815,"children":11816},{"style":720},[11817],{"type":56,"value":11818},"'80:80'\n",{"type":29,"tag":127,"props":11820,"children":11821},{"class":677,"line":1367},[11822,11826],{"type":29,"tag":127,"props":11823,"children":11824},{"style":688},[11825],{"type":56,"value":746},{"type":29,"tag":127,"props":11827,"children":11828},{"style":720},[11829],{"type":56,"value":11830},"'443:443'\n",{"type":29,"tag":127,"props":11832,"children":11833},{"class":677,"line":1380},[11834,11838],{"type":29,"tag":127,"props":11835,"children":11836},{"style":688},[11837],{"type":56,"value":746},{"type":29,"tag":127,"props":11839,"children":11840},{"style":720},[11841],{"type":56,"value":11842},"'22:22'\n",{"type":29,"tag":127,"props":11844,"children":11845},{"class":677,"line":1393},[11846,11850],{"type":29,"tag":127,"props":11847,"children":11848},{"style":682},[11849],{"type":56,"value":1529},{"type":29,"tag":127,"props":11851,"children":11852},{"style":688},[11853],{"type":56,"value":691},{"type":29,"tag":127,"props":11855,"children":11856},{"class":677,"line":1402},[11857,11861],{"type":29,"tag":127,"props":11858,"children":11859},{"style":688},[11860],{"type":56,"value":746},{"type":29,"tag":127,"props":11862,"children":11863},{"style":720},[11864],{"type":56,"value":11865},"'$GITLAB_HOME/config:/etc/gitlab'\n",{"type":29,"tag":127,"props":11867,"children":11868},{"class":677,"line":1415},[11869,11873],{"type":29,"tag":127,"props":11870,"children":11871},{"style":688},[11872],{"type":56,"value":746},{"type":29,"tag":127,"props":11874,"children":11875},{"style":720},[11876],{"type":56,"value":11877},"'$GITLAB_HOME/logs:/var/log/gitlab'\n",{"type":29,"tag":127,"props":11879,"children":11880},{"class":677,"line":1428},[11881,11885],{"type":29,"tag":127,"props":11882,"children":11883},{"style":688},[11884],{"type":56,"value":746},{"type":29,"tag":127,"props":11886,"children":11887},{"style":720},[11888],{"type":56,"value":11889},"'$GITLAB_HOME/data:/var/opt/gitlab'\n",{"type":29,"tag":127,"props":11891,"children":11892},{"class":677,"line":1437},[11893,11898,11902],{"type":29,"tag":127,"props":11894,"children":11895},{"style":682},[11896],{"type":56,"value":11897},"    shm_size",{"type":29,"tag":127,"props":11899,"children":11900},{"style":688},[11901],{"type":56,"value":717},{"type":29,"tag":127,"props":11903,"children":11904},{"style":720},[11905],{"type":56,"value":11906},"'256m'\n",{"type":29,"tag":48,"props":11908,"children":11909},{},[11910],{"type":56,"value":11911},"Dies setzt voraus, dass Sie einen Server haben, der ausschließlich für GitLab bestimmt ist und alle erforderlichen Ports (http, https, ssh) frei sind.\nGitLab kümmert sich um alles, einschließlich der TLS-Konfiguration mit Lets Encrypt.",{"type":29,"tag":90,"props":11913,"children":11915},{"id":11914},"integration-von-gitlab-neben-anderen-deployments",[11916],{"type":56,"value":11917},"Integration von GitLab neben anderen Deployments",{"type":29,"tag":48,"props":11919,"children":11920},{},[11921],{"type":56,"value":11922},"Was ist, wenn Sie GitLab nicht auf einem dedizierten Server installieren können oder wollen?",{"type":29,"tag":48,"props":11924,"children":11925},{},[11926],{"type":56,"value":11927},"Vielleicht möchten Sie einfach einen einzigen Server für alle Ihre Dienste?",{"type":29,"tag":48,"props":11929,"children":11930},{},[11931],{"type":56,"value":11932},"Dies ist eine Beispielstruktur, wie Sie Ihre Deployments organisieren könnten:",{"type":29,"tag":659,"props":11934,"children":11936},{"className":3021,"code":11935,"language":3023,"meta":7,"style":7},".\n├── gitlab/                # GitLab Service-Stack\n├── gitlab-runner/         # GitLab Runner für CI/CD\n├── mattermost/            # Mattermost Team-Kollaboration\n├── nextcloud/             # Nextcloud Dateihosting und Zusammenarbeit\n└── traefik/               # Traefik Reverse-Proxy-Konfiguration\n",[11937],{"type":29,"tag":672,"props":11938,"children":11939},{"__ignoreMap":7},[11940,11947,11964,11981,11998,12015],{"type":29,"tag":127,"props":11941,"children":11942},{"class":677,"line":678},[11943],{"type":29,"tag":127,"props":11944,"children":11945},{"style":9820},[11946],{"type":56,"value":9823},{"type":29,"tag":127,"props":11948,"children":11949},{"class":677,"line":342},[11950,11954,11959],{"type":29,"tag":127,"props":11951,"children":11952},{"style":3033},[11953],{"type":56,"value":9844},{"type":29,"tag":127,"props":11955,"children":11956},{"style":720},[11957],{"type":56,"value":11958}," gitlab/",{"type":29,"tag":127,"props":11960,"children":11961},{"style":1796},[11962],{"type":56,"value":11963},"                # GitLab Service-Stack\n",{"type":29,"tag":127,"props":11965,"children":11966},{"class":677,"line":706},[11967,11971,11976],{"type":29,"tag":127,"props":11968,"children":11969},{"style":3033},[11970],{"type":56,"value":9844},{"type":29,"tag":127,"props":11972,"children":11973},{"style":720},[11974],{"type":56,"value":11975}," gitlab-runner/",{"type":29,"tag":127,"props":11977,"children":11978},{"style":1796},[11979],{"type":56,"value":11980},"         # GitLab Runner für CI/CD\n",{"type":29,"tag":127,"props":11982,"children":11983},{"class":677,"line":726},[11984,11988,11993],{"type":29,"tag":127,"props":11985,"children":11986},{"style":3033},[11987],{"type":56,"value":9844},{"type":29,"tag":127,"props":11989,"children":11990},{"style":720},[11991],{"type":56,"value":11992}," mattermost/",{"type":29,"tag":127,"props":11994,"children":11995},{"style":1796},[11996],{"type":56,"value":11997},"            # Mattermost Team-Kollaboration\n",{"type":29,"tag":127,"props":11999,"children":12000},{"class":677,"line":664},[12001,12005,12010],{"type":29,"tag":127,"props":12002,"children":12003},{"style":3033},[12004],{"type":56,"value":9844},{"type":29,"tag":127,"props":12006,"children":12007},{"style":720},[12008],{"type":56,"value":12009}," nextcloud/",{"type":29,"tag":127,"props":12011,"children":12012},{"style":1796},[12013],{"type":56,"value":12014},"             # Nextcloud Dateihosting und Zusammenarbeit\n",{"type":29,"tag":127,"props":12016,"children":12017},{"class":677,"line":665},[12018,12022,12027],{"type":29,"tag":127,"props":12019,"children":12020},{"style":3033},[12021],{"type":56,"value":9897},{"type":29,"tag":127,"props":12023,"children":12024},{"style":720},[12025],{"type":56,"value":12026}," traefik/",{"type":29,"tag":127,"props":12028,"children":12029},{"style":1796},[12030],{"type":56,"value":12031},"               # Traefik Reverse-Proxy-Konfiguration\n",{"type":29,"tag":122,"props":12033,"children":12035},{"id":12034},"verwendung-einer-dedizierten-ip",[12036],{"type":56,"value":12037},"Verwendung einer dedizierten IP",{"type":29,"tag":48,"props":12039,"children":12040},{},[12041],{"type":56,"value":12042},"Falls Sie die Möglichkeit haben, Ihrem Server eine zusätzliche IP zuzuweisen (wie eine Floating IP bei Hetzner),\nkönnen Sie die Ports einfach an diese IP binden.",{"type":29,"tag":659,"props":12044,"children":12047},{"className":669,"code":12045,"filename":11659,"highlights":12046,"language":508,"meta":7,"style":7},"services:\n  gitlab:\n    image: gitlab/gitlab-ee:\u003Cversion>-ce.0\n    container_name: gitlab\n    restart: always\n    hostname: '\u003Cgitlab.example.com>'\n    environment:\n      GITLAB_OMNIBUS_CONFIG: |\n        # Add any other gitlab.rb configuration here, each on its own line\n        external_url 'https://\u003Cgitlab.example.com>'\n    ports:\n      - '192.168.0.1:80:80'\n      - '192.168.0.1:443:443'\n      - '192.168.0.1:22:22'\n    volumes:\n      - '$GITLAB_HOME/config:/etc/gitlab'\n      - '$GITLAB_HOME/logs:/var/log/gitlab'\n      - '$GITLAB_HOME/data:/var/opt/gitlab'\n    shm_size: '256m'\n",[118,1367,1380],[12048],{"type":29,"tag":672,"props":12049,"children":12050},{"__ignoreMap":7},[12051,12062,12073,12088,12103,12118,12133,12144,12159,12166,12173,12184,12197,12210,12223,12234,12245,12256,12267],{"type":29,"tag":127,"props":12052,"children":12053},{"class":677,"line":678},[12054,12058],{"type":29,"tag":127,"props":12055,"children":12056},{"style":682},[12057],{"type":56,"value":685},{"type":29,"tag":127,"props":12059,"children":12060},{"style":688},[12061],{"type":56,"value":691},{"type":29,"tag":127,"props":12063,"children":12064},{"class":677,"line":342},[12065,12069],{"type":29,"tag":127,"props":12066,"children":12067},{"style":682},[12068],{"type":56,"value":11682},{"type":29,"tag":127,"props":12070,"children":12071},{"style":688},[12072],{"type":56,"value":691},{"type":29,"tag":127,"props":12074,"children":12075},{"class":677,"line":706},[12076,12080,12084],{"type":29,"tag":127,"props":12077,"children":12078},{"style":682},[12079],{"type":56,"value":712},{"type":29,"tag":127,"props":12081,"children":12082},{"style":688},[12083],{"type":56,"value":717},{"type":29,"tag":127,"props":12085,"children":12086},{"style":720},[12087],{"type":56,"value":11702},{"type":29,"tag":127,"props":12089,"children":12090},{"class":677,"line":726},[12091,12095,12099],{"type":29,"tag":127,"props":12092,"children":12093},{"style":682},[12094],{"type":56,"value":1267},{"type":29,"tag":127,"props":12096,"children":12097},{"style":688},[12098],{"type":56,"value":717},{"type":29,"tag":127,"props":12100,"children":12101},{"style":720},[12102],{"type":56,"value":11718},{"type":29,"tag":127,"props":12104,"children":12105},{"class":677,"line":664},[12106,12110,12114],{"type":29,"tag":127,"props":12107,"children":12108},{"style":682},[12109],{"type":56,"value":1284},{"type":29,"tag":127,"props":12111,"children":12112},{"style":688},[12113],{"type":56,"value":717},{"type":29,"tag":127,"props":12115,"children":12116},{"style":720},[12117],{"type":56,"value":1293},{"type":29,"tag":127,"props":12119,"children":12120},{"class":677,"line":665},[12121,12125,12129],{"type":29,"tag":127,"props":12122,"children":12123},{"style":682},[12124],{"type":56,"value":11741},{"type":29,"tag":127,"props":12126,"children":12127},{"style":688},[12128],{"type":56,"value":717},{"type":29,"tag":127,"props":12130,"children":12131},{"style":720},[12132],{"type":56,"value":11750},{"type":29,"tag":127,"props":12134,"children":12135},{"class":677,"line":666},[12136,12140],{"type":29,"tag":127,"props":12137,"children":12138},{"style":682},[12139],{"type":56,"value":10054},{"type":29,"tag":127,"props":12141,"children":12142},{"style":688},[12143],{"type":56,"value":691},{"type":29,"tag":127,"props":12145,"children":12146},{"class":677,"line":667},[12147,12151,12155],{"type":29,"tag":127,"props":12148,"children":12149},{"style":682},[12150],{"type":56,"value":11769},{"type":29,"tag":127,"props":12152,"children":12153},{"style":688},[12154],{"type":56,"value":717},{"type":29,"tag":127,"props":12156,"children":12157},{"style":4942},[12158],{"type":56,"value":11778},{"type":29,"tag":127,"props":12160,"children":12161},{"class":677,"line":668},[12162],{"type":29,"tag":127,"props":12163,"children":12164},{"style":720},[12165],{"type":56,"value":11786},{"type":29,"tag":127,"props":12167,"children":12168},{"class":677,"line":1329},[12169],{"type":29,"tag":127,"props":12170,"children":12171},{"style":720},[12172],{"type":56,"value":11794},{"type":29,"tag":127,"props":12174,"children":12175},{"class":677,"line":1342},[12176,12180],{"type":29,"tag":127,"props":12177,"children":12178},{"style":682},[12179],{"type":56,"value":11802},{"type":29,"tag":127,"props":12181,"children":12182},{"style":688},[12183],{"type":56,"value":691},{"type":29,"tag":127,"props":12185,"children":12187},{"class":12186,"line":118},[677,740],[12188,12192],{"type":29,"tag":127,"props":12189,"children":12190},{"style":688},[12191],{"type":56,"value":746},{"type":29,"tag":127,"props":12193,"children":12194},{"style":720},[12195],{"type":56,"value":12196},"'192.168.0.1:80:80'\n",{"type":29,"tag":127,"props":12198,"children":12200},{"class":12199,"line":1367},[677,740],[12201,12205],{"type":29,"tag":127,"props":12202,"children":12203},{"style":688},[12204],{"type":56,"value":746},{"type":29,"tag":127,"props":12206,"children":12207},{"style":720},[12208],{"type":56,"value":12209},"'192.168.0.1:443:443'\n",{"type":29,"tag":127,"props":12211,"children":12213},{"class":12212,"line":1380},[677,740],[12214,12218],{"type":29,"tag":127,"props":12215,"children":12216},{"style":688},[12217],{"type":56,"value":746},{"type":29,"tag":127,"props":12219,"children":12220},{"style":720},[12221],{"type":56,"value":12222},"'192.168.0.1:22:22'\n",{"type":29,"tag":127,"props":12224,"children":12225},{"class":677,"line":1393},[12226,12230],{"type":29,"tag":127,"props":12227,"children":12228},{"style":682},[12229],{"type":56,"value":1529},{"type":29,"tag":127,"props":12231,"children":12232},{"style":688},[12233],{"type":56,"value":691},{"type":29,"tag":127,"props":12235,"children":12236},{"class":677,"line":1402},[12237,12241],{"type":29,"tag":127,"props":12238,"children":12239},{"style":688},[12240],{"type":56,"value":746},{"type":29,"tag":127,"props":12242,"children":12243},{"style":720},[12244],{"type":56,"value":11865},{"type":29,"tag":127,"props":12246,"children":12247},{"class":677,"line":1415},[12248,12252],{"type":29,"tag":127,"props":12249,"children":12250},{"style":688},[12251],{"type":56,"value":746},{"type":29,"tag":127,"props":12253,"children":12254},{"style":720},[12255],{"type":56,"value":11877},{"type":29,"tag":127,"props":12257,"children":12258},{"class":677,"line":1428},[12259,12263],{"type":29,"tag":127,"props":12260,"children":12261},{"style":688},[12262],{"type":56,"value":746},{"type":29,"tag":127,"props":12264,"children":12265},{"style":720},[12266],{"type":56,"value":11889},{"type":29,"tag":127,"props":12268,"children":12269},{"class":677,"line":1437},[12270,12274,12278],{"type":29,"tag":127,"props":12271,"children":12272},{"style":682},[12273],{"type":56,"value":11897},{"type":29,"tag":127,"props":12275,"children":12276},{"style":688},[12277],{"type":56,"value":717},{"type":29,"tag":127,"props":12279,"children":12280},{"style":720},[12281],{"type":56,"value":11906},{"type":29,"tag":122,"props":12283,"children":12285},{"id":12284},"verwendung-von-traefik-als-reverse-proxy",[12286],{"type":56,"value":12287},"Verwendung von Traefik als Reverse-Proxy",{"type":29,"tag":48,"props":12289,"children":12290},{},[12291],{"type":56,"value":12292},"In diesem Fall gehe ich davon aus, dass Sie:",{"type":29,"tag":810,"props":12294,"children":12295},{},[12296,12301,12306],{"type":29,"tag":814,"props":12297,"children":12298},{},[12299],{"type":56,"value":12300},"keine dedizierte IP für GitLab zuweisen können oder wollen",{"type":29,"tag":814,"props":12302,"children":12303},{},[12304],{"type":56,"value":12305},"Ihren Standard-SSH-Port nicht ändern können oder wollen",{"type":29,"tag":814,"props":12307,"children":12308},{},[12309],{"type":56,"value":12310},"Traefik als Reverse-Proxy verwenden möchten",{"type":29,"tag":12312,"props":12313,"children":12315},"h4",{"id":12314},"das-traefik-deployment",[12316],{"type":56,"value":12317},"Das Traefik-Deployment",{"type":29,"tag":48,"props":12319,"children":12320},{},[12321,12323,12332],{"type":56,"value":12322},"Denken Sie daran, ",{"type":29,"tag":52,"props":12324,"children":12325},{},[12326],{"type":29,"tag":672,"props":12327,"children":12329},{"className":12328},[],[12330],{"type":56,"value":12331},"\u003Cinfo@example.com>",{"type":56,"value":12333}," durch Ihre eigene E-Mail-Adresse zu ersetzen.",{"type":29,"tag":659,"props":12335,"children":12338},{"className":669,"code":12336,"filename":12337,"language":508,"meta":7,"style":7},"volumes:\n  letsencrypt:\n\nservices:\n  traefik:\n    image: traefik:3\n    container_name: traefik\n    restart: always\n    network_mode: host\n    volumes:\n      - /var/run/docker.sock:/var/run/docker.sock:ro\n      - letsencrypt:/letsencrypt\n    command:\n      - --log.level=INFO\n\n      - --entrypoints.web.address=:80\n      - --entrypoints.web.http.redirections.entrypoint.to=websecure\n      - --entrypoints.web.http.redirections.entrypoint.scheme=https\n\n      - --entrypoints.websecure.address=:443\n      - --entrypoints.websecure.http.tls.certresolver=letsencrypt\n\n      - --providers.docker=true\n      - --providers.docker.exposedByDefault=false\n\n      - --certificatesresolvers.letsencrypt.acme.email=\u003Cinfo@example.com>\n      - --certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json\n      - --certificatesresolvers.letsencrypt.acme.httpchallenge=true\n      - --certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web\n","traefik/docker-compose.yaml",[12339],{"type":29,"tag":672,"props":12340,"children":12341},{"__ignoreMap":7},[12342,12353,12364,12371,12382,12393,12408,12423,12438,12453,12464,12475,12487,12498,12510,12517,12528,12539,12550,12557,12568,12579,12586,12598,12610,12617,12629,12640,12651],{"type":29,"tag":127,"props":12343,"children":12344},{"class":677,"line":678},[12345,12349],{"type":29,"tag":127,"props":12346,"children":12347},{"style":682},[12348],{"type":56,"value":1212},{"type":29,"tag":127,"props":12350,"children":12351},{"style":688},[12352],{"type":56,"value":691},{"type":29,"tag":127,"props":12354,"children":12355},{"class":677,"line":342},[12356,12360],{"type":29,"tag":127,"props":12357,"children":12358},{"style":682},[12359],{"type":56,"value":1224},{"type":29,"tag":127,"props":12361,"children":12362},{"style":688},[12363],{"type":56,"value":691},{"type":29,"tag":127,"props":12365,"children":12366},{"class":677,"line":706},[12367],{"type":29,"tag":127,"props":12368,"children":12369},{"emptyLinePlaceholder":500},[12370],{"type":56,"value":1399},{"type":29,"tag":127,"props":12372,"children":12373},{"class":677,"line":726},[12374,12378],{"type":29,"tag":127,"props":12375,"children":12376},{"style":682},[12377],{"type":56,"value":685},{"type":29,"tag":127,"props":12379,"children":12380},{"style":688},[12381],{"type":56,"value":691},{"type":29,"tag":127,"props":12383,"children":12384},{"class":677,"line":664},[12385,12389],{"type":29,"tag":127,"props":12386,"children":12387},{"style":682},[12388],{"type":56,"value":1255},{"type":29,"tag":127,"props":12390,"children":12391},{"style":688},[12392],{"type":56,"value":691},{"type":29,"tag":127,"props":12394,"children":12395},{"class":677,"line":665},[12396,12400,12404],{"type":29,"tag":127,"props":12397,"children":12398},{"style":682},[12399],{"type":56,"value":712},{"type":29,"tag":127,"props":12401,"children":12402},{"style":688},[12403],{"type":56,"value":717},{"type":29,"tag":127,"props":12405,"children":12406},{"style":720},[12407],{"type":56,"value":1309},{"type":29,"tag":127,"props":12409,"children":12410},{"class":677,"line":666},[12411,12415,12419],{"type":29,"tag":127,"props":12412,"children":12413},{"style":682},[12414],{"type":56,"value":1267},{"type":29,"tag":127,"props":12416,"children":12417},{"style":688},[12418],{"type":56,"value":717},{"type":29,"tag":127,"props":12420,"children":12421},{"style":720},[12422],{"type":56,"value":1276},{"type":29,"tag":127,"props":12424,"children":12425},{"class":677,"line":667},[12426,12430,12434],{"type":29,"tag":127,"props":12427,"children":12428},{"style":682},[12429],{"type":56,"value":1284},{"type":29,"tag":127,"props":12431,"children":12432},{"style":688},[12433],{"type":56,"value":717},{"type":29,"tag":127,"props":12435,"children":12436},{"style":720},[12437],{"type":56,"value":1293},{"type":29,"tag":127,"props":12439,"children":12440},{"class":677,"line":668},[12441,12445,12449],{"type":29,"tag":127,"props":12442,"children":12443},{"style":682},[12444],{"type":56,"value":1317},{"type":29,"tag":127,"props":12446,"children":12447},{"style":688},[12448],{"type":56,"value":717},{"type":29,"tag":127,"props":12450,"children":12451},{"style":720},[12452],{"type":56,"value":1326},{"type":29,"tag":127,"props":12454,"children":12455},{"class":677,"line":1329},[12456,12460],{"type":29,"tag":127,"props":12457,"children":12458},{"style":682},[12459],{"type":56,"value":1529},{"type":29,"tag":127,"props":12461,"children":12462},{"style":688},[12463],{"type":56,"value":691},{"type":29,"tag":127,"props":12465,"children":12466},{"class":677,"line":1342},[12467,12471],{"type":29,"tag":127,"props":12468,"children":12469},{"style":688},[12470],{"type":56,"value":746},{"type":29,"tag":127,"props":12472,"children":12473},{"style":720},[12474],{"type":56,"value":1546},{"type":29,"tag":127,"props":12476,"children":12477},{"class":677,"line":118},[12478,12482],{"type":29,"tag":127,"props":12479,"children":12480},{"style":688},[12481],{"type":56,"value":746},{"type":29,"tag":127,"props":12483,"children":12484},{"style":720},[12485],{"type":56,"value":12486},"letsencrypt:/letsencrypt\n",{"type":29,"tag":127,"props":12488,"children":12489},{"class":677,"line":1367},[12490,12494],{"type":29,"tag":127,"props":12491,"children":12492},{"style":682},[12493],{"type":56,"value":1335},{"type":29,"tag":127,"props":12495,"children":12496},{"style":688},[12497],{"type":56,"value":691},{"type":29,"tag":127,"props":12499,"children":12500},{"class":677,"line":1380},[12501,12505],{"type":29,"tag":127,"props":12502,"children":12503},{"style":688},[12504],{"type":56,"value":746},{"type":29,"tag":127,"props":12506,"children":12507},{"style":720},[12508],{"type":56,"value":12509},"--log.level=INFO\n",{"type":29,"tag":127,"props":12511,"children":12512},{"class":677,"line":1393},[12513],{"type":29,"tag":127,"props":12514,"children":12515},{"emptyLinePlaceholder":500},[12516],{"type":56,"value":1399},{"type":29,"tag":127,"props":12518,"children":12519},{"class":677,"line":1402},[12520,12524],{"type":29,"tag":127,"props":12521,"children":12522},{"style":688},[12523],{"type":56,"value":746},{"type":29,"tag":127,"props":12525,"children":12526},{"style":720},[12527],{"type":56,"value":1412},{"type":29,"tag":127,"props":12529,"children":12530},{"class":677,"line":1415},[12531,12535],{"type":29,"tag":127,"props":12532,"children":12533},{"style":688},[12534],{"type":56,"value":746},{"type":29,"tag":127,"props":12536,"children":12537},{"style":720},[12538],{"type":56,"value":1447},{"type":29,"tag":127,"props":12540,"children":12541},{"class":677,"line":1428},[12542,12546],{"type":29,"tag":127,"props":12543,"children":12544},{"style":688},[12545],{"type":56,"value":746},{"type":29,"tag":127,"props":12547,"children":12548},{"style":720},[12549],{"type":56,"value":1460},{"type":29,"tag":127,"props":12551,"children":12552},{"class":677,"line":1437},[12553],{"type":29,"tag":127,"props":12554,"children":12555},{"emptyLinePlaceholder":500},[12556],{"type":56,"value":1399},{"type":29,"tag":127,"props":12558,"children":12559},{"class":677,"line":1450},[12560,12564],{"type":29,"tag":127,"props":12561,"children":12562},{"style":688},[12563],{"type":56,"value":746},{"type":29,"tag":127,"props":12565,"children":12566},{"style":720},[12567],{"type":56,"value":1425},{"type":29,"tag":127,"props":12569,"children":12570},{"class":677,"line":1463},[12571,12575],{"type":29,"tag":127,"props":12572,"children":12573},{"style":688},[12574],{"type":56,"value":746},{"type":29,"tag":127,"props":12576,"children":12577},{"style":720},[12578],{"type":56,"value":1473},{"type":29,"tag":127,"props":12580,"children":12581},{"class":677,"line":1476},[12582],{"type":29,"tag":127,"props":12583,"children":12584},{"emptyLinePlaceholder":500},[12585],{"type":56,"value":1399},{"type":29,"tag":127,"props":12587,"children":12588},{"class":677,"line":1484},[12589,12593],{"type":29,"tag":127,"props":12590,"children":12591},{"style":688},[12592],{"type":56,"value":746},{"type":29,"tag":127,"props":12594,"children":12595},{"style":720},[12596],{"type":56,"value":12597},"--providers.docker=true\n",{"type":29,"tag":127,"props":12599,"children":12600},{"class":677,"line":1497},[12601,12605],{"type":29,"tag":127,"props":12602,"children":12603},{"style":688},[12604],{"type":56,"value":746},{"type":29,"tag":127,"props":12606,"children":12607},{"style":720},[12608],{"type":56,"value":12609},"--providers.docker.exposedByDefault=false\n",{"type":29,"tag":127,"props":12611,"children":12612},{"class":677,"line":1510},[12613],{"type":29,"tag":127,"props":12614,"children":12615},{"emptyLinePlaceholder":500},[12616],{"type":56,"value":1399},{"type":29,"tag":127,"props":12618,"children":12619},{"class":677,"line":1523},[12620,12624],{"type":29,"tag":127,"props":12621,"children":12622},{"style":688},[12623],{"type":56,"value":746},{"type":29,"tag":127,"props":12625,"children":12626},{"style":720},[12627],{"type":56,"value":12628},"--certificatesresolvers.letsencrypt.acme.email=\u003Cinfo@example.com>\n",{"type":29,"tag":127,"props":12630,"children":12631},{"class":677,"line":1536},[12632,12636],{"type":29,"tag":127,"props":12633,"children":12634},{"style":688},[12635],{"type":56,"value":746},{"type":29,"tag":127,"props":12637,"children":12638},{"style":720},[12639],{"type":56,"value":1377},{"type":29,"tag":127,"props":12641,"children":12642},{"class":677,"line":1549},[12643,12647],{"type":29,"tag":127,"props":12644,"children":12645},{"style":688},[12646],{"type":56,"value":746},{"type":29,"tag":127,"props":12648,"children":12649},{"style":720},[12650],{"type":56,"value":1352},{"type":29,"tag":127,"props":12652,"children":12653},{"class":677,"line":2411},[12654,12658],{"type":29,"tag":127,"props":12655,"children":12656},{"style":688},[12657],{"type":56,"value":746},{"type":29,"tag":127,"props":12659,"children":12660},{"style":720},[12661],{"type":56,"value":1390},{"type":29,"tag":48,"props":12663,"children":12664},{},[12665],{"type":56,"value":12666},"Diese Konfiguration wird:",{"type":29,"tag":810,"props":12668,"children":12669},{},[12670,12679,12688,12693,12710,12719],{"type":29,"tag":814,"props":12671,"children":12672},{},[12673],{"type":29,"tag":645,"props":12674,"children":12676},{"href":12675},"https://doc.traefik.io/traefik/reference/install-configuration/providers/docker/",[12677],{"type":56,"value":12678},"den Docker-Provider aktivieren",{"type":29,"tag":814,"props":12680,"children":12681},{},[12682],{"type":29,"tag":645,"props":12683,"children":12685},{"href":12684},"https://doc.traefik.io/traefik/providers/docker/#exposedbydefault",[12686],{"type":56,"value":12687},"die Container-Erkennung deaktivieren",{"type":29,"tag":814,"props":12689,"children":12690},{},[12691],{"type":56,"value":12692},"den gesamten HTTP-traffic auf HTTPS umleiten",{"type":29,"tag":814,"props":12694,"children":12695},{},[12696],{"type":29,"tag":645,"props":12697,"children":12699},{"href":12698},"https://doc.traefik.io/traefik/https/acme/#httpchallenge",[12700,12702,12708],{"type":56,"value":12701},"Let's Encrypt mit ",{"type":29,"tag":672,"props":12703,"children":12705},{"className":12704},[],[12706],{"type":56,"value":12707},"HTTP-01",{"type":56,"value":12709},"-Challenge konfigurieren",{"type":29,"tag":814,"props":12711,"children":12712},{},[12713],{"type":29,"tag":645,"props":12714,"children":12716},{"href":12715},"https://doc.traefik.io/traefik/routing/entrypoints/#tls",[12717],{"type":56,"value":12718},"die TLS-Konfiguration auf alle Routen anwenden",{"type":29,"tag":814,"props":12720,"children":12721},{},[12722,12728],{"type":29,"tag":645,"props":12723,"children":12725},{"href":12724},"https://docs.docker.com/engine/network/tutorials/host/",[12726],{"type":56,"value":12727},"den Traefik-Container direkt an das Netzwerk des Hosts binden",{"type":56,"value":12729},", sodass keine zusätzliche Konfiguration für Traefik erforderlich ist",{"type":29,"tag":12312,"props":12731,"children":12733},{"id":12732},"das-gitlab-deployment",[12734],{"type":56,"value":12735},"Das GitLab-Deployment",{"type":29,"tag":48,"props":12737,"children":12738},{},[12739,12740,12749],{"type":56,"value":12322},{"type":29,"tag":52,"props":12741,"children":12742},{},[12743],{"type":29,"tag":672,"props":12744,"children":12746},{"className":12745},[],[12747],{"type":56,"value":12748},"\u003Cgitlab.example.com>",{"type":56,"value":12750}," durch Ihre eigene Domain zu ersetzen.",{"type":29,"tag":48,"props":12752,"children":12753},{},[12754,12756,12762,12764,12773],{"type":56,"value":12755},"Bitte schauen Sie in die ",{"type":29,"tag":645,"props":12757,"children":12759},{"href":12758},"https://docs.gitlab.com/install/docker/installation/#create-a-directory-for-the-volumes",[12760],{"type":56,"value":12761},"offizielle Dokumentation",{"type":56,"value":12763}," bezüglich des ",{"type":29,"tag":52,"props":12765,"children":12766},{},[12767],{"type":29,"tag":672,"props":12768,"children":12770},{"className":12769},[],[12771],{"type":56,"value":12772},"GITLAB_HOME",{"type":56,"value":12774},"-Verzeichnisses",{"type":29,"tag":659,"props":12776,"children":12779},{"className":669,"code":12777,"filename":11659,"highlights":12778,"language":508,"meta":7,"style":7},"services:\n  gitlab:\n    image: gitlab/gitlab-ce:\u003Cversion>-ce.0\n    container_name: gitlab\n    labels:\n      - \"traefik.enable=true\"\n      - \"traefik.http.routers.gitlab.rule=Host(`\u003Cgitlab.example.com>`)\"\n      - \"traefik.http.routers.gitlab.service=gitlab\"\n      - \"traefik.http.services.gitlab.loadbalancer.server.port=80\"\n    restart: always\n    hostname: 'gitlab.example.com'\n    environment:\n      GITLAB_OMNIBUS_CONFIG: |\n        # Add any other gitlab.rb configuration here, each on its own line\n        external_url '\u003Chttps://gitlab.example.com>'\n        \n        letsencrypt['enable'] = false\n        \n        nginx['listen_port'] = 80\n        nginx['listen_https'] = false\n        nginx['proxy_set_headers'] = {\n          \"X-Forwarded-Proto\" => \"https\",\n          \"X-Forwarded-Ssl\" => \"on\"\n        }\n        \n        gitlab_rails['gitlab_shell_ssh_port'] = 2424\n    ports:\n      - '2424:22'\n    volumes:\n      - '$GITLAB_HOME/config:/etc/gitlab'\n      - '$GITLAB_HOME/logs:/var/log/gitlab'\n      - '$GITLAB_HOME/data:/var/opt/gitlab'\n    shm_size: '256m'\n",[664,665,666,667,668,1415,1437,1450,1463,1476,1484,1497,1523,1549],[12780],{"type":29,"tag":672,"props":12781,"children":12782},{"__ignoreMap":7},[12783,12794,12805,12821,12836,12848,12860,12873,12886,12899,12914,12930,12941,12956,12963,12971,12979,12988,12995,13004,13013,13022,13031,13040,13048,13055,13064,13075,13088,13099,13110,13121,13132],{"type":29,"tag":127,"props":12784,"children":12785},{"class":677,"line":678},[12786,12790],{"type":29,"tag":127,"props":12787,"children":12788},{"style":682},[12789],{"type":56,"value":685},{"type":29,"tag":127,"props":12791,"children":12792},{"style":688},[12793],{"type":56,"value":691},{"type":29,"tag":127,"props":12795,"children":12796},{"class":677,"line":342},[12797,12801],{"type":29,"tag":127,"props":12798,"children":12799},{"style":682},[12800],{"type":56,"value":11682},{"type":29,"tag":127,"props":12802,"children":12803},{"style":688},[12804],{"type":56,"value":691},{"type":29,"tag":127,"props":12806,"children":12807},{"class":677,"line":706},[12808,12812,12816],{"type":29,"tag":127,"props":12809,"children":12810},{"style":682},[12811],{"type":56,"value":712},{"type":29,"tag":127,"props":12813,"children":12814},{"style":688},[12815],{"type":56,"value":717},{"type":29,"tag":127,"props":12817,"children":12818},{"style":720},[12819],{"type":56,"value":12820},"gitlab/gitlab-ce:\u003Cversion>-ce.0\n",{"type":29,"tag":127,"props":12822,"children":12823},{"class":677,"line":726},[12824,12828,12832],{"type":29,"tag":127,"props":12825,"children":12826},{"style":682},[12827],{"type":56,"value":1267},{"type":29,"tag":127,"props":12829,"children":12830},{"style":688},[12831],{"type":56,"value":717},{"type":29,"tag":127,"props":12833,"children":12834},{"style":720},[12835],{"type":56,"value":11718},{"type":29,"tag":127,"props":12837,"children":12839},{"class":12838,"line":664},[677,740],[12840,12844],{"type":29,"tag":127,"props":12841,"children":12842},{"style":682},[12843],{"type":56,"value":732},{"type":29,"tag":127,"props":12845,"children":12846},{"style":688},[12847],{"type":56,"value":691},{"type":29,"tag":127,"props":12849,"children":12851},{"class":12850,"line":665},[677,740],[12852,12856],{"type":29,"tag":127,"props":12853,"children":12854},{"style":688},[12855],{"type":56,"value":746},{"type":29,"tag":127,"props":12857,"children":12858},{"style":720},[12859],{"type":56,"value":751},{"type":29,"tag":127,"props":12861,"children":12863},{"class":12862,"line":666},[677,740],[12864,12868],{"type":29,"tag":127,"props":12865,"children":12866},{"style":688},[12867],{"type":56,"value":746},{"type":29,"tag":127,"props":12869,"children":12870},{"style":720},[12871],{"type":56,"value":12872},"\"traefik.http.routers.gitlab.rule=Host(`\u003Cgitlab.example.com>`)\"\n",{"type":29,"tag":127,"props":12874,"children":12876},{"class":12875,"line":667},[677,740],[12877,12881],{"type":29,"tag":127,"props":12878,"children":12879},{"style":688},[12880],{"type":56,"value":746},{"type":29,"tag":127,"props":12882,"children":12883},{"style":720},[12884],{"type":56,"value":12885},"\"traefik.http.routers.gitlab.service=gitlab\"\n",{"type":29,"tag":127,"props":12887,"children":12889},{"class":12888,"line":668},[677,740],[12890,12894],{"type":29,"tag":127,"props":12891,"children":12892},{"style":688},[12893],{"type":56,"value":746},{"type":29,"tag":127,"props":12895,"children":12896},{"style":720},[12897],{"type":56,"value":12898},"\"traefik.http.services.gitlab.loadbalancer.server.port=80\"\n",{"type":29,"tag":127,"props":12900,"children":12901},{"class":677,"line":1329},[12902,12906,12910],{"type":29,"tag":127,"props":12903,"children":12904},{"style":682},[12905],{"type":56,"value":1284},{"type":29,"tag":127,"props":12907,"children":12908},{"style":688},[12909],{"type":56,"value":717},{"type":29,"tag":127,"props":12911,"children":12912},{"style":720},[12913],{"type":56,"value":1293},{"type":29,"tag":127,"props":12915,"children":12916},{"class":677,"line":1342},[12917,12921,12925],{"type":29,"tag":127,"props":12918,"children":12919},{"style":682},[12920],{"type":56,"value":11741},{"type":29,"tag":127,"props":12922,"children":12923},{"style":688},[12924],{"type":56,"value":717},{"type":29,"tag":127,"props":12926,"children":12927},{"style":720},[12928],{"type":56,"value":12929},"'gitlab.example.com'\n",{"type":29,"tag":127,"props":12931,"children":12932},{"class":677,"line":118},[12933,12937],{"type":29,"tag":127,"props":12934,"children":12935},{"style":682},[12936],{"type":56,"value":10054},{"type":29,"tag":127,"props":12938,"children":12939},{"style":688},[12940],{"type":56,"value":691},{"type":29,"tag":127,"props":12942,"children":12943},{"class":677,"line":1367},[12944,12948,12952],{"type":29,"tag":127,"props":12945,"children":12946},{"style":682},[12947],{"type":56,"value":11769},{"type":29,"tag":127,"props":12949,"children":12950},{"style":688},[12951],{"type":56,"value":717},{"type":29,"tag":127,"props":12953,"children":12954},{"style":4942},[12955],{"type":56,"value":11778},{"type":29,"tag":127,"props":12957,"children":12958},{"class":677,"line":1380},[12959],{"type":29,"tag":127,"props":12960,"children":12961},{"style":720},[12962],{"type":56,"value":11786},{"type":29,"tag":127,"props":12964,"children":12965},{"class":677,"line":1393},[12966],{"type":29,"tag":127,"props":12967,"children":12968},{"style":720},[12969],{"type":56,"value":12970},"        external_url '\u003Chttps://gitlab.example.com>'\n",{"type":29,"tag":127,"props":12972,"children":12973},{"class":677,"line":1402},[12974],{"type":29,"tag":127,"props":12975,"children":12976},{"style":720},[12977],{"type":56,"value":12978},"        \n",{"type":29,"tag":127,"props":12980,"children":12982},{"class":12981,"line":1415},[677,740],[12983],{"type":29,"tag":127,"props":12984,"children":12985},{"style":720},[12986],{"type":56,"value":12987},"        letsencrypt['enable'] = false\n",{"type":29,"tag":127,"props":12989,"children":12990},{"class":677,"line":1428},[12991],{"type":29,"tag":127,"props":12992,"children":12993},{"style":720},[12994],{"type":56,"value":12978},{"type":29,"tag":127,"props":12996,"children":12998},{"class":12997,"line":1437},[677,740],[12999],{"type":29,"tag":127,"props":13000,"children":13001},{"style":720},[13002],{"type":56,"value":13003},"        nginx['listen_port'] = 80\n",{"type":29,"tag":127,"props":13005,"children":13007},{"class":13006,"line":1450},[677,740],[13008],{"type":29,"tag":127,"props":13009,"children":13010},{"style":720},[13011],{"type":56,"value":13012},"        nginx['listen_https'] = false\n",{"type":29,"tag":127,"props":13014,"children":13016},{"class":13015,"line":1463},[677,740],[13017],{"type":29,"tag":127,"props":13018,"children":13019},{"style":720},[13020],{"type":56,"value":13021},"        nginx['proxy_set_headers'] = {\n",{"type":29,"tag":127,"props":13023,"children":13025},{"class":13024,"line":1476},[677,740],[13026],{"type":29,"tag":127,"props":13027,"children":13028},{"style":720},[13029],{"type":56,"value":13030},"          \"X-Forwarded-Proto\" => \"https\",\n",{"type":29,"tag":127,"props":13032,"children":13034},{"class":13033,"line":1484},[677,740],[13035],{"type":29,"tag":127,"props":13036,"children":13037},{"style":720},[13038],{"type":56,"value":13039},"          \"X-Forwarded-Ssl\" => \"on\"\n",{"type":29,"tag":127,"props":13041,"children":13043},{"class":13042,"line":1497},[677,740],[13044],{"type":29,"tag":127,"props":13045,"children":13046},{"style":720},[13047],{"type":56,"value":3541},{"type":29,"tag":127,"props":13049,"children":13050},{"class":677,"line":1510},[13051],{"type":29,"tag":127,"props":13052,"children":13053},{"style":720},[13054],{"type":56,"value":12978},{"type":29,"tag":127,"props":13056,"children":13058},{"class":13057,"line":1523},[677,740],[13059],{"type":29,"tag":127,"props":13060,"children":13061},{"style":720},[13062],{"type":56,"value":13063},"        gitlab_rails['gitlab_shell_ssh_port'] = 2424\n",{"type":29,"tag":127,"props":13065,"children":13066},{"class":677,"line":1536},[13067,13071],{"type":29,"tag":127,"props":13068,"children":13069},{"style":682},[13070],{"type":56,"value":11802},{"type":29,"tag":127,"props":13072,"children":13073},{"style":688},[13074],{"type":56,"value":691},{"type":29,"tag":127,"props":13076,"children":13078},{"class":13077,"line":1549},[677,740],[13079,13083],{"type":29,"tag":127,"props":13080,"children":13081},{"style":688},[13082],{"type":56,"value":746},{"type":29,"tag":127,"props":13084,"children":13085},{"style":720},[13086],{"type":56,"value":13087},"'2424:22'\n",{"type":29,"tag":127,"props":13089,"children":13090},{"class":677,"line":2411},[13091,13095],{"type":29,"tag":127,"props":13092,"children":13093},{"style":682},[13094],{"type":56,"value":1529},{"type":29,"tag":127,"props":13096,"children":13097},{"style":688},[13098],{"type":56,"value":691},{"type":29,"tag":127,"props":13100,"children":13101},{"class":677,"line":2419},[13102,13106],{"type":29,"tag":127,"props":13103,"children":13104},{"style":688},[13105],{"type":56,"value":746},{"type":29,"tag":127,"props":13107,"children":13108},{"style":720},[13109],{"type":56,"value":11865},{"type":29,"tag":127,"props":13111,"children":13112},{"class":677,"line":2439},[13113,13117],{"type":29,"tag":127,"props":13114,"children":13115},{"style":688},[13116],{"type":56,"value":746},{"type":29,"tag":127,"props":13118,"children":13119},{"style":720},[13120],{"type":56,"value":11877},{"type":29,"tag":127,"props":13122,"children":13123},{"class":677,"line":2460},[13124,13128],{"type":29,"tag":127,"props":13125,"children":13126},{"style":688},[13127],{"type":56,"value":746},{"type":29,"tag":127,"props":13129,"children":13130},{"style":720},[13131],{"type":56,"value":11889},{"type":29,"tag":127,"props":13133,"children":13134},{"class":677,"line":2472},[13135,13139,13143],{"type":29,"tag":127,"props":13136,"children":13137},{"style":682},[13138],{"type":56,"value":11897},{"type":29,"tag":127,"props":13140,"children":13141},{"style":688},[13142],{"type":56,"value":717},{"type":29,"tag":127,"props":13144,"children":13145},{"style":720},[13146],{"type":56,"value":11906},{"type":29,"tag":48,"props":13148,"children":13149},{},[13150],{"type":56,"value":12666},{"type":29,"tag":810,"props":13152,"children":13153},{},[13154,13159,13164,13169,13174],{"type":29,"tag":814,"props":13155,"children":13156},{},[13157],{"type":56,"value":13158},"Let's Encrypt deaktivieren",{"type":29,"tag":814,"props":13160,"children":13161},{},[13162],{"type":56,"value":13163},"das Abhören von HTTPS deaktivieren und auf Port 80 hören",{"type":29,"tag":814,"props":13165,"children":13166},{},[13167],{"type":56,"value":13168},"die erforderlichen Proxy-Header setzen",{"type":29,"tag":814,"props":13170,"children":13171},{},[13172],{"type":56,"value":13173},"den SSH-Port auf 2424 ändern",{"type":29,"tag":814,"props":13175,"children":13176},{},[13177,13179,13185],{"type":56,"value":13178},"Traefik anweisen, den gesamten Verkehr für ",{"type":29,"tag":672,"props":13180,"children":13182},{"className":13181},[],[13183],{"type":56,"value":13184},"gitlab.example.com",{"type":56,"value":13186}," an Port 80 des Containers weiterzuleiten",{"type":29,"tag":1670,"props":13188,"children":13189},{},[],{"type":29,"tag":48,"props":13191,"children":13192},{},[13193],{"type":29,"tag":127,"props":13194,"children":13196},{"className":13195},[5257],[13197],{"type":56,"value":7310},{"type":29,"tag":1670,"props":13199,"children":13200},{},[],{"type":29,"tag":1189,"props":13202,"children":13203},{},[],{"type":29,"tag":122,"props":13205,"children":13207},{"id":13206},"gitlab-container-registry",[13208],{"type":56,"value":13209},"GitLab Container-Registry",{"type":29,"tag":48,"props":13211,"children":13212},{},[13213,13215,13221],{"type":56,"value":13214},"Wenn Sie so weit gekommen sind, möchten Sie wahrscheinlich auch die ",{"type":29,"tag":645,"props":13216,"children":13218},{"href":13217},"https://docs.gitlab.com/administration/packages/container_registry/",[13219],{"type":56,"value":13220},"Container-Registry",{"type":56,"value":13222}," einrichten",{"type":29,"tag":12312,"props":13224,"children":13226},{"id":13225},"container-registry-unter-eigener-domain-konfigurieren",[13227],{"type":29,"tag":645,"props":13228,"children":13230},{"href":13229},"https://docs.gitlab.com/administration/packages/container_registry/#configure-container-registry-under-its-own-domain",[13231],{"type":56,"value":13232},"Container-Registry unter eigener Domain konfigurieren",{"type":29,"tag":48,"props":13234,"children":13235},{},[13236,13238,13244],{"type":56,"value":13237},"Diese Einrichtung ist einfach. Wir müssen nur die ",{"type":29,"tag":672,"props":13239,"children":13241},{"className":13240},[],[13242],{"type":56,"value":13243},"registry_external_url",{"type":56,"value":13245}," setzen und Traefik anweisen, wohin die Anfragen weitergeleitet werden sollen",{"type":29,"tag":1670,"props":13247,"children":13248},{},[],{"type":29,"tag":13250,"props":13251,"children":13253},"h5",{"id":13252},"aktualisierung-der-gitlab-konfiguration",[13254],{"type":56,"value":13255},"Aktualisierung der GitLab-Konfiguration",{"type":29,"tag":659,"props":13257,"children":13260},{"className":669,"code":13258,"filename":11659,"highlights":13259,"language":508,"meta":7,"style":7},"services:\n  gitlab:\n    image: gitlab/gitlab-ce:\u003Cversion>-ce.0\n    container_name: gitlab\n    labels:\n      - \"traefik.enable=true\"\n      - \"traefik.http.routers.gitlab.rule=Host(`\u003Cgitlab.example.com>`)\"\n      - \"traefik.http.routers.gitlab.service=gitlab\"\n      - \"traefik.http.services.gitlab.loadbalancer.server.port=80\"\n      - \"traefik.http.routers.container-registry.rule=Host(`registry.gitlab.example.com`)\"\n      - \"traefik.http.services.container-registry.loadbalancer.server.port=5000\"\n    restart: always\n    hostname: 'gitlab.example.com'\n    environment:\n      GITLAB_OMNIBUS_CONFIG: |\n        # Add any other gitlab.rb configuration here, each on its own line\n        external_url '\u003Chttps://gitlab.example.com>'\n\n        letsencrypt['enable'] = false\n\n        nginx['listen_port'] = 80\n        nginx['listen_https'] = false\n        nginx['proxy_set_headers'] = {\n          \"X-Forwarded-Proto\" => \"https\",\n          \"X-Forwarded-Ssl\" => \"on\"\n        }\n\n        gitlab_rails['gitlab_shell_ssh_port'] = 2424\n\n        registry_external_url '\u003Chttps://registry.gitlab.example.com>'\n        registry_nginx['enable'] = false\n    ports:\n      - '2424:22'\n    volumes:\n      - '$GITLAB_HOME/config:/etc/gitlab'\n      - '$GITLAB_HOME/logs:/var/log/gitlab'\n      - '$GITLAB_HOME/data:/var/opt/gitlab'\n    shm_size: '256m'\n",[1329,1342,2419,2439],[13261],{"type":29,"tag":672,"props":13262,"children":13263},{"__ignoreMap":7},[13264,13275,13286,13301,13316,13327,13338,13349,13360,13371,13384,13397,13412,13427,13438,13453,13460,13467,13474,13481,13488,13495,13502,13509,13516,13523,13530,13537,13544,13551,13560,13569,13580,13591,13602,13613,13624,13635],{"type":29,"tag":127,"props":13265,"children":13266},{"class":677,"line":678},[13267,13271],{"type":29,"tag":127,"props":13268,"children":13269},{"style":682},[13270],{"type":56,"value":685},{"type":29,"tag":127,"props":13272,"children":13273},{"style":688},[13274],{"type":56,"value":691},{"type":29,"tag":127,"props":13276,"children":13277},{"class":677,"line":342},[13278,13282],{"type":29,"tag":127,"props":13279,"children":13280},{"style":682},[13281],{"type":56,"value":11682},{"type":29,"tag":127,"props":13283,"children":13284},{"style":688},[13285],{"type":56,"value":691},{"type":29,"tag":127,"props":13287,"children":13288},{"class":677,"line":706},[13289,13293,13297],{"type":29,"tag":127,"props":13290,"children":13291},{"style":682},[13292],{"type":56,"value":712},{"type":29,"tag":127,"props":13294,"children":13295},{"style":688},[13296],{"type":56,"value":717},{"type":29,"tag":127,"props":13298,"children":13299},{"style":720},[13300],{"type":56,"value":12820},{"type":29,"tag":127,"props":13302,"children":13303},{"class":677,"line":726},[13304,13308,13312],{"type":29,"tag":127,"props":13305,"children":13306},{"style":682},[13307],{"type":56,"value":1267},{"type":29,"tag":127,"props":13309,"children":13310},{"style":688},[13311],{"type":56,"value":717},{"type":29,"tag":127,"props":13313,"children":13314},{"style":720},[13315],{"type":56,"value":11718},{"type":29,"tag":127,"props":13317,"children":13318},{"class":677,"line":664},[13319,13323],{"type":29,"tag":127,"props":13320,"children":13321},{"style":682},[13322],{"type":56,"value":732},{"type":29,"tag":127,"props":13324,"children":13325},{"style":688},[13326],{"type":56,"value":691},{"type":29,"tag":127,"props":13328,"children":13329},{"class":677,"line":665},[13330,13334],{"type":29,"tag":127,"props":13331,"children":13332},{"style":688},[13333],{"type":56,"value":746},{"type":29,"tag":127,"props":13335,"children":13336},{"style":720},[13337],{"type":56,"value":751},{"type":29,"tag":127,"props":13339,"children":13340},{"class":677,"line":666},[13341,13345],{"type":29,"tag":127,"props":13342,"children":13343},{"style":688},[13344],{"type":56,"value":746},{"type":29,"tag":127,"props":13346,"children":13347},{"style":720},[13348],{"type":56,"value":12872},{"type":29,"tag":127,"props":13350,"children":13351},{"class":677,"line":667},[13352,13356],{"type":29,"tag":127,"props":13353,"children":13354},{"style":688},[13355],{"type":56,"value":746},{"type":29,"tag":127,"props":13357,"children":13358},{"style":720},[13359],{"type":56,"value":12885},{"type":29,"tag":127,"props":13361,"children":13362},{"class":677,"line":668},[13363,13367],{"type":29,"tag":127,"props":13364,"children":13365},{"style":688},[13366],{"type":56,"value":746},{"type":29,"tag":127,"props":13368,"children":13369},{"style":720},[13370],{"type":56,"value":12898},{"type":29,"tag":127,"props":13372,"children":13374},{"class":13373,"line":1329},[677,740],[13375,13379],{"type":29,"tag":127,"props":13376,"children":13377},{"style":688},[13378],{"type":56,"value":746},{"type":29,"tag":127,"props":13380,"children":13381},{"style":720},[13382],{"type":56,"value":13383},"\"traefik.http.routers.container-registry.rule=Host(`registry.gitlab.example.com`)\"\n",{"type":29,"tag":127,"props":13385,"children":13387},{"class":13386,"line":1342},[677,740],[13388,13392],{"type":29,"tag":127,"props":13389,"children":13390},{"style":688},[13391],{"type":56,"value":746},{"type":29,"tag":127,"props":13393,"children":13394},{"style":720},[13395],{"type":56,"value":13396},"\"traefik.http.services.container-registry.loadbalancer.server.port=5000\"\n",{"type":29,"tag":127,"props":13398,"children":13399},{"class":677,"line":118},[13400,13404,13408],{"type":29,"tag":127,"props":13401,"children":13402},{"style":682},[13403],{"type":56,"value":1284},{"type":29,"tag":127,"props":13405,"children":13406},{"style":688},[13407],{"type":56,"value":717},{"type":29,"tag":127,"props":13409,"children":13410},{"style":720},[13411],{"type":56,"value":1293},{"type":29,"tag":127,"props":13413,"children":13414},{"class":677,"line":1367},[13415,13419,13423],{"type":29,"tag":127,"props":13416,"children":13417},{"style":682},[13418],{"type":56,"value":11741},{"type":29,"tag":127,"props":13420,"children":13421},{"style":688},[13422],{"type":56,"value":717},{"type":29,"tag":127,"props":13424,"children":13425},{"style":720},[13426],{"type":56,"value":12929},{"type":29,"tag":127,"props":13428,"children":13429},{"class":677,"line":1380},[13430,13434],{"type":29,"tag":127,"props":13431,"children":13432},{"style":682},[13433],{"type":56,"value":10054},{"type":29,"tag":127,"props":13435,"children":13436},{"style":688},[13437],{"type":56,"value":691},{"type":29,"tag":127,"props":13439,"children":13440},{"class":677,"line":1393},[13441,13445,13449],{"type":29,"tag":127,"props":13442,"children":13443},{"style":682},[13444],{"type":56,"value":11769},{"type":29,"tag":127,"props":13446,"children":13447},{"style":688},[13448],{"type":56,"value":717},{"type":29,"tag":127,"props":13450,"children":13451},{"style":4942},[13452],{"type":56,"value":11778},{"type":29,"tag":127,"props":13454,"children":13455},{"class":677,"line":1402},[13456],{"type":29,"tag":127,"props":13457,"children":13458},{"style":720},[13459],{"type":56,"value":11786},{"type":29,"tag":127,"props":13461,"children":13462},{"class":677,"line":1415},[13463],{"type":29,"tag":127,"props":13464,"children":13465},{"style":720},[13466],{"type":56,"value":12970},{"type":29,"tag":127,"props":13468,"children":13469},{"class":677,"line":1428},[13470],{"type":29,"tag":127,"props":13471,"children":13472},{"emptyLinePlaceholder":500},[13473],{"type":56,"value":1399},{"type":29,"tag":127,"props":13475,"children":13476},{"class":677,"line":1437},[13477],{"type":29,"tag":127,"props":13478,"children":13479},{"style":720},[13480],{"type":56,"value":12987},{"type":29,"tag":127,"props":13482,"children":13483},{"class":677,"line":1450},[13484],{"type":29,"tag":127,"props":13485,"children":13486},{"emptyLinePlaceholder":500},[13487],{"type":56,"value":1399},{"type":29,"tag":127,"props":13489,"children":13490},{"class":677,"line":1463},[13491],{"type":29,"tag":127,"props":13492,"children":13493},{"style":720},[13494],{"type":56,"value":13003},{"type":29,"tag":127,"props":13496,"children":13497},{"class":677,"line":1476},[13498],{"type":29,"tag":127,"props":13499,"children":13500},{"style":720},[13501],{"type":56,"value":13012},{"type":29,"tag":127,"props":13503,"children":13504},{"class":677,"line":1484},[13505],{"type":29,"tag":127,"props":13506,"children":13507},{"style":720},[13508],{"type":56,"value":13021},{"type":29,"tag":127,"props":13510,"children":13511},{"class":677,"line":1497},[13512],{"type":29,"tag":127,"props":13513,"children":13514},{"style":720},[13515],{"type":56,"value":13030},{"type":29,"tag":127,"props":13517,"children":13518},{"class":677,"line":1510},[13519],{"type":29,"tag":127,"props":13520,"children":13521},{"style":720},[13522],{"type":56,"value":13039},{"type":29,"tag":127,"props":13524,"children":13525},{"class":677,"line":1523},[13526],{"type":29,"tag":127,"props":13527,"children":13528},{"style":720},[13529],{"type":56,"value":3541},{"type":29,"tag":127,"props":13531,"children":13532},{"class":677,"line":1536},[13533],{"type":29,"tag":127,"props":13534,"children":13535},{"emptyLinePlaceholder":500},[13536],{"type":56,"value":1399},{"type":29,"tag":127,"props":13538,"children":13539},{"class":677,"line":1549},[13540],{"type":29,"tag":127,"props":13541,"children":13542},{"style":720},[13543],{"type":56,"value":13063},{"type":29,"tag":127,"props":13545,"children":13546},{"class":677,"line":2411},[13547],{"type":29,"tag":127,"props":13548,"children":13549},{"emptyLinePlaceholder":500},[13550],{"type":56,"value":1399},{"type":29,"tag":127,"props":13552,"children":13554},{"class":13553,"line":2419},[677,740],[13555],{"type":29,"tag":127,"props":13556,"children":13557},{"style":720},[13558],{"type":56,"value":13559},"        registry_external_url '\u003Chttps://registry.gitlab.example.com>'\n",{"type":29,"tag":127,"props":13561,"children":13563},{"class":13562,"line":2439},[677,740],[13564],{"type":29,"tag":127,"props":13565,"children":13566},{"style":720},[13567],{"type":56,"value":13568},"        registry_nginx['enable'] = false\n",{"type":29,"tag":127,"props":13570,"children":13571},{"class":677,"line":2460},[13572,13576],{"type":29,"tag":127,"props":13573,"children":13574},{"style":682},[13575],{"type":56,"value":11802},{"type":29,"tag":127,"props":13577,"children":13578},{"style":688},[13579],{"type":56,"value":691},{"type":29,"tag":127,"props":13581,"children":13582},{"class":677,"line":2472},[13583,13587],{"type":29,"tag":127,"props":13584,"children":13585},{"style":688},[13586],{"type":56,"value":746},{"type":29,"tag":127,"props":13588,"children":13589},{"style":720},[13590],{"type":56,"value":13087},{"type":29,"tag":127,"props":13592,"children":13593},{"class":677,"line":2488},[13594,13598],{"type":29,"tag":127,"props":13595,"children":13596},{"style":682},[13597],{"type":56,"value":1529},{"type":29,"tag":127,"props":13599,"children":13600},{"style":688},[13601],{"type":56,"value":691},{"type":29,"tag":127,"props":13603,"children":13604},{"class":677,"line":2496},[13605,13609],{"type":29,"tag":127,"props":13606,"children":13607},{"style":688},[13608],{"type":56,"value":746},{"type":29,"tag":127,"props":13610,"children":13611},{"style":720},[13612],{"type":56,"value":11865},{"type":29,"tag":127,"props":13614,"children":13615},{"class":677,"line":1970},[13616,13620],{"type":29,"tag":127,"props":13617,"children":13618},{"style":688},[13619],{"type":56,"value":746},{"type":29,"tag":127,"props":13621,"children":13622},{"style":720},[13623],{"type":56,"value":11877},{"type":29,"tag":127,"props":13625,"children":13626},{"class":677,"line":1971},[13627,13631],{"type":29,"tag":127,"props":13628,"children":13629},{"style":688},[13630],{"type":56,"value":746},{"type":29,"tag":127,"props":13632,"children":13633},{"style":720},[13634],{"type":56,"value":11889},{"type":29,"tag":127,"props":13636,"children":13637},{"class":677,"line":1972},[13638,13642,13646],{"type":29,"tag":127,"props":13639,"children":13640},{"style":682},[13641],{"type":56,"value":11897},{"type":29,"tag":127,"props":13643,"children":13644},{"style":688},[13645],{"type":56,"value":717},{"type":29,"tag":127,"props":13647,"children":13648},{"style":720},[13649],{"type":56,"value":11906},{"type":29,"tag":48,"props":13651,"children":13652},{},[13653],{"type":56,"value":12666},{"type":29,"tag":810,"props":13655,"children":13656},{},[13657,13662,13667],{"type":29,"tag":814,"props":13658,"children":13659},{},[13660],{"type":56,"value":13661},"die externe URL der Registry setzen",{"type":29,"tag":814,"props":13663,"children":13664},{},[13665],{"type":56,"value":13666},"Nginx für die Registry deaktivieren",{"type":29,"tag":814,"props":13668,"children":13669},{},[13670,13671,13677],{"type":56,"value":13178},{"type":29,"tag":672,"props":13672,"children":13674},{"className":13673},[],[13675],{"type":56,"value":13676},"registry.gitlab.example.com",{"type":56,"value":13678}," an Port 5000 des Containers weiterzuleiten",{"type":29,"tag":1670,"props":13680,"children":13681},{},[],{"type":29,"tag":1189,"props":13683,"children":13684},{},[],{"type":29,"tag":12312,"props":13686,"children":13688},{"id":13687},"container-registry-unter-einer-bestehenden-gitlab-domain-konfigurieren",[13689],{"type":29,"tag":645,"props":13690,"children":13692},{"href":13691},"https://docs.gitlab.com/administration/packages/container_registry/#configure-container-registry-under-an-existing-gitlab-domain",[13693],{"type":56,"value":13694},"Container-Registry unter einer bestehenden GitLab-Domain konfigurieren",{"type":29,"tag":13250,"props":13696,"children":13698},{"id":13697},"aktualisierung-der-traefik-konfiguration",[13699],{"type":56,"value":13700},"Aktualisierung der Traefik-Konfiguration",{"type":29,"tag":659,"props":13702,"children":13705},{"className":669,"code":13703,"filename":12337,"highlights":13704,"language":508,"meta":7,"style":7},"volumes:\n  letsencrypt:\n\nservices:\n  traefik:\n    image: traefik:3\n    container_name: traefik\n    restart: always\n    network_mode: host\n    volumes:\n      - /var/run/docker.sock:/var/run/docker.sock:ro\n      - letsencrypt:/letsencrypt\n    command:\n      - --log.level=INFO\n\n      - --entrypoints.web.address=:80\n      - --entrypoints.web.http.redirections.entrypoint.to=websecure\n      - --entrypoints.web.http.redirections.entrypoint.scheme=https\n\n      - --entrypoints.websecure.address=:443\n      - --entrypoints.websecure.http.tls.certresolver=letsencrypt\n        \n      - --entrypoints.container-registry.address=:5050\n      - --entrypoints.container-registry.http.tls.certresolver=letsencrypt\n\n      - --providers.docker=true\n      - --providers.docker.exposedByDefault=false\n\n      - --certificatesresolvers.letsencrypt.acme.email=\u003Cinfo@example.com>\n      - --certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json\n      - --certificatesresolvers.letsencrypt.acme.httpchallenge=true\n      - --certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web\n",[1484,1497],[13706],{"type":29,"tag":672,"props":13707,"children":13708},{"__ignoreMap":7},[13709,13720,13731,13738,13749,13760,13775,13790,13805,13820,13831,13842,13853,13864,13875,13882,13893,13904,13915,13922,13933,13944,13951,13964,13977,13984,13995,14006,14013,14024,14035,14046],{"type":29,"tag":127,"props":13710,"children":13711},{"class":677,"line":678},[13712,13716],{"type":29,"tag":127,"props":13713,"children":13714},{"style":682},[13715],{"type":56,"value":1212},{"type":29,"tag":127,"props":13717,"children":13718},{"style":688},[13719],{"type":56,"value":691},{"type":29,"tag":127,"props":13721,"children":13722},{"class":677,"line":342},[13723,13727],{"type":29,"tag":127,"props":13724,"children":13725},{"style":682},[13726],{"type":56,"value":1224},{"type":29,"tag":127,"props":13728,"children":13729},{"style":688},[13730],{"type":56,"value":691},{"type":29,"tag":127,"props":13732,"children":13733},{"class":677,"line":706},[13734],{"type":29,"tag":127,"props":13735,"children":13736},{"emptyLinePlaceholder":500},[13737],{"type":56,"value":1399},{"type":29,"tag":127,"props":13739,"children":13740},{"class":677,"line":726},[13741,13745],{"type":29,"tag":127,"props":13742,"children":13743},{"style":682},[13744],{"type":56,"value":685},{"type":29,"tag":127,"props":13746,"children":13747},{"style":688},[13748],{"type":56,"value":691},{"type":29,"tag":127,"props":13750,"children":13751},{"class":677,"line":664},[13752,13756],{"type":29,"tag":127,"props":13753,"children":13754},{"style":682},[13755],{"type":56,"value":1255},{"type":29,"tag":127,"props":13757,"children":13758},{"style":688},[13759],{"type":56,"value":691},{"type":29,"tag":127,"props":13761,"children":13762},{"class":677,"line":665},[13763,13767,13771],{"type":29,"tag":127,"props":13764,"children":13765},{"style":682},[13766],{"type":56,"value":712},{"type":29,"tag":127,"props":13768,"children":13769},{"style":688},[13770],{"type":56,"value":717},{"type":29,"tag":127,"props":13772,"children":13773},{"style":720},[13774],{"type":56,"value":1309},{"type":29,"tag":127,"props":13776,"children":13777},{"class":677,"line":666},[13778,13782,13786],{"type":29,"tag":127,"props":13779,"children":13780},{"style":682},[13781],{"type":56,"value":1267},{"type":29,"tag":127,"props":13783,"children":13784},{"style":688},[13785],{"type":56,"value":717},{"type":29,"tag":127,"props":13787,"children":13788},{"style":720},[13789],{"type":56,"value":1276},{"type":29,"tag":127,"props":13791,"children":13792},{"class":677,"line":667},[13793,13797,13801],{"type":29,"tag":127,"props":13794,"children":13795},{"style":682},[13796],{"type":56,"value":1284},{"type":29,"tag":127,"props":13798,"children":13799},{"style":688},[13800],{"type":56,"value":717},{"type":29,"tag":127,"props":13802,"children":13803},{"style":720},[13804],{"type":56,"value":1293},{"type":29,"tag":127,"props":13806,"children":13807},{"class":677,"line":668},[13808,13812,13816],{"type":29,"tag":127,"props":13809,"children":13810},{"style":682},[13811],{"type":56,"value":1317},{"type":29,"tag":127,"props":13813,"children":13814},{"style":688},[13815],{"type":56,"value":717},{"type":29,"tag":127,"props":13817,"children":13818},{"style":720},[13819],{"type":56,"value":1326},{"type":29,"tag":127,"props":13821,"children":13822},{"class":677,"line":1329},[13823,13827],{"type":29,"tag":127,"props":13824,"children":13825},{"style":682},[13826],{"type":56,"value":1529},{"type":29,"tag":127,"props":13828,"children":13829},{"style":688},[13830],{"type":56,"value":691},{"type":29,"tag":127,"props":13832,"children":13833},{"class":677,"line":1342},[13834,13838],{"type":29,"tag":127,"props":13835,"children":13836},{"style":688},[13837],{"type":56,"value":746},{"type":29,"tag":127,"props":13839,"children":13840},{"style":720},[13841],{"type":56,"value":1546},{"type":29,"tag":127,"props":13843,"children":13844},{"class":677,"line":118},[13845,13849],{"type":29,"tag":127,"props":13846,"children":13847},{"style":688},[13848],{"type":56,"value":746},{"type":29,"tag":127,"props":13850,"children":13851},{"style":720},[13852],{"type":56,"value":12486},{"type":29,"tag":127,"props":13854,"children":13855},{"class":677,"line":1367},[13856,13860],{"type":29,"tag":127,"props":13857,"children":13858},{"style":682},[13859],{"type":56,"value":1335},{"type":29,"tag":127,"props":13861,"children":13862},{"style":688},[13863],{"type":56,"value":691},{"type":29,"tag":127,"props":13865,"children":13866},{"class":677,"line":1380},[13867,13871],{"type":29,"tag":127,"props":13868,"children":13869},{"style":688},[13870],{"type":56,"value":746},{"type":29,"tag":127,"props":13872,"children":13873},{"style":720},[13874],{"type":56,"value":12509},{"type":29,"tag":127,"props":13876,"children":13877},{"class":677,"line":1393},[13878],{"type":29,"tag":127,"props":13879,"children":13880},{"emptyLinePlaceholder":500},[13881],{"type":56,"value":1399},{"type":29,"tag":127,"props":13883,"children":13884},{"class":677,"line":1402},[13885,13889],{"type":29,"tag":127,"props":13886,"children":13887},{"style":688},[13888],{"type":56,"value":746},{"type":29,"tag":127,"props":13890,"children":13891},{"style":720},[13892],{"type":56,"value":1412},{"type":29,"tag":127,"props":13894,"children":13895},{"class":677,"line":1415},[13896,13900],{"type":29,"tag":127,"props":13897,"children":13898},{"style":688},[13899],{"type":56,"value":746},{"type":29,"tag":127,"props":13901,"children":13902},{"style":720},[13903],{"type":56,"value":1447},{"type":29,"tag":127,"props":13905,"children":13906},{"class":677,"line":1428},[13907,13911],{"type":29,"tag":127,"props":13908,"children":13909},{"style":688},[13910],{"type":56,"value":746},{"type":29,"tag":127,"props":13912,"children":13913},{"style":720},[13914],{"type":56,"value":1460},{"type":29,"tag":127,"props":13916,"children":13917},{"class":677,"line":1437},[13918],{"type":29,"tag":127,"props":13919,"children":13920},{"emptyLinePlaceholder":500},[13921],{"type":56,"value":1399},{"type":29,"tag":127,"props":13923,"children":13924},{"class":677,"line":1450},[13925,13929],{"type":29,"tag":127,"props":13926,"children":13927},{"style":688},[13928],{"type":56,"value":746},{"type":29,"tag":127,"props":13930,"children":13931},{"style":720},[13932],{"type":56,"value":1425},{"type":29,"tag":127,"props":13934,"children":13935},{"class":677,"line":1463},[13936,13940],{"type":29,"tag":127,"props":13937,"children":13938},{"style":688},[13939],{"type":56,"value":746},{"type":29,"tag":127,"props":13941,"children":13942},{"style":720},[13943],{"type":56,"value":1473},{"type":29,"tag":127,"props":13945,"children":13946},{"class":677,"line":1476},[13947],{"type":29,"tag":127,"props":13948,"children":13949},{"style":688},[13950],{"type":56,"value":12978},{"type":29,"tag":127,"props":13952,"children":13954},{"class":13953,"line":1484},[677,740],[13955,13959],{"type":29,"tag":127,"props":13956,"children":13957},{"style":688},[13958],{"type":56,"value":746},{"type":29,"tag":127,"props":13960,"children":13961},{"style":720},[13962],{"type":56,"value":13963},"--entrypoints.container-registry.address=:5050\n",{"type":29,"tag":127,"props":13965,"children":13967},{"class":13966,"line":1497},[677,740],[13968,13972],{"type":29,"tag":127,"props":13969,"children":13970},{"style":688},[13971],{"type":56,"value":746},{"type":29,"tag":127,"props":13973,"children":13974},{"style":720},[13975],{"type":56,"value":13976},"--entrypoints.container-registry.http.tls.certresolver=letsencrypt\n",{"type":29,"tag":127,"props":13978,"children":13979},{"class":677,"line":1510},[13980],{"type":29,"tag":127,"props":13981,"children":13982},{"emptyLinePlaceholder":500},[13983],{"type":56,"value":1399},{"type":29,"tag":127,"props":13985,"children":13986},{"class":677,"line":1523},[13987,13991],{"type":29,"tag":127,"props":13988,"children":13989},{"style":688},[13990],{"type":56,"value":746},{"type":29,"tag":127,"props":13992,"children":13993},{"style":720},[13994],{"type":56,"value":12597},{"type":29,"tag":127,"props":13996,"children":13997},{"class":677,"line":1536},[13998,14002],{"type":29,"tag":127,"props":13999,"children":14000},{"style":688},[14001],{"type":56,"value":746},{"type":29,"tag":127,"props":14003,"children":14004},{"style":720},[14005],{"type":56,"value":12609},{"type":29,"tag":127,"props":14007,"children":14008},{"class":677,"line":1549},[14009],{"type":29,"tag":127,"props":14010,"children":14011},{"emptyLinePlaceholder":500},[14012],{"type":56,"value":1399},{"type":29,"tag":127,"props":14014,"children":14015},{"class":677,"line":2411},[14016,14020],{"type":29,"tag":127,"props":14017,"children":14018},{"style":688},[14019],{"type":56,"value":746},{"type":29,"tag":127,"props":14021,"children":14022},{"style":720},[14023],{"type":56,"value":12628},{"type":29,"tag":127,"props":14025,"children":14026},{"class":677,"line":2419},[14027,14031],{"type":29,"tag":127,"props":14028,"children":14029},{"style":688},[14030],{"type":56,"value":746},{"type":29,"tag":127,"props":14032,"children":14033},{"style":720},[14034],{"type":56,"value":1377},{"type":29,"tag":127,"props":14036,"children":14037},{"class":677,"line":2439},[14038,14042],{"type":29,"tag":127,"props":14039,"children":14040},{"style":688},[14041],{"type":56,"value":746},{"type":29,"tag":127,"props":14043,"children":14044},{"style":720},[14045],{"type":56,"value":1352},{"type":29,"tag":127,"props":14047,"children":14048},{"class":677,"line":2460},[14049,14053],{"type":29,"tag":127,"props":14050,"children":14051},{"style":688},[14052],{"type":56,"value":746},{"type":29,"tag":127,"props":14054,"children":14055},{"style":720},[14056],{"type":56,"value":1390},{"type":29,"tag":48,"props":14058,"children":14059},{},[14060],{"type":56,"value":12666},{"type":29,"tag":810,"props":14062,"children":14063},{},[14064,14069],{"type":29,"tag":814,"props":14065,"children":14066},{},[14067],{"type":56,"value":14068},"einen neuen Einstiegspunkt für die Container-Registry hinzufügen",{"type":29,"tag":814,"props":14070,"children":14071},{},[14072],{"type":56,"value":14073},"die TLS-Konfiguration auf alle Routen in diesem Einstiegspunkt anwenden",{"type":29,"tag":1670,"props":14075,"children":14076},{},[],{"type":29,"tag":13250,"props":14078,"children":14080},{"id":14079},"aktualisierung-der-gitlab-konfiguration-1",[14081],{"type":56,"value":13255},{"type":29,"tag":659,"props":14083,"children":14086},{"className":669,"code":14084,"filename":11659,"highlights":14085,"language":508,"meta":7,"style":7},"services:\n  gitlab:\n    image: gitlab/gitlab-ce:\u003Cversion>-ce.0\n    container_name: gitlab\n    labels:\n      - \"traefik.enable=true\"\n      - \"traefik.http.routers.gitlab.rule=Host(`\u003Cgitlab.example.com>`)\"\n      - \"traefik.http.routers.gitlab.entrypoints=web,websecure\"\n      - \"traefik.http.routers.gitlab.service=gitlab\"\n      - \"traefik.http.services.gitlab.loadbalancer.server.port=80\"\n      - \"traefik.http.routers.container-registry.rule=Host(`gitlab.example.com`)\"\n      - \"traefik.http.routers.container-registry.entrypoints=container-registry\"\n      - \"traefik.http.routers.container-registry.service=container-registry\"\n      - \"traefik.http.services.container-registry.loadbalancer.server.port=5000\"\n    restart: always\n    hostname: 'gitlab.example.com'\n    environment:\n      GITLAB_OMNIBUS_CONFIG: |\n        # Add any other gitlab.rb configuration here, each on its own line\n        external_url '\u003Chttps://gitlab.example.com>'\n\n        letsencrypt['enable'] = false\n\n        nginx['listen_port'] = 80\n        nginx['listen_https'] = false\n        nginx['proxy_set_headers'] = {\n          \"X-Forwarded-Proto\" => \"https\",\n          \"X-Forwarded-Ssl\" => \"on\"\n        }\n\n        gitlab_rails['gitlab_shell_ssh_port'] = 2424\n\n        registry_external_url '\u003Chttps://gitlab.example.com:5050>'\n        registry_nginx['enable'] = false\n    ports:\n      - '2424:22'\n    volumes:\n      - '$GITLAB_HOME/config:/etc/gitlab'\n      - '$GITLAB_HOME/logs:/var/log/gitlab'\n      - '$GITLAB_HOME/data:/var/opt/gitlab'\n    shm_size: '256m'\n",[667,1342,118,1367,1380,2472],[14087],{"type":29,"tag":672,"props":14088,"children":14089},{"__ignoreMap":7},[14090,14101,14112,14127,14142,14153,14164,14175,14188,14199,14210,14223,14236,14249,14261,14276,14291,14302,14317,14324,14331,14338,14345,14352,14359,14366,14373,14380,14387,14394,14401,14408,14415,14424,14431,14442,14453,14464,14475,14486,14497],{"type":29,"tag":127,"props":14091,"children":14092},{"class":677,"line":678},[14093,14097],{"type":29,"tag":127,"props":14094,"children":14095},{"style":682},[14096],{"type":56,"value":685},{"type":29,"tag":127,"props":14098,"children":14099},{"style":688},[14100],{"type":56,"value":691},{"type":29,"tag":127,"props":14102,"children":14103},{"class":677,"line":342},[14104,14108],{"type":29,"tag":127,"props":14105,"children":14106},{"style":682},[14107],{"type":56,"value":11682},{"type":29,"tag":127,"props":14109,"children":14110},{"style":688},[14111],{"type":56,"value":691},{"type":29,"tag":127,"props":14113,"children":14114},{"class":677,"line":706},[14115,14119,14123],{"type":29,"tag":127,"props":14116,"children":14117},{"style":682},[14118],{"type":56,"value":712},{"type":29,"tag":127,"props":14120,"children":14121},{"style":688},[14122],{"type":56,"value":717},{"type":29,"tag":127,"props":14124,"children":14125},{"style":720},[14126],{"type":56,"value":12820},{"type":29,"tag":127,"props":14128,"children":14129},{"class":677,"line":726},[14130,14134,14138],{"type":29,"tag":127,"props":14131,"children":14132},{"style":682},[14133],{"type":56,"value":1267},{"type":29,"tag":127,"props":14135,"children":14136},{"style":688},[14137],{"type":56,"value":717},{"type":29,"tag":127,"props":14139,"children":14140},{"style":720},[14141],{"type":56,"value":11718},{"type":29,"tag":127,"props":14143,"children":14144},{"class":677,"line":664},[14145,14149],{"type":29,"tag":127,"props":14146,"children":14147},{"style":682},[14148],{"type":56,"value":732},{"type":29,"tag":127,"props":14150,"children":14151},{"style":688},[14152],{"type":56,"value":691},{"type":29,"tag":127,"props":14154,"children":14155},{"class":677,"line":665},[14156,14160],{"type":29,"tag":127,"props":14157,"children":14158},{"style":688},[14159],{"type":56,"value":746},{"type":29,"tag":127,"props":14161,"children":14162},{"style":720},[14163],{"type":56,"value":751},{"type":29,"tag":127,"props":14165,"children":14166},{"class":677,"line":666},[14167,14171],{"type":29,"tag":127,"props":14168,"children":14169},{"style":688},[14170],{"type":56,"value":746},{"type":29,"tag":127,"props":14172,"children":14173},{"style":720},[14174],{"type":56,"value":12872},{"type":29,"tag":127,"props":14176,"children":14178},{"class":14177,"line":667},[677,740],[14179,14183],{"type":29,"tag":127,"props":14180,"children":14181},{"style":688},[14182],{"type":56,"value":746},{"type":29,"tag":127,"props":14184,"children":14185},{"style":720},[14186],{"type":56,"value":14187},"\"traefik.http.routers.gitlab.entrypoints=web,websecure\"\n",{"type":29,"tag":127,"props":14189,"children":14190},{"class":677,"line":668},[14191,14195],{"type":29,"tag":127,"props":14192,"children":14193},{"style":688},[14194],{"type":56,"value":746},{"type":29,"tag":127,"props":14196,"children":14197},{"style":720},[14198],{"type":56,"value":12885},{"type":29,"tag":127,"props":14200,"children":14201},{"class":677,"line":1329},[14202,14206],{"type":29,"tag":127,"props":14203,"children":14204},{"style":688},[14205],{"type":56,"value":746},{"type":29,"tag":127,"props":14207,"children":14208},{"style":720},[14209],{"type":56,"value":12898},{"type":29,"tag":127,"props":14211,"children":14213},{"class":14212,"line":1342},[677,740],[14214,14218],{"type":29,"tag":127,"props":14215,"children":14216},{"style":688},[14217],{"type":56,"value":746},{"type":29,"tag":127,"props":14219,"children":14220},{"style":720},[14221],{"type":56,"value":14222},"\"traefik.http.routers.container-registry.rule=Host(`gitlab.example.com`)\"\n",{"type":29,"tag":127,"props":14224,"children":14226},{"class":14225,"line":118},[677,740],[14227,14231],{"type":29,"tag":127,"props":14228,"children":14229},{"style":688},[14230],{"type":56,"value":746},{"type":29,"tag":127,"props":14232,"children":14233},{"style":720},[14234],{"type":56,"value":14235},"\"traefik.http.routers.container-registry.entrypoints=container-registry\"\n",{"type":29,"tag":127,"props":14237,"children":14239},{"class":14238,"line":1367},[677,740],[14240,14244],{"type":29,"tag":127,"props":14241,"children":14242},{"style":688},[14243],{"type":56,"value":746},{"type":29,"tag":127,"props":14245,"children":14246},{"style":720},[14247],{"type":56,"value":14248},"\"traefik.http.routers.container-registry.service=container-registry\"\n",{"type":29,"tag":127,"props":14250,"children":14252},{"class":14251,"line":1380},[677,740],[14253,14257],{"type":29,"tag":127,"props":14254,"children":14255},{"style":688},[14256],{"type":56,"value":746},{"type":29,"tag":127,"props":14258,"children":14259},{"style":720},[14260],{"type":56,"value":13396},{"type":29,"tag":127,"props":14262,"children":14263},{"class":677,"line":1393},[14264,14268,14272],{"type":29,"tag":127,"props":14265,"children":14266},{"style":682},[14267],{"type":56,"value":1284},{"type":29,"tag":127,"props":14269,"children":14270},{"style":688},[14271],{"type":56,"value":717},{"type":29,"tag":127,"props":14273,"children":14274},{"style":720},[14275],{"type":56,"value":1293},{"type":29,"tag":127,"props":14277,"children":14278},{"class":677,"line":1402},[14279,14283,14287],{"type":29,"tag":127,"props":14280,"children":14281},{"style":682},[14282],{"type":56,"value":11741},{"type":29,"tag":127,"props":14284,"children":14285},{"style":688},[14286],{"type":56,"value":717},{"type":29,"tag":127,"props":14288,"children":14289},{"style":720},[14290],{"type":56,"value":12929},{"type":29,"tag":127,"props":14292,"children":14293},{"class":677,"line":1415},[14294,14298],{"type":29,"tag":127,"props":14295,"children":14296},{"style":682},[14297],{"type":56,"value":10054},{"type":29,"tag":127,"props":14299,"children":14300},{"style":688},[14301],{"type":56,"value":691},{"type":29,"tag":127,"props":14303,"children":14304},{"class":677,"line":1428},[14305,14309,14313],{"type":29,"tag":127,"props":14306,"children":14307},{"style":682},[14308],{"type":56,"value":11769},{"type":29,"tag":127,"props":14310,"children":14311},{"style":688},[14312],{"type":56,"value":717},{"type":29,"tag":127,"props":14314,"children":14315},{"style":4942},[14316],{"type":56,"value":11778},{"type":29,"tag":127,"props":14318,"children":14319},{"class":677,"line":1437},[14320],{"type":29,"tag":127,"props":14321,"children":14322},{"style":720},[14323],{"type":56,"value":11786},{"type":29,"tag":127,"props":14325,"children":14326},{"class":677,"line":1450},[14327],{"type":29,"tag":127,"props":14328,"children":14329},{"style":720},[14330],{"type":56,"value":12970},{"type":29,"tag":127,"props":14332,"children":14333},{"class":677,"line":1463},[14334],{"type":29,"tag":127,"props":14335,"children":14336},{"emptyLinePlaceholder":500},[14337],{"type":56,"value":1399},{"type":29,"tag":127,"props":14339,"children":14340},{"class":677,"line":1476},[14341],{"type":29,"tag":127,"props":14342,"children":14343},{"style":720},[14344],{"type":56,"value":12987},{"type":29,"tag":127,"props":14346,"children":14347},{"class":677,"line":1484},[14348],{"type":29,"tag":127,"props":14349,"children":14350},{"emptyLinePlaceholder":500},[14351],{"type":56,"value":1399},{"type":29,"tag":127,"props":14353,"children":14354},{"class":677,"line":1497},[14355],{"type":29,"tag":127,"props":14356,"children":14357},{"style":720},[14358],{"type":56,"value":13003},{"type":29,"tag":127,"props":14360,"children":14361},{"class":677,"line":1510},[14362],{"type":29,"tag":127,"props":14363,"children":14364},{"style":720},[14365],{"type":56,"value":13012},{"type":29,"tag":127,"props":14367,"children":14368},{"class":677,"line":1523},[14369],{"type":29,"tag":127,"props":14370,"children":14371},{"style":720},[14372],{"type":56,"value":13021},{"type":29,"tag":127,"props":14374,"children":14375},{"class":677,"line":1536},[14376],{"type":29,"tag":127,"props":14377,"children":14378},{"style":720},[14379],{"type":56,"value":13030},{"type":29,"tag":127,"props":14381,"children":14382},{"class":677,"line":1549},[14383],{"type":29,"tag":127,"props":14384,"children":14385},{"style":720},[14386],{"type":56,"value":13039},{"type":29,"tag":127,"props":14388,"children":14389},{"class":677,"line":2411},[14390],{"type":29,"tag":127,"props":14391,"children":14392},{"style":720},[14393],{"type":56,"value":3541},{"type":29,"tag":127,"props":14395,"children":14396},{"class":677,"line":2419},[14397],{"type":29,"tag":127,"props":14398,"children":14399},{"emptyLinePlaceholder":500},[14400],{"type":56,"value":1399},{"type":29,"tag":127,"props":14402,"children":14403},{"class":677,"line":2439},[14404],{"type":29,"tag":127,"props":14405,"children":14406},{"style":720},[14407],{"type":56,"value":13063},{"type":29,"tag":127,"props":14409,"children":14410},{"class":677,"line":2460},[14411],{"type":29,"tag":127,"props":14412,"children":14413},{"emptyLinePlaceholder":500},[14414],{"type":56,"value":1399},{"type":29,"tag":127,"props":14416,"children":14418},{"class":14417,"line":2472},[677,740],[14419],{"type":29,"tag":127,"props":14420,"children":14421},{"style":720},[14422],{"type":56,"value":14423},"        registry_external_url '\u003Chttps://gitlab.example.com:5050>'\n",{"type":29,"tag":127,"props":14425,"children":14426},{"class":677,"line":2488},[14427],{"type":29,"tag":127,"props":14428,"children":14429},{"style":720},[14430],{"type":56,"value":13568},{"type":29,"tag":127,"props":14432,"children":14433},{"class":677,"line":2496},[14434,14438],{"type":29,"tag":127,"props":14435,"children":14436},{"style":682},[14437],{"type":56,"value":11802},{"type":29,"tag":127,"props":14439,"children":14440},{"style":688},[14441],{"type":56,"value":691},{"type":29,"tag":127,"props":14443,"children":14444},{"class":677,"line":1970},[14445,14449],{"type":29,"tag":127,"props":14446,"children":14447},{"style":688},[14448],{"type":56,"value":746},{"type":29,"tag":127,"props":14450,"children":14451},{"style":720},[14452],{"type":56,"value":13087},{"type":29,"tag":127,"props":14454,"children":14455},{"class":677,"line":1971},[14456,14460],{"type":29,"tag":127,"props":14457,"children":14458},{"style":682},[14459],{"type":56,"value":1529},{"type":29,"tag":127,"props":14461,"children":14462},{"style":688},[14463],{"type":56,"value":691},{"type":29,"tag":127,"props":14465,"children":14466},{"class":677,"line":1972},[14467,14471],{"type":29,"tag":127,"props":14468,"children":14469},{"style":688},[14470],{"type":56,"value":746},{"type":29,"tag":127,"props":14472,"children":14473},{"style":720},[14474],{"type":56,"value":11865},{"type":29,"tag":127,"props":14476,"children":14477},{"class":677,"line":1973},[14478,14482],{"type":29,"tag":127,"props":14479,"children":14480},{"style":688},[14481],{"type":56,"value":746},{"type":29,"tag":127,"props":14483,"children":14484},{"style":720},[14485],{"type":56,"value":11877},{"type":29,"tag":127,"props":14487,"children":14488},{"class":677,"line":2559},[14489,14493],{"type":29,"tag":127,"props":14490,"children":14491},{"style":688},[14492],{"type":56,"value":746},{"type":29,"tag":127,"props":14494,"children":14495},{"style":720},[14496],{"type":56,"value":11889},{"type":29,"tag":127,"props":14498,"children":14499},{"class":677,"line":2568},[14500,14504,14508],{"type":29,"tag":127,"props":14501,"children":14502},{"style":682},[14503],{"type":56,"value":11897},{"type":29,"tag":127,"props":14505,"children":14506},{"style":688},[14507],{"type":56,"value":717},{"type":29,"tag":127,"props":14509,"children":14510},{"style":720},[14511],{"type":56,"value":11906},{"type":29,"tag":48,"props":14513,"children":14514},{},[14515],{"type":56,"value":12666},{"type":29,"tag":810,"props":14517,"children":14518},{},[14519,14523,14527],{"type":29,"tag":814,"props":14520,"children":14521},{},[14522],{"type":56,"value":13661},{"type":29,"tag":814,"props":14524,"children":14525},{},[14526],{"type":56,"value":13666},{"type":29,"tag":814,"props":14528,"children":14529},{},[14530],{"type":56,"value":14531},"Traefik anweisen, den gesamten Verkehr von Port 5050 an Port 5000 des Containers weiterzuleiten",{"type":29,"tag":1838,"props":14533,"children":14534},{},[14535],{"type":56,"value":1842},{"title":7,"searchDepth":342,"depth":342,"links":14537},[14538,14539],{"id":11642,"depth":342,"text":11645},{"id":11914,"depth":342,"text":11917,"children":14540},[14541,14542,14543],{"id":12034,"depth":706,"text":12037},{"id":12284,"depth":706,"text":12287},{"id":13206,"depth":706,"text":13209},{"_path":598,"_dir":515,"_draft":6,"_partial":6,"_locale":7,"title":599,"description":600,"author":601,"image":519,"releaseDate":602,"blogCategories":14545,"articleTags":14546,"tags":14547,"body":14548,"_type":346,"_id":606,"_source":348,"_file":607,"_stem":608,"_extension":351},[579],[523],[24],{"type":26,"children":14549,"toc":15803},[14550,14556,14575,14581,14627,14691,14703,14709,14719,14760,14769,14801,14841,14850,14883,14902,14956,14962,14971,15002,15047,15072,15097,15103,15112,15147,15268,15271,15275,15319,15325,15334,15387,15418,15442,15473,15492,15498,15507,15539,15558,15594,15613,15639,15651,15657,15666,15692,15747,15753,15781,15793],{"type":29,"tag":61,"props":14551,"children":14555},{"alt":14552,"aspect-ratio":14553,"height":1862,"object-fit":1863,"src":14554},"Eine Person hällt einen Sticker mit dem Schriftzug \"Dev-ops\" in der Hand","2.07","/blog/person_holding_devops_sticker.jpg",[],{"type":29,"tag":127,"props":14557,"children":14561},{"className":14558},[14559,14560],"text-right","text-caption",[14562],{"type":29,"tag":48,"props":14563,"children":14564},{},[14565],{"type":29,"tag":14566,"props":14567,"children":14568},"em",{},[14569],{"type":29,"tag":645,"props":14570,"children":14572},{"href":14571},"https://www.pexels.com/photo/person-holding-a-sticker-11035393/",[14573],{"type":56,"value":14574},"Photo by RealToughCandy.com",{"type":29,"tag":90,"props":14576,"children":14578},{"id":14577},"warum-die-entwicklung-einer-web-applikation-nur-der-anfang-ist",[14579],{"type":56,"value":14580},"Warum die Entwicklung einer (Web-)Applikation nur der Anfang ist",{"type":29,"tag":48,"props":14582,"children":14583},{},[14584,14586,14591,14593,14598,14600,14604,14606,14611,14613,14618,14620,14625],{"type":56,"value":14585},"Web-Anwendungen werden meistens in einer ",{"type":29,"tag":14566,"props":14587,"children":14588},{},[14589],{"type":56,"value":14590},"Dev",{"type":56,"value":14592},"-Umgebung (Development-Umgebung) entwickelt und getestet – doch der\neigentliche Härtetest kommt in der Praxis auf den ",{"type":29,"tag":14566,"props":14594,"children":14595},{},[14596],{"type":56,"value":14597},"Prod",{"type":56,"value":14599},"-Systemen (Produktivumgebung). ",{"type":29,"tag":52,"props":14601,"children":14602},{},[14603],{"type":56,"value":523},{"type":56,"value":14605}," (kurz für\n",{"type":29,"tag":14566,"props":14607,"children":14608},{},[14609],{"type":56,"value":14610},"Development Operations",{"type":56,"value":14612},", also die enge Verzahnung von Entwicklung und IT-Betrieb) spielt hier eine Schlüsselrolle.\nInsbesondere bei Web-Anwendungen auf ",{"type":29,"tag":52,"props":14614,"children":14615},{},[14616],{"type":56,"value":14617},"Linux-Servern",{"type":56,"value":14619}," mit komplexer ",{"type":29,"tag":52,"props":14621,"children":14622},{},[14623],{"type":56,"value":14624},"Netzwerkinfrastruktur",{"type":56,"value":14626}," stellt sich oft erst\n„live“ heraus, wie stabil und performant eine Anwendung wirklich läuft. In diesem Beitrag werfen wir einen Blick auf\ngängige Thesen rund um DevOps im Web-Umfeld und prüfen, was dran ist. Dabei betrachten wir vor allem Aspekte, die für\nKunden aus dem Mittelstand und Partnerfirmen einer Software-Agentur relevant sind.",{"type":29,"tag":48,"props":14628,"children":14629},{},[14630,14632,14637,14639,14644,14645,14650,14652,14661,14663,14672,14674,14682,14684,14689],{"type":56,"value":14631},"Wir beleuchten, warum Entwicklungsumgebungen an ihre Grenzen stoßen, wieso echte Lasttests und ",{"type":29,"tag":14566,"props":14633,"children":14634},{},[14635],{"type":56,"value":14636},"Edge Cases",{"type":56,"value":14638}," (Randfälle)\nschwer simulierbar sind und weshalb die Arbeit nach dem Launch (Stichwort ",{"type":29,"tag":14566,"props":14640,"children":14641},{},[14642],{"type":56,"value":14643},"Monitoring",{"type":56,"value":9692},{"type":29,"tag":14566,"props":14646,"children":14647},{},[14648],{"type":56,"value":14649},"Continuous Improvement",{"type":56,"value":14651},")\ngerade erst richtig beginnt. Außerdem gehen wir darauf ein, welche Tools – von ",{"type":29,"tag":645,"props":14653,"children":14655},{"href":14654},"https://sentry.io/",[14656],{"type":29,"tag":52,"props":14657,"children":14658},{},[14659],{"type":56,"value":14660},"Sentry",{"type":56,"value":14662}," über ",{"type":29,"tag":645,"props":14664,"children":14666},{"href":14665},"https://grafana.com/",[14667],{"type":29,"tag":52,"props":14668,"children":14669},{},[14670],{"type":56,"value":14671},"Grafana",{"type":56,"value":14673}," bis\n",{"type":29,"tag":645,"props":14675,"children":14677},{"href":14676},"https://www.zabbix.com/",[14678],{"type":29,"tag":52,"props":14679,"children":14680},{},[14681],{"type":56,"value":385},{"type":56,"value":14683}," – im Alltag unverzichtbar sind und wie ",{"type":29,"tag":52,"props":14685,"children":14686},{},[14687],{"type":56,"value":14688},"CI/CD-Pipelines",{"type":56,"value":14690}," auch weniger erfahrenen Entwicklern helfen,\ngefahrlos zu deployen.",{"type":29,"tag":127,"props":14692,"children":14694},{"className":14693},[14559],[14695],{"type":29,"tag":48,"props":14696,"children":14697},{},[14698],{"type":29,"tag":14566,"props":14699,"children":14700},{},[14701],{"type":56,"value":14702},"Lesedauer: ca. 20 Minuten",{"type":29,"tag":90,"props":14704,"children":14706},{"id":14705},"entwicklungsumgebung-vs-realität-begrenzte-leistung-und-unbekannte-randfälle",[14707],{"type":56,"value":14708},"Entwicklungsumgebung vs. Realität: Begrenzte Leistung und unbekannte Randfälle",{"type":29,"tag":48,"props":14710,"children":14711},{},[14712,14717],{"type":29,"tag":52,"props":14713,"children":14714},{},[14715],{"type":56,"value":14716},"These:",{"type":56,"value":14718}," Software-Projekte und Web-Anwendungen werden in Entwicklungsumgebungen gebaut, die in Leistung und Testdaten\nlimitiert sind.",{"type":29,"tag":48,"props":14720,"children":14721},{},[14722,14724,14729,14731,14736,14738,14743,14745,14750,14752,14758],{"type":56,"value":14723},"In der Entwicklungsphase läuft eine Web-Anwendung oft auf dem Laptop, einem Desktop-PC oder in einer isolierten\nTest-Umgebung der Entwickler. Diese ",{"type":29,"tag":52,"props":14725,"children":14726},{},[14727],{"type":56,"value":14728},"Dev-Umgebung",{"type":56,"value":14730}," ist typischerweise ",{"type":29,"tag":52,"props":14732,"children":14733},{},[14734],{"type":56,"value":14735},"weniger leistungsfähig",{"type":56,"value":14737}," als die späteren\nProduktionsserver und enthält nur einen Bruchteil echter Daten. Das ist zunächst normal – niemand hat eine vollständige\nKopie der Produktionsdatenbank auf seinem Laptop, und man will ja auch lokal schnell arbeiten können. Allerdings führt\ndiese Diskrepanz dazu, dass manche Probleme in der Dev-Umgebung gar nicht erst sichtbar werden. Ebenfalls kann sich bei\nperformance-Problemen schnell der Gedanke einschleichen, dass das Produktivsystem mit seiner überlegenen Leistung schon\nnicht so schwer damit zu kämpfen hat. Eine ",{"type":29,"tag":52,"props":14739,"children":14740},{},[14741],{"type":56,"value":14742},"staging",{"type":56,"value":14744},"- oder Test-Umgebung kann versuchen, die Produktionsumgebung\nnachzuahmen, ",{"type":29,"tag":52,"props":14746,"children":14747},{},[14748],{"type":56,"value":14749},"stößt aber an Grenzen",{"type":56,"value":14751},": Production environments haben Feinheiten, die in Staging nur schwer zu\nsimulieren sind – etwa das reale Nutzerverhalten, große Datenmengen oder komplexe System-Interaktionen\n",{"type":29,"tag":645,"props":14753,"children":14755},{"href":14754},"https://www.browserstack.com/guide/testing-in-production#:~:text=1.%20Real,only%20surface%20under%20specific%20conditions",[14756],{"type":56,"value":14757},"browserstack.com",{"type":56,"value":14759},"\n. Mit anderen Worten: In der Testumgebung läuft alles „schön sauber“, aber in der Realität kommen ganz andere Faktoren\nins Spiel.",{"type":29,"tag":48,"props":14761,"children":14762},{},[14763,14767],{"type":29,"tag":52,"props":14764,"children":14765},{},[14766],{"type":56,"value":14716},{"type":56,"value":14768}," Entwickler und Kunden haben oft nicht den vollständigen Überblick über reale Anwendungsfälle, Edge-Cases und\nLastspitzen.",{"type":29,"tag":48,"props":14770,"children":14771},{},[14772,14774,14779,14781,14786,14788,14792,14794,14799],{"type":56,"value":14773},"Entwicklungsteams und selbst die Kunden kennen zwar die ",{"type":29,"tag":14566,"props":14775,"children":14776},{},[14777],{"type":56,"value":14778},"Hauptanwendungsfälle",{"type":56,"value":14780}," ihrer Software, doch ",{"type":29,"tag":52,"props":14782,"children":14783},{},[14784],{"type":56,"value":14785},"reale Benutzer",{"type":56,"value":14787},"\ntreiben Anwendungen gerne an ihre Grenzen. Plötzlich nutzen sie Features in Kombinationen, an die niemand gedacht hat,\noder geben unerwartete Daten ein. Solche ",{"type":29,"tag":52,"props":14789,"children":14790},{},[14791],{"type":56,"value":14636},{"type":56,"value":14793}," (Rand- oder Grenzfälle) bleiben in der Spezifikation oft\nunentdeckt. Erst im Echtbetrieb tauchen dann Fehler auf, die vorher niemand vorausgesehen hat. Ein Grund dafür ist,\ndass einige Bugs nur unter spezifischen Bedingungen auftreten, die man in Pre-Production-Tests nicht antizipiert.\nBeispielsweise könnte ein Nutzerprofil mit einem ",{"type":29,"tag":14566,"props":14795,"children":14796},{},[14797],{"type":56,"value":14798},"Emoji",{"type":56,"value":14800}," im Namen irgendwo in der Verarbeitung einen Fehler auslösen –\netwas, das im Testdatensatz nicht vorkam. Oder ein Kunde nutzt die Web-App auf einem älteren Browser und stößt auf\nDarstellungsprobleme. Solche Fälle zeigen sich oft erst, wenn die Anwendung „in freier Wildbahn“ verwendet wird.",{"type":29,"tag":48,"props":14802,"children":14803},{},[14804,14806,14811,14813,14818,14820,14825,14827,14832,14834,14839],{"type":56,"value":14805},"Zudem kennen Kunden zwar ihre Geschäftsprozesse, aber ",{"type":29,"tag":52,"props":14807,"children":14808},{},[14809],{"type":56,"value":14810},"Lastspitzen",{"type":56,"value":14812}," durch Marketing-Aktionen oder völlig atypische\nNutzungszeiten (z.B. am Wochenende um 3 Uhr nachts) werden leicht unterschätzt. Die ",{"type":29,"tag":52,"props":14814,"children":14815},{},[14816],{"type":56,"value":14817},"kritische Perspektive",{"type":56,"value":14819}," hier:\nModerne Ansätze versuchen diese Lücken zu schließen und propagieren, dass Entwicklungs- und Produktionsumgebung so\nähnlich wie möglich sein sollen (",{"type":29,"tag":14566,"props":14821,"children":14822},{},[14823],{"type":56,"value":14824},"dev/prod parity",{"type":56,"value":14826},"), um spätere Überraschungen zu minimieren.\n",{"type":29,"tag":52,"props":14828,"children":14829},{},[14830],{"type":56,"value":14831},"Containerisierung",{"type":56,"value":14833}," (z.B. mit Docker) erlaubt es, lokal eine Umgebung zu schaffen, die zumindest in den\nAbhängigkeiten und Voraussetzungen der Software-Faktoren der Produktionsumgebung sehr nahekommt. Dennoch bleibt es\nillusorisch, wirklich ",{"type":29,"tag":52,"props":14835,"children":14836},{},[14837],{"type":56,"value":14838},"alle",{"type":56,"value":14840}," realen Bedingungen vorwegzunehmen.",{"type":29,"tag":48,"props":14842,"children":14843},{},[14844,14848],{"type":29,"tag":52,"props":14845,"children":14846},{},[14847],{"type":56,"value":14716},{"type":56,"value":14849}," Verhalten unter Dauerlast, externen Crawlern, Penetration-Tests oder Spam-Bots sind schwer simulierbar.",{"type":29,"tag":48,"props":14851,"children":14852},{},[14853,14855,14860,14862,14867,14869,14874,14876,14881],{"type":56,"value":14854},"Performance-Tests gehören zwar zum guten Ton, aber ",{"type":29,"tag":52,"props":14856,"children":14857},{},[14858],{"type":56,"value":14859},"dauerhafte Last 24/7",{"type":56,"value":14861}," über Wochen hinweg lässt sich „im Labor“\nkaum vollständig nachstellen. Viele Unternehmen führen vor einem Launch Stresstests durch – doch diese laufen oft nur\nwenige Stunden oder Tage. Wie sich die Anwendung über Monate verhält (Memory Leaks? Datenbank wächst unvorhergesehen?\nLogs füllen die Festplatte?) bleibt offen. Auch ",{"type":29,"tag":52,"props":14863,"children":14864},{},[14865],{"type":56,"value":14866},"böswillige Zugriffe",{"type":56,"value":14868}," sind ein Thema. Externe ",{"type":29,"tag":52,"props":14870,"children":14871},{},[14872],{"type":56,"value":14873},"Crawler",{"type":56,"value":14875}," (z.B. von\nGoogle, Bing, oder sonstigen) könnten massenhaft Seiten aufrufen oder ",{"type":29,"tag":52,"props":14877,"children":14878},{},[14879],{"type":56,"value":14880},"Spam-Bots",{"type":56,"value":14882}," atypische Eingaben und Aufrufe\nverursachen. Ein Dauerbeschuss durch ein Penetration-Testing-Tool oder gar eine echte Angriffssimulation (Stichwort\nDDoS) ist nur begrenzt machbar, ohne die echten Systeme evtl. zu gefährden oder für den Tagesbetrieb unbrauchbar zu\nmachen.",{"type":29,"tag":48,"props":14884,"children":14885},{},[14886,14888,14893,14895,14900],{"type":56,"value":14887},"Die Community der Entwickler und Dev-Ops ist sich hier einig: Es ist ",{"type":29,"tag":52,"props":14889,"children":14890},{},[14891],{"type":56,"value":14892},"unheimlich schwierig, Produktionslast wirklich zu\nsimulieren",{"type":56,"value":14894},". Selbst mit Testumgebungen, die der Prod-Umgebung ähneln, können unvorhergesehene Effekte auftreten. Ein\ninteressanter Ansatz ist dabei beinahe kontraintuitiv: Manchmal nutzt man ",{"type":29,"tag":52,"props":14896,"children":14897},{},[14898],{"type":56,"value":14899},"absichtlich unterdimensionierte\nTestumgebungen",{"type":56,"value":14901},", um Schwachstellen zu entdecken. In dem erwähnten Bericht führte eine kleine Test-Datenbank dazu, dass\nein wachsendes Log schneller die Platte füllte – ein Problem, das in einer großen Umgebung erst viel später aufgefallen\nwäre.",{"type":29,"tag":48,"props":14903,"children":14904},{},[14905,14906,14911,14913,14918,14920,14925,14927,14932,14934,14942,14943,14948,14954],{"type":56,"value":6227},{"type":29,"tag":52,"props":14907,"children":14908},{},[14909],{"type":56,"value":14910},"überwiegende Meinung",{"type":56,"value":14912}," in der Tech-Community ist jedoch, dass ",{"type":29,"tag":52,"props":14914,"children":14915},{},[14916],{"type":56,"value":14917},"nichts an echte Produktions-Tests herankommt",{"type":56,"value":14919},".\nGroße Player wie Netflix propagieren sogar ",{"type":29,"tag":14566,"props":14921,"children":14922},{},[14923],{"type":56,"value":14924},"Chaos Engineering",{"type":56,"value":14926},", bei dem in der laufenden Produktion gezielt Störungen\nerzeugt werden, um die Systemrobustheit zu prüfen. Ein Experte fasst es so zusammen: ",{"type":29,"tag":14566,"props":14928,"children":14929},{},[14930],{"type":56,"value":14931},"„Um effektiv zu testen, muss das\nSystem in Produktion laufen. Schließlich kann man erst",{"type":56,"value":14933}," ",{"type":29,"tag":14566,"props":14935,"children":14936},{},[14937],{"type":29,"tag":52,"props":14938,"children":14939},{},[14940],{"type":56,"value":14941},"in Produktion",{"type":56,"value":14933},{"type":29,"tag":14566,"props":14944,"children":14945},{},[14946],{"type":56,"value":14947},"mit Faktoren wie Zustandsdaten, echten\nInputs und dem Verhalten externer Systeme arbeiten“",{"type":29,"tag":645,"props":14949,"children":14951},{"href":14950},"https://www.techtarget.com/searchsoftwarequality/tip/9-techniques-for-fixing-bugs-in-production#:~:text=want%20it%20to%2C%20and%20code,and%20how%20external%20systems%20behave",[14952],{"type":56,"value":14953},"techtarget.com",{"type":56,"value":14955},"\n. Das heißt, einige Fehler werden wir erst sehen, wenn wir live gehen. Wichtig ist dann, schnell reagieren zu können –\nund genau hier setzt DevOps an.",{"type":29,"tag":90,"props":14957,"children":14959},{"id":14958},"nach-dem-launch-ist-vor-dem-launch-analyse-und-optimierung-im-laufenden-betrieb",[14960],{"type":56,"value":14961},"Nach dem Launch ist vor dem Launch: Analyse und Optimierung im laufenden Betrieb",{"type":29,"tag":48,"props":14963,"children":14964},{},[14965,14969],{"type":29,"tag":52,"props":14966,"children":14967},{},[14968],{"type":56,"value":14716},{"type":56,"value":14970}," Weitergehende Analyse und Optimierung nach dem Launch ist essenziell.",{"type":29,"tag":48,"props":14972,"children":14973},{},[14974,14976,14980,14982,14987,14989,14994,15000],{"type":56,"value":14975},"Früher galt ein Software-Projekt mit dem Go-Live als abgeschlossen – heute weiß man, dass ",{"type":29,"tag":52,"props":14977,"children":14978},{},[14979],{"type":56,"value":14649},{"type":56,"value":14981},"\n(kontinuierliche Verbesserung) ein zentraler Bestandteil erfolgreicher Software ist. Gerade ",{"type":29,"tag":52,"props":14983,"children":14984},{},[14985],{"type":56,"value":14986},"nach dem Launch",{"type":56,"value":14988}," beginnt\ndie Phase, in der echte Nutzungsdaten ausgewertet, Engpässe erkannt und Optimierungen ausgerollt werden. So betont ein\nFachartikel: ",{"type":29,"tag":14566,"props":14990,"children":14991},{},[14992],{"type":56,"value":14993},"„Selbst mit gründlichem Pre-Launch-Testing können echte Anwender in der Praxis Performance-Probleme\naufdecken, die während der Entwicklung nicht offensichtlich waren. Post-Launch-Monitoring hilft, diese Probleme zu\nidentifizieren, bevor sie eine große Zahl von Nutzern beeinträchtigen“",{"type":29,"tag":645,"props":14995,"children":14997},{"href":14996},"https://www.topdevelopers.co/blog/post-launch-support-in-software-development/#:~:text=Even%20with%20rigorous%20pre,a%20large%20number%20of%20users",[14998],{"type":56,"value":14999},"topdevelopers.co",{"type":56,"value":15001},"\n. Anders ausgedrückt: Ein Launch ohne anschließende Überwachung ist wie die Jungfernfahrt ohne jemanden am Steuerrad.\nIn der Praxis unterschätzen gerade kleinere und mittelständische Unternehmen diesen Aufwand gern.",{"type":29,"tag":48,"props":15003,"children":15004},{},[15005,15010,15012,15017,15019,15024,15026,15031,15033,15038,15040,15045],{"type":29,"tag":52,"props":15006,"children":15007},{},[15008],{"type":56,"value":15009},"Kritische Perspektive:",{"type":56,"value":15011}," Manche denken, eine gute Software würde „out of the box“ laufen – doch das ist nach unserer\nErfahrung nur extrem selten der Fall. Es braucht Zeit und iterative Verbesserungen, um eine (Web-)Anwendung zu\n",{"type":29,"tag":52,"props":15013,"children":15014},{},[15015],{"type":56,"value":15016},"stabilisieren und zu beschleunigen",{"type":56,"value":15018},". Studien zeigen, dass ",{"type":29,"tag":14566,"props":15020,"children":15021},{},[15022],{"type":56,"value":15023},"kontinuierliche Pflege",{"type":56,"value":15025}," die ",{"type":29,"tag":52,"props":15027,"children":15028},{},[15029],{"type":56,"value":15030},"Nutzerzufriedenheit und\n-bindung",{"type":56,"value":15032}," deutlich erhöhten kann. Dazu gehören regelmäßige ",{"type":29,"tag":52,"props":15034,"children":15035},{},[15036],{"type":56,"value":15037},"Bugfixes",{"type":56,"value":15039},", Performance-Tuning (z.B. Caching-Strategien anpassen, Datenbank-Indices\noptimieren) und auch ",{"type":29,"tag":52,"props":15041,"children":15042},{},[15043],{"type":56,"value":15044},"Security-Patches",{"type":56,"value":15046},". Gerade Sicherheitslücken, die erst nach und nach publik werden, müssen sofort\ngeschlossen werden, um Schaden abzuwenden.",{"type":29,"tag":48,"props":15048,"children":15049},{},[15050,15052,15057,15059,15064,15066,15071],{"type":56,"value":15051},"Ein weiterer Aspekt ist die ",{"type":29,"tag":52,"props":15053,"children":15054},{},[15055],{"type":56,"value":15056},"Feedback-Schleife",{"type":56,"value":15058},": Durch echtes Nutzer-Feedback erfährt man, welche Features gut\nankommen und wo eventuell Usability-Probleme bestehen. Dieses Feedback fließt idealerweise direkt ins Backlog des\nEntwicklungsteams ein. Eine Kultur der ",{"type":29,"tag":14566,"props":15060,"children":15061},{},[15062],{"type":56,"value":15063},"Continuous Deployment",{"type":56,"value":15065}," stellt sicher, dass Verbesserungen zeitnah zu den Kunden\ngelangen und nicht bis zum nächsten großen „Release“ aufgeschoben werden. Moderne DevOps-Teams betrachten ihre Software\nals lebendiges Produkt: ",{"type":29,"tag":14566,"props":15067,"children":15068},{},[15069],{"type":56,"value":15070},"„Software endet nicht mit dem Launch – sie sollte als lebendiges Produkt gesehen werden.\nPost-Launch-Support ermöglicht kontinuierliche Verbesserung anhand von Nutzerfeedback und Performance-Daten“",{"type":56,"value":1651},{"type":29,"tag":48,"props":15073,"children":15074},{},[15075,15076,15081,15083,15088,15090,15095],{"type":56,"value":6227},{"type":29,"tag":52,"props":15077,"children":15078},{},[15079],{"type":56,"value":15080},"aktuelle Praxis",{"type":56,"value":15082}," in erfolgreichen Unternehmen zeigt klar: Nach dem Launch ist vor dem Launch. ",{"type":29,"tag":52,"props":15084,"children":15085},{},[15086],{"type":56,"value":15087},"Stagnation",{"type":56,"value":15089}," ist\ngefährlich – wer nach dem Go-Live nicht in ",{"type":29,"tag":52,"props":15091,"children":15092},{},[15093],{"type":56,"value":15094},"Monitoring, Fehlerbehebung und Optimierung",{"type":56,"value":15096}," investiert, riskiert Ausfälle,\nunzufriedene Nutzende und veraltete Software. Für Mittelständler bedeutet das konkret, genügend Ressourcen für die\nBetriebsphase einzuplanen oder einen kompetenten Partner zu haben, der das Monitoring und die Wartung übernimmt.",{"type":29,"tag":90,"props":15098,"children":15100},{"id":15099},"monitoring-und-logging-ohne-beobachtung-geht-es-nicht",[15101],{"type":56,"value":15102},"Monitoring und Logging: Ohne Beobachtung geht es nicht",{"type":29,"tag":48,"props":15104,"children":15105},{},[15106,15110],{"type":29,"tag":52,"props":15107,"children":15108},{},[15109],{"type":56,"value":14716},{"type":56,"value":15111}," Monitoring-Tools wie Sentry oder Grafana sind unerlässlich für Logging und Fehleranalyse.",{"type":29,"tag":48,"props":15113,"children":15114},{},[15115,15117,15122,15124,15131,15132,15139,15141,15144],{"type":56,"value":15116},"Um im laufenden Betrieb Probleme schnell zu erkennen, sind ",{"type":29,"tag":52,"props":15118,"children":15119},{},[15120],{"type":56,"value":15121},"Monitoring- und Logging-Tools",{"type":56,"value":15123}," absolut entscheidend. Zwei\nprominente Vertreter sind ",{"type":29,"tag":645,"props":15125,"children":15126},{"href":14654},[15127],{"type":29,"tag":52,"props":15128,"children":15129},{},[15130],{"type":56,"value":14660},{"type":56,"value":9692},{"type":29,"tag":645,"props":15133,"children":15134},{"href":14665},[15135],{"type":29,"tag":52,"props":15136,"children":15137},{},[15138],{"type":56,"value":14671},{"type":56,"value":15140}," (oft in Kombination mit Time-Series-Datenbanken wie Prometheus oder\nLog-Datenbanken wie ElasticSearch/Loki).\n",{"type":29,"tag":1670,"props":15142,"children":15143},{},[],{"type":29,"tag":1670,"props":15145,"children":15146},{},[],{"type":29,"tag":810,"props":15148,"children":15149},{},[15150,15201],{"type":29,"tag":814,"props":15151,"children":15152},{},[15153,15160,15162,15167,15169,15174,15176,15185,15187,15192,15194,15199],{"type":29,"tag":645,"props":15154,"children":15155},{"href":14654},[15156],{"type":29,"tag":52,"props":15157,"children":15158},{},[15159],{"type":56,"value":14660},{"type":56,"value":15161}," ist ein spezialisiertes Tool für ",{"type":29,"tag":52,"props":15163,"children":15164},{},[15165],{"type":56,"value":15166},"Error Tracking",{"type":56,"value":15168},". Es fängt Fehler und Exceptions der Anwendung ab und\nsammelt sie zentral. Warum ist das wichtig? In Produktion kann ein Entwickler nicht einfach mit dem Debugger am Code\nhängen. Sentry schließt diese Lücke: Es liefert detaillierte Fehlerreports (mit Stacktrace, User-Informationen,\nKontextvariablen etc.), sobald irgendwo im Code eine Exception auftritt. In der Dev-Community gilt Sentry daher\nmittlerweile als ",{"type":29,"tag":52,"props":15170,"children":15171},{},[15172],{"type":56,"value":15173},"industrieller Standard",{"type":56,"value":15175},", wenn es um Crash-Reporting geht\n",{"type":29,"tag":645,"props":15177,"children":15179},{"href":15178},"https://medium.com/@AndrzejSala/efficient-error-tracking-with-sentry-e975c186947c#:~:text=Sentry%20is%20a%20crash,an%20industry%20standard%20by%20TechRadar",[15180,15182],{"type":56,"value":15181},"medium.com",{"type":29,"tag":1670,"props":15183,"children":15184},{},[],{"type":56,"value":15186},".\nSelbst weniger erfahrene Entwickler finden mit Sentry schneller die Ursache von Fehlern, weil das Tool viel manuelle\nDetektivarbeit abnimmt. Ohne ein Tool wie Sentry bekommt man viele Fehler in einer komplexen Web-Anwendung gar nicht\nmit, bis Nutzende sich beschweren. Mit Sentry hingegen erfährt das Team oft ",{"type":29,"tag":52,"props":15188,"children":15189},{},[15190],{"type":56,"value":15191},"sofort",{"type":56,"value":15193},", wenn irgendwo ein Fehler\npassiert – und kann proaktiv reagieren, ",{"type":29,"tag":52,"props":15195,"children":15196},{},[15197],{"type":56,"value":15198},"bevor",{"type":56,"value":15200}," alle Nutzenden betroffen sind.",{"type":29,"tag":814,"props":15202,"children":15203},{},[15204,15211,15213,15218,15220,15225,15227,15232,15234,15239,15241,15246,15248,15253,15255,15260,15262,15267],{"type":29,"tag":645,"props":15205,"children":15206},{"href":14665},[15207],{"type":29,"tag":52,"props":15208,"children":15209},{},[15210],{"type":56,"value":14671},{"type":56,"value":15212}," dagegen adressiert das ",{"type":29,"tag":52,"props":15214,"children":15215},{},[15216],{"type":56,"value":15217},"Performance-Monitoring und die Visualisierung",{"type":56,"value":15219}," von Systemmetriken. Grafana\nselbst ist eigentlich ein Dashboard-Werkzeug, das verschiedene Datenquellen einbinden kann – von Server-CPU-Auslastung\nüber Datenbank-Performance bis hin zu anwendungsspezifischen KPIs. In Kombination mit z.B. ",{"type":29,"tag":52,"props":15221,"children":15222},{},[15223],{"type":56,"value":15224},"Prometheus",{"type":56,"value":15226}," (für\nMetrik-Sammlung) oder ",{"type":29,"tag":52,"props":15228,"children":15229},{},[15230],{"type":56,"value":15231},"Loki",{"type":56,"value":15233}," (für Log-Sammlung) entsteht so ein mächtiges ",{"type":29,"tag":52,"props":15235,"children":15236},{},[15237],{"type":56,"value":15238},"Monitoring-Cockpit",{"type":56,"value":15240},". Man möchte ",{"type":29,"tag":14566,"props":15242,"children":15243},{},[15244],{"type":56,"value":15245},"auf\neinen Blick",{"type":56,"value":15247}," sehen können, ob alle Systeme grün sind, wo vielleicht Engpässe drohen oder ob ungewöhnliche Ausschläge\nauftreten. Konkret bedeutet dies: Grafana & Co. helfen dabei, ",{"type":29,"tag":52,"props":15249,"children":15250},{},[15251],{"type":56,"value":15252},"Trends",{"type":56,"value":15254}," zu erkennen (z.B. stetig steigende\nSpeicherlast), ",{"type":29,"tag":52,"props":15256,"children":15257},{},[15258],{"type":56,"value":15259},"Anomalien",{"type":56,"value":15261}," aufzuspüren (z.B. plötzlicher Traffic-Anstieg um Mitternacht) und im Fehlerfall schnell\ndie ",{"type":29,"tag":52,"props":15263,"children":15264},{},[15265],{"type":56,"value":15266},"Ursache einzugrenzen",{"type":56,"value":1651},{"type":29,"tag":1670,"props":15269,"children":15270},{},[],{"type":29,"tag":15272,"props":15273,"children":15274},"icons-dev-ops",{},[],{"type":29,"tag":48,"props":15276,"children":15277},{},[15278,15282,15284,15289,15291,15296,15298,15303,15305,15310,15312,15317],{"type":29,"tag":52,"props":15279,"children":15280},{},[15281],{"type":56,"value":15009},{"type":56,"value":15283}," Braucht jede kleinere Web-Anwendung gleich so ein Arsenal an Tools? Einige kleinere\nUnternehmen versuchen zunächst, ohne dediziertes Monitoring auszukommen, und verlassen sich auf einfache Logs oder\nmanuelles Überprüfen. Unsere persönliche Erfahrung zeigt jedoch: ",{"type":29,"tag":52,"props":15285,"children":15286},{},[15287],{"type":56,"value":15288},"Spätestens beim ersten größeren Problem wird klar,\ndass Monitoring kein „nice-to-have“, sondern ein echter Mehrwert",{"type":56,"value":15290}," ist. Ohne diese Tools tappt man schnell und lange im\nDunkeln und wühlt sich durch Log-Dateien. Essentiell ist jedoch, die ",{"type":29,"tag":52,"props":15292,"children":15293},{},[15294],{"type":56,"value":15295},"Flut an Daten",{"type":56,"value":15297}," richtig zu kanalisieren und dann\nzu interpretieren. Monitoring richtig aufzusetzen kostet anfangs Zeit (und erfordert etwas Expertise), zahlt sich aber\nbeim ersten Incident vielfach aus. Ein gut konfiguriertes Monitoring vermeidet zudem ",{"type":29,"tag":14566,"props":15299,"children":15300},{},[15301],{"type":56,"value":15302},"Alert Fatigue",{"type":56,"value":15304}," – also zu viele\nFehlalarme. Hier ist ",{"type":29,"tag":52,"props":15306,"children":15307},{},[15308],{"type":56,"value":15309},"Qualität vor Quantität",{"type":56,"value":15311}," gefragt. Lieber wenige, dafür aussagekräftige Metriken und Alerts. Wir\nraten allen unseren Kunden mit Nachdruck: ",{"type":29,"tag":14566,"props":15313,"children":15314},{},[15315],{"type":56,"value":15316},"die Investition in Monitoring- und Logging-Tools sind unerlässlich",{"type":56,"value":15318},", um im\nFehlerfall handlungsfähig zu bleiben!",{"type":29,"tag":90,"props":15320,"children":15322},{"id":15321},"automatische-alerts-zabbix-und-co-als-wächter-der-systeme",[15323],{"type":56,"value":15324},"Automatische Alerts: Zabbix und Co. als Wächter der Systeme",{"type":29,"tag":48,"props":15326,"children":15327},{},[15328,15332],{"type":29,"tag":52,"props":15329,"children":15330},{},[15331],{"type":56,"value":14716},{"type":56,"value":15333}," Überwachungstools wie Zabbix sind notwendig für Alerts bei kritischen Systemzuständen.",{"type":29,"tag":48,"props":15335,"children":15336},{},[15337,15339,15344,15346,15350,15351,15356,15357,15362,15364,15371,15373,15378,15380,15385],{"type":56,"value":15338},"Neben dem reinen Beobachten von Metriken wollen wir natürlich ",{"type":29,"tag":52,"props":15340,"children":15341},{},[15342],{"type":56,"value":15343},"automatisch alarmiert",{"type":56,"value":15345}," werden, wenn etwas aus dem Ruder\nläuft. Hier kommen Systemüberwachungs-Tools wie ",{"type":29,"tag":52,"props":15347,"children":15348},{},[15349],{"type":56,"value":385},{"type":56,"value":10187},{"type":29,"tag":52,"props":15352,"children":15353},{},[15354],{"type":56,"value":15355},"Nagios",{"type":56,"value":10187},{"type":29,"tag":52,"props":15358,"children":15359},{},[15360],{"type":56,"value":15361},"Icinga",{"type":56,"value":15363}," etc. ins Spiel. Bleiben wir bei\n",{"type":29,"tag":645,"props":15365,"children":15366},{"href":14676},[15367],{"type":29,"tag":52,"props":15368,"children":15369},{},[15370],{"type":56,"value":385},{"type":56,"value":15372},"als Beispiel: Zabbix ist ein Open-Source-Monitoring-System, das vordefinierte ",{"type":29,"tag":52,"props":15374,"children":15375},{},[15376],{"type":56,"value":15377},"Trigger",{"type":56,"value":15379}," und\n",{"type":29,"tag":52,"props":15381,"children":15382},{},[15383],{"type":56,"value":15384},"Benachrichtigungen",{"type":56,"value":15386}," bietet. Man kann Grenzwerte festlegen – z.B. „CPU-Last > 90% über 5 Minuten“ oder „weniger als 10%\nfreier Plattenplatz“ – und sobald diese erreicht sind, sendet Zabbix einen Alarm (per E-Mail, SMS, Slack usw.).",{"type":29,"tag":48,"props":15388,"children":15389},{},[15390,15392,15396,15398,15403,15405,15409,15411,15416],{"type":56,"value":15391},"Warum braucht man das, wo wir doch eben Grafana & Co. gelobt haben? Der Unterschied: ",{"type":29,"tag":52,"props":15393,"children":15394},{},[15395],{"type":56,"value":14671},{"type":56,"value":15397}," ist super für\nVisualisierung und Analyse, aber ",{"type":29,"tag":52,"props":15399,"children":15400},{},[15401],{"type":56,"value":15402},"aktive Alarmierung",{"type":56,"value":15404}," übernimmt oft ein dediziertes Tool wie Zabbix (oder Grafana wird\nmit einem Alertmanager kombiniert). ",{"type":29,"tag":52,"props":15406,"children":15407},{},[15408],{"type":56,"value":385},{"type":56,"value":15410}," und ähnliche Tools sind quasi die ",{"type":29,"tag":52,"props":15412,"children":15413},{},[15414],{"type":56,"value":15415},"Nachtwächter",{"type":56,"value":15417},", die unermüdlich auf\ndefinierte Bedingungen achten.",{"type":29,"tag":48,"props":15419,"children":15420},{},[15421,15423,15428,15434,15436,15440],{"type":56,"value":15422},"Die Wichtigkeit solcher Alerts kann man gar nicht überschätzen. Ein treffendes Zitat aus einem Linux-Journal-Artikel:\n",{"type":29,"tag":14566,"props":15424,"children":15425},{},[15426],{"type":56,"value":15427},"„Alerts und Trigger sind der Herzschlag des Monitorings. Zabbix lässt einen spezifische Bedingungen definieren, bei\nderen Eintreten Benachrichtigungen über verschiedene Kanäle versendet werden, sodass man unverzüglich über kritische\nEreignisse informiert wird“",{"type":29,"tag":645,"props":15429,"children":15431},{"href":15430},"https://www.linuxjournal.com/content/how-monitor-your-system-zabbix#:~:text=Alerts%20and%20triggers%20are%20the,that%20could%20impact%20system%20performance",[15432],{"type":56,"value":15433},"linuxjournal.com",{"type":56,"value":15435},"\n. Ohne ein Alerting-System kann es passieren, dass ein Problem stundenlang unentdeckt bleibt – im schlimmsten Fall\nerfährt man es zuerst vom verärgerten Kunden am Telefon. Mit richtig konfigurierten Alerts erfährt das Team hingegen\n",{"type":29,"tag":52,"props":15437,"children":15438},{},[15439],{"type":56,"value":15191},{"type":56,"value":15441},", wenn zum Beispiel der Webserver ausgefallen ist oder die Antwortzeiten kritisch hochgehen.",{"type":29,"tag":48,"props":15443,"children":15444},{},[15445,15450,15452,15457,15459,15464,15466,15471],{"type":29,"tag":52,"props":15446,"children":15447},{},[15448],{"type":56,"value":15449},"Praxisblick:",{"type":56,"value":15451}," Für mittelständische Unternehmen, die vielleicht kein 24/7-Betriebsteam haben, ist ein gutes Alerting\nnoch wichtiger. Es ermöglicht kleinen Teams, effizient zu arbeiten, weil sie sich auf die Warnmeldungen verlassen\nkönnen, anstatt ständig manuell alles zu überprüfen. Allerdings gilt auch hier, dass ein schlecht konfiguriertes System,\ndas andauernd „Wölfe, Wölfe, …“ schreit (Stichwort ",{"type":29,"tag":14566,"props":15453,"children":15454},{},[15455],{"type":56,"value":15456},"false positives",{"type":56,"value":15458},"), wird schnell ignoriert. Die Kunst ist,\n",{"type":29,"tag":52,"props":15460,"children":15461},{},[15462],{"type":56,"value":15463},"sinnvolle Grenzwerte",{"type":56,"value":15465}," zu definieren und ",{"type":29,"tag":52,"props":15467,"children":15468},{},[15469],{"type":56,"value":15470},"kontextreiche Alerts",{"type":56,"value":15472}," zu versenden (z.B. direkt mit Hinweis, welche\nKomponente betroffen ist, Logs anhängen etc.).",{"type":29,"tag":48,"props":15474,"children":15475},{},[15476,15483,15485,15490],{"type":29,"tag":645,"props":15477,"children":15478},{"href":14676},[15479],{"type":29,"tag":52,"props":15480,"children":15481},{},[15482],{"type":56,"value":385},{"type":56,"value":15484}," hat sich in vielen unserer Projekte bewährt und wird bei uns intern oft als ",{"type":29,"tag":52,"props":15486,"children":15487},{},[15488],{"type":56,"value":15489},"unverzichtbares Werkzeug",{"type":56,"value":15491},"\ngenannt.",{"type":29,"tag":90,"props":15493,"children":15495},{"id":15494},"cicd-pipelines-standardisierte-deployments-auch-für-anfänger",[15496],{"type":56,"value":15497},"CI/CD-Pipelines: Standardisierte Deployments – auch für Anfänger",{"type":29,"tag":48,"props":15499,"children":15500},{},[15501,15505],{"type":29,"tag":52,"props":15502,"children":15503},{},[15504],{"type":56,"value":14716},{"type":56,"value":15506}," CI/CD-Pipelines ermöglichen standardisierte, sichere Deployments auch für wenig erfahrene Entwickler.",{"type":29,"tag":48,"props":15508,"children":15509},{},[15510,15512,15516,15518,15523,15525,15530,15532,15537],{"type":56,"value":15511},"Die Begriffe ",{"type":29,"tag":52,"props":15513,"children":15514},{},[15515],{"type":56,"value":5277},{"type":56,"value":15517}," stehen für ",{"type":29,"tag":14566,"props":15519,"children":15520},{},[15521],{"type":56,"value":15522},"Continuous Integration",{"type":56,"value":15524}," (kontinuierliche Integration) und ",{"type":29,"tag":14566,"props":15526,"children":15527},{},[15528],{"type":56,"value":15529},"Continuous\nDelivery/Deployment",{"type":56,"value":15531}," (kontinuierliche Auslieferung bzw. Bereitstellung). Eine ",{"type":29,"tag":52,"props":15533,"children":15534},{},[15535],{"type":56,"value":15536},"CI/CD-Pipeline",{"type":56,"value":15538}," ist eine automatisierte\nProzesskette, die Code vom Commit bis zum Rollout durchbaut, testet und schließlich deployt. Warum ist das so wichtig –\nund wie hilft es weniger erfahrenen Entwicklern?",{"type":29,"tag":48,"props":15540,"children":15541},{},[15542,15544,15549,15551,15556],{"type":56,"value":15543},"In traditionellen Entwicklungsabläufen war das ",{"type":29,"tag":52,"props":15545,"children":15546},{},[15547],{"type":56,"value":15548},"Deployment",{"type":56,"value":15550}," oft Handarbeit, ausgeführt von erfahrenen Admins oder\nDevOps-Engineers, weil viel schiefgehen konnte (fehlende Abhängigkeiten, falsche Configs, Downtime vermeiden etc.). Mit\neiner gut eingerichteten CI/CD-Pipeline wird Deployment jedoch zu einem ",{"type":29,"tag":52,"props":15552,"children":15553},{},[15554],{"type":56,"value":15555},"standardisierten, wiederholbaren Vorgang",{"type":56,"value":15557}," –\nim Idealfall auf Knopfdruck. Selbst wenn ein Entwickler noch nie manuell einen Linux-Server eingerichtet hat, kann er\ndurch die Pipeline-Funktionalität Code live stellen, weil die Pipeline ihm die nötigen Schritte abnimmt.",{"type":29,"tag":48,"props":15559,"children":15560},{},[15561,15566,15568,15573,15575,15579,15580,15585,15587,15592],{"type":29,"tag":52,"props":15562,"children":15563},{},[15564],{"type":56,"value":15565},"Sicherheit und Qualität",{"type":56,"value":15567}," kommen dabei nicht zu kurz – im Gegenteil. Gerade weniger erfahrene Entwickler profitieren\ndavon, dass die Pipeline ",{"type":29,"tag":14566,"props":15569,"children":15570},{},[15571],{"type":56,"value":15572},"vor",{"type":56,"value":15574}," dem Deployment automatisierte ",{"type":29,"tag":52,"props":15576,"children":15577},{},[15578],{"type":56,"value":3649},{"type":56,"value":9692},{"type":29,"tag":52,"props":15581,"children":15582},{},[15583],{"type":56,"value":15584},"Code-Checks",{"type":56,"value":15586}," ausführt. So werden Fehler\nabgefangen, bevor sie auf die Nutzerschaft losgelassen werden. Zudem sorgt die Pipeline dafür, dass immer auf ",{"type":29,"tag":52,"props":15588,"children":15589},{},[15590],{"type":56,"value":15591},"die\ngleiche Weise",{"type":56,"value":15593}," deployed wird – es gibt keine Abweichungen, die durch menschliches Vergessen passieren (z.B. „Oops, die\nstaging Config auf Prod geladen“ – solche Patzer werden eliminiert). Für KMUs bedeutet das: schnellere Updates bei\ngleichzeitig geringerer Fehlerquote.",{"type":29,"tag":48,"props":15595,"children":15596},{},[15597,15599,15604,15606,15611],{"type":56,"value":15598},"Natürlich erfordert das Einrichten einer CI/CD-Pipeline zunächst ",{"type":29,"tag":52,"props":15600,"children":15601},{},[15602],{"type":56,"value":15603},"Know-how und Aufwand",{"type":56,"value":15605},". Hier kommt oft ein\nDevOps-Spezialist ins Spiel, der eine solche Pipeline (z.B. mit Jenkins, GitLab CI, GitHub Actions oder Bitbucket\nPipelines) aufbaut. ",{"type":29,"tag":52,"props":15607,"children":15608},{},[15609],{"type":56,"value":15610},"Kritisch betrachtet",{"type":56,"value":15612}," argumentieren manche, dass in einem perfekten DevOps-Team diese\nUnterscheidung zwischen Entwicklern und DevOps gar nicht mehr nötig wäre, weil alle für den Prozess verantwortlich sind.\nIn der Realität ist es aber gerade für weniger erfahrene Entwickler eine enorme Erleichterung, wenn ein robustes\nCI/CD-System existiert – es nimmt ihnen die Deployment-Angst (das gilt auch für mich selbst als\nProjekt-Verantwortlicher). Ein Junior-Entwickler kann mit ruhigem Gewissen auf „Deploy“ klicken, weil er weiß, wenn\nautomatisierte Tests durchlaufen sind und der Rollout kontrolliert abläuft, besteht ein Mindestmaß an Sicherheit, dass\ndas Produktivsystem nicht beeinträchtigt wird.",{"type":29,"tag":48,"props":15614,"children":15615},{},[15616,15618,15623,15625,15630,15632,15637],{"type":56,"value":15617},"Wichtig ist, dass CI/CD nicht nur technische, sondern auch ",{"type":29,"tag":52,"props":15619,"children":15620},{},[15621],{"type":56,"value":15622},"kulturelle Veränderungen",{"type":56,"value":15624}," mit sich bringt. Deployments\nwerden kleiner, dafür häufiger. Das reduziert Risiko und Fehler-Impact. Teams gewöhnen sich daran, dass Deployments\n",{"type":29,"tag":14566,"props":15626,"children":15627},{},[15628],{"type":56,"value":15629},"Alltag",{"type":56,"value":15631}," sind und nicht „Großkampftage“. Gerade in der ",{"type":29,"tag":52,"props":15633,"children":15634},{},[15635],{"type":56,"value":15636},"Agilen Entwicklung",{"type":56,"value":15638}," ist CI/CD quasi das Rückgrat, um schnelle\nIterationen überhaupt zu ermöglichen.",{"type":29,"tag":48,"props":15640,"children":15641},{},[15642,15644,15649],{"type":56,"value":15643},"Zusammengefasst: CI/CD-Pipelines sind ein Game-Changer, der auch weniger erfahrene Entwickler befähigt,\n",{"type":29,"tag":52,"props":15645,"children":15646},{},[15647],{"type":56,"value":15648},"auf Knopfdruck",{"type":56,"value":15650}," auszuliefern – zuverlässig und wiederholbar.",{"type":29,"tag":90,"props":15652,"children":15654},{"id":15653},"erfahrung-zählt-live-daten-spezielle-fehler-und-die-rolle-von-devops-experten",[15655],{"type":56,"value":15656},"Erfahrung zählt: Live-Daten, spezielle Fehler und die Rolle von DevOps-Experten",{"type":29,"tag":48,"props":15658,"children":15659},{},[15660,15664],{"type":29,"tag":52,"props":15661,"children":15662},{},[15663],{"type":56,"value":14716},{"type":56,"value":15665}," Bestimmte Fehler und Performance-Probleme zeigen sich nur auf Live-Daten und erfordern erfahrene\nDevOps-Spezialisten.",{"type":29,"tag":48,"props":15667,"children":15668},{},[15669,15671,15676,15678,15683,15685,15690],{"type":56,"value":15670},"Trotz aller Automatisierung und Testing bleibt die ",{"type":29,"tag":52,"props":15672,"children":15673},{},[15674],{"type":56,"value":15675},"Erfahrung",{"type":56,"value":15677}," im Umgang mit Produktionssystemen ist durch nichts zu\nersetzen. Es gibt Fehlerbilder, die erst bei echten ",{"type":29,"tag":52,"props":15679,"children":15680},{},[15681],{"type":56,"value":15682},"Live-Daten und Lasten",{"type":56,"value":15684}," auftreten – etwa aufgrund komplexer\nDatenkonstellationen oder schlichter Skalierungseffekte. Ein Query, der mit 100 Test-Datensätzen blitzschnell ist, kann\nmit 100 Millionen echten Datensätzen plötzlich zum Flaschenhals werden. Oder ein ",{"type":29,"tag":52,"props":15686,"children":15687},{},[15688],{"type":56,"value":15689},"Memory-Leak",{"type":56,"value":15691}," in einer bestimmten\nLibrary fällt erst nach Wochen Dauerbetrieb auf, wenn der Prozess immer mehr Speicher belegt. Solche Probleme zu\nerkennen und zu beheben, erfordert oft einen erfahrenen Blick.",{"type":29,"tag":48,"props":15693,"children":15694},{},[15695,15697,15702,15704,15710,15711,15717,15718,15724,15726,15731,15733,15738,15740,15745],{"type":56,"value":15696},"Ein DevOps-Engineer mit viel Betriebserfahrung hat meist ein Repertoire an ",{"type":29,"tag":52,"props":15698,"children":15699},{},[15700],{"type":56,"value":15701},"Diagnosetechniken",{"type":56,"value":15703},". Beispielsweise wissen\nerfahrene Leute, wie man mit Tools wie ",{"type":29,"tag":672,"props":15705,"children":15707},{"className":15706},[],[15708],{"type":56,"value":15709},"htop",{"type":56,"value":10187},{"type":29,"tag":672,"props":15712,"children":15714},{"className":15713},[],[15715],{"type":56,"value":15716},"iotop",{"type":56,"value":11194},{"type":29,"tag":672,"props":15719,"children":15721},{"className":15720},[],[15722],{"type":56,"value":15723},"strace",{"type":56,"value":15725}," auf Linux debuggt, was weniger routinierte Entwickler\nvielleicht nie gebraucht haben. Auch ",{"type":29,"tag":52,"props":15727,"children":15728},{},[15729],{"type":56,"value":15730},"Dauerlast-Phänomene",{"type":56,"value":15732}," (Stichwort ",{"type":29,"tag":14566,"props":15734,"children":15735},{},[15736],{"type":56,"value":15737},"Floating-Point-Precision Bugs",{"type":56,"value":15739},",\nspeicherbedingte Rounding Errors, etc.) kennen erfahrene DevOps aus der Praxis. Ein drastisches, aber reales Szenario:\nEin Speicherfehler tritt ",{"type":29,"tag":14566,"props":15741,"children":15742},{},[15743],{"type":56,"value":15744},"nur",{"type":56,"value":15746}," unter richtiger Volllast auf und nur in Kombination mit bestimmten Hardwarebedingungen –\nhier braucht es Experten, die vielleicht schon mal ähnliches gesehen haben oder wissen, wo man ansetzt.",{"type":29,"tag":90,"props":15748,"children":15750},{"id":15749},"fazit",[15751],{"type":56,"value":15752},"Fazit",{"type":29,"tag":48,"props":15754,"children":15755},{},[15756,15758,15763,15765,15770,15772,15779],{"type":56,"value":15757},"Für (Web-)Anwendungen im produktiven Einsatz sind ",{"type":29,"tag":52,"props":15759,"children":15760},{},[15761],{"type":56,"value":15762},"DevOps kein Luxus, sondern eine Notwendigkeit",{"type":56,"value":15764},".\nEntwicklungsumgebungen stoßen an Grenzen, echte Nutzer sorgen für Überraschungen, und ohne kontinuierliches Monitoring\nfliegt man blind. Mittelständische Unternehmen, die vielleicht keine riesigen IT-Abteilungen haben, können durch einen\nDevOps-Ansatz enorm profitieren. Stabilere Systeme, schnellere Reaktionszeiten bei Problemen und zufriedenere Kunden.\nAllerdings muss man bereit sein, auch nach dem Launch ",{"type":29,"tag":52,"props":15766,"children":15767},{},[15768],{"type":56,"value":15769},"Zeit und Ressourcen zu investieren",{"type":56,"value":15771},", um Daten zu analysieren\nund Verbesserungen einzuspielen. Tools wie ",{"type":29,"tag":645,"props":15773,"children":15774},{"href":14654},[15775],{"type":29,"tag":52,"props":15776,"children":15777},{},[15778],{"type":56,"value":14660},{"type":56,"value":15780},", Grafana und Zabbix bilden dabei das Rückgrat der Überwachung – sie\nliefern die nötigen Daten und Unterstützungsmechanismen. Automatisierung mittels CI/CD nimmt viel Risiko aus Deployments\nund erlaubt auch weniger erfahrenen Team-Mitgliedern, Änderungen sicher live zu bringen.",{"type":29,"tag":48,"props":15782,"children":15783},{},[15784,15786,15791],{"type":56,"value":15785},"Am Ende zeigt sich: ",{"type":29,"tag":52,"props":15787,"children":15788},{},[15789],{"type":56,"value":15790},"Menschen",{"type":56,"value":15792}," machen den Unterschied. Erfahrene DevOps-Spezialisten können knifflige Live-Probleme\nlösen und eine Brücke zwischen Entwicklern und Betrieb schlagen.",{"type":29,"tag":48,"props":15794,"children":15795},{},[15796,15801],{"type":29,"tag":52,"props":15797,"children":15798},{},[15799],{"type":56,"value":15800},"Hinweis:",{"type":56,"value":15802}," Dieser Artikel wurde auch mit Unterstützung von KI generiert (Modell: GPT-4).",{"title":7,"searchDepth":342,"depth":342,"links":15804},[15805,15806,15807,15808,15809,15810,15811,15812],{"id":14577,"depth":342,"text":14580},{"id":14705,"depth":342,"text":14708},{"id":14958,"depth":342,"text":14961},{"id":15099,"depth":342,"text":15102},{"id":15321,"depth":342,"text":15324},{"id":15494,"depth":342,"text":15497},{"id":15653,"depth":342,"text":15656},{"id":15749,"depth":342,"text":15752},{"_path":610,"_dir":515,"_draft":6,"_partial":6,"_locale":7,"title":611,"description":612,"author":170,"image":613,"releaseDate":614,"blogCategories":15814,"articleTags":15815,"tags":15816,"body":15817,"_type":346,"_id":619,"_source":348,"_file":620,"_stem":621,"_extension":351},[579,523],[617,382],[24],{"type":26,"children":15818,"toc":16360},[15819,15825,15830,15835,15851,15864,15870,15897,15915,15921,15926,15939,15952,15983,16010,16031,16085,16101,16127,16170,16199,16249,16268,16281,16324,16336,16356],{"type":29,"tag":90,"props":15820,"children":15822},{"id":15821},"wie-man-ausgewählte-domains-über-vpn-unter-linux-auflöst",[15823],{"type":56,"value":15824},"Wie man ausgewählte Domains über VPN unter Linux auflöst",{"type":29,"tag":48,"props":15826,"children":15827},{},[15828],{"type":56,"value":15829},"In der heutigen Welt nutzen mehr Menschen als je zuvor VPN-Dienste, um aus der Ferne zu arbeiten. In manchen Fällen ist\nes jedoch nicht wünschenswert, den gesamten Datenverkehr und alle Domainnamenauflösungen über die VPN-Verbindung zu\nleiten. Selbst wenn der VPN-Server möchte, dass der Client genau so\nkonfiguriert werden soll, kann der Client so konfiguriert werden, dass er die Anforderung, den gesamten Datenverkehr\nüber die VPN-Verbindung zu leiten, ignoriert.",{"type":29,"tag":48,"props":15831,"children":15832},{},[15833],{"type":56,"value":15834},"Zum Beispiel kann bei Openvpn die Option",{"type":29,"tag":659,"props":15836,"children":15840},{"className":15837,"code":15838,"language":15839,"meta":7,"style":7},"language-apache shiki shiki-themes github-dark github-dark monokai","pull-filter ignore redirect-gateway\n","apache",[15841],{"type":29,"tag":672,"props":15842,"children":15843},{"__ignoreMap":7},[15844],{"type":29,"tag":127,"props":15845,"children":15846},{"class":677,"line":678},[15847],{"type":29,"tag":127,"props":15848,"children":15849},{"style":688},[15850],{"type":56,"value":15838},{"type":29,"tag":48,"props":15852,"children":15853},{},[15854,15856,15862],{"type":56,"value":15855},"verwendet werden, um den ",{"type":29,"tag":672,"props":15857,"children":15859},{"className":15858},[],[15860],{"type":56,"value":15861},"openvpn-client",{"type":56,"value":15863}," anzuweisen, alle \"route all\"-Anfragen des Servers zu ignorieren.",{"type":29,"tag":90,"props":15865,"children":15867},{"id":15866},"fritzbox-beispiel",[15868],{"type":56,"value":15869},"FRITZ!Box Beispiel",{"type":29,"tag":48,"props":15871,"children":15872},{},[15873,15875,15880,15882,15888,15890,15896],{"type":56,"value":15874},"Kürzlich musste ich eine VPN-Verbindung zu einer ",{"type":29,"tag":52,"props":15876,"children":15877},{},[15878],{"type":56,"value":15879},"FRITZ!Box",{"type":56,"value":15881}," nutzen. Das ist ein sehr beliebter Router in Deutschland,\nder nicht nur\neinfache\nVPN-Verbindungen anbietet, sondern auch alle Hosts in seinem Netzwerk zu seinem eigenen DNS hinzufügt. Wenn Sie mit\neinem Rechner mit dem Namen ",{"type":29,"tag":672,"props":15883,"children":15885},{"className":15884},[],[15886],{"type":56,"value":15887}," workstation",{"type":56,"value":15889}," ansprechen wollen, können Sie ihn über den dns-Namen \"workstation.fritz.box\" erreichen. Die fritz-box\nselbst ist auch unter dem\ndns-Namen ",{"type":29,"tag":672,"props":15891,"children":15893},{"className":15892},[],[15894],{"type":56,"value":15895},"fritz.box",{"type":56,"value":1651},{"type":29,"tag":48,"props":15898,"children":15899},{},[15900,15902,15907,15909,15913],{"type":56,"value":15901},"In meinem Fall ziehe ich es aus Geschwindigkeits- und Datenschutzgründen vor, meinen eigenen DNS-Server für alle\nAbfragen zu verwenden - das heißt, ich möchte nur\ndie Domains mit dem Suffix ",{"type":29,"tag":672,"props":15903,"children":15905},{"className":15904},[],[15906],{"type":56,"value":15895},{"type":56,"value":15908}," über die ",{"type":29,"tag":52,"props":15910,"children":15911},{},[15912],{"type":56,"value":15879},{"type":56,"value":15914}," auflösen.",{"type":29,"tag":90,"props":15916,"children":15918},{"id":15917},"lösung-mit-einem-lokalen-dns-server-dnsmasq",[15919],{"type":56,"value":15920},"Lösung mit einem lokalen DNS-Server - dnsmasq",{"type":29,"tag":48,"props":15922,"children":15923},{},[15924],{"type":56,"value":15925},"Dnsmasq ist ein leichtgewichtiger DNS-Server, den man auf dem eigenen Rechner laufen lassen kann, um die Kontrolle über\ndie Namensauflösung zu bekommen. Ein netter Nebeneffekt ist, dass er seinen eigenen DNS-Cache hat, was wiederkehrende\nDNS-Abfragen schneller macht. Hier ist, wie ich ihn eingerichtet habe:",{"type":29,"tag":48,"props":15927,"children":15928},{},[15929,15931,15937],{"type":56,"value":15930},"Bevor Sie beginnen, müssen Sie herausfinden, welcher DNS-Server im VPN verwendet wird. Normalerweise ist es das\nStandard-Gateway, das normalerweise\nein ",{"type":29,"tag":672,"props":15932,"children":15934},{"className":15933},[],[15935],{"type":56,"value":15936},".1",{"type":56,"value":15938}," am Ende hat. Sie können die VPN-Protokolle genau beobachten, um herauszufinden, welcher DNS-Server bei der\nVerbindung verwendet wird.",{"type":29,"tag":48,"props":15940,"children":15941},{},[15942,15944,15950],{"type":56,"value":15943},"Es gibt ein Tool namens ",{"type":29,"tag":672,"props":15945,"children":15947},{"className":15946},[],[15948],{"type":56,"value":15949},"dig",{"type":56,"value":15951},", das DNS-Abfragen über bestimmte DNS-Server durchführen kann, zum Beispiel",{"type":29,"tag":659,"props":15953,"children":15957},{"className":15954,"code":15955,"language":15956,"meta":7,"style":7},"language-bash shiki shiki-themes github-dark github-dark monokai","dig @192.168.1.1 a fritz.box\n\n","bash",[15958],{"type":29,"tag":672,"props":15959,"children":15960},{"__ignoreMap":7},[15961],{"type":29,"tag":127,"props":15962,"children":15963},{"class":677,"line":678},[15964,15968,15973,15978],{"type":29,"tag":127,"props":15965,"children":15966},{"style":3033},[15967],{"type":56,"value":15949},{"type":29,"tag":127,"props":15969,"children":15970},{"style":720},[15971],{"type":56,"value":15972}," @192.168.1.1",{"type":29,"tag":127,"props":15974,"children":15975},{"style":720},[15976],{"type":56,"value":15977}," a",{"type":29,"tag":127,"props":15979,"children":15980},{"style":720},[15981],{"type":56,"value":15982}," fritz.box\n",{"type":29,"tag":48,"props":15984,"children":15985},{},[15986,15988,15994,15996,16001,16003,16009],{"type":56,"value":15987},"wird den DNS-Server ",{"type":29,"tag":672,"props":15989,"children":15991},{"className":15990},[],[15992],{"type":56,"value":15993},"192.168.1.1",{"type":56,"value":15995}," nach der IP von ",{"type":29,"tag":672,"props":15997,"children":15999},{"className":15998},[],[16000],{"type":56,"value":15895},{"type":56,"value":16002}," fragen. Dig ist sehr praktisch bei der Fehlersuche bei DNS-Problemen und Ihrer Einrichtung zu testen.  Sie müssen es eventuell auf Ihrem System installieren. Unter Debian befindet es sich in einem Paket namens ",{"type":29,"tag":672,"props":16004,"children":16006},{"className":16005},[],[16007],{"type":56,"value":16008},"dnsutils",{"type":56,"value":1651},{"type":29,"tag":48,"props":16011,"children":16012},{},[16013,16015,16021,16023,16029],{"type":56,"value":16014},"Installieren Sie zuerst ",{"type":29,"tag":672,"props":16016,"children":16018},{"className":16017},[],[16019],{"type":56,"value":16020},"dnsmasq",{"type":56,"value":16022}," auf Ihrem Linux und bearbeiten Sie seine Konfiguration (normalerweise in ",{"type":29,"tag":672,"props":16024,"children":16026},{"className":16025},[],[16027],{"type":56,"value":16028},"/etc/dnsmasq.conf",{"type":56,"value":16030},"). Fügen Sie diese Zeilen\nhier ein:",{"type":29,"tag":659,"props":16032,"children":16034},{"className":15837,"code":16033,"language":15839,"meta":7,"style":7},"resolv-datei=/etc/resolv.dnsmasq.conf\nserver=/fritz.box/192.168.1.1\n",[16035],{"type":29,"tag":672,"props":16036,"children":16037},{"__ignoreMap":7},[16038,16046],{"type":29,"tag":127,"props":16039,"children":16040},{"class":677,"line":678},[16041],{"type":29,"tag":127,"props":16042,"children":16043},{"style":688},[16044],{"type":56,"value":16045},"resolv-datei=/etc/resolv.dnsmasq.conf\n",{"type":29,"tag":127,"props":16047,"children":16048},{"class":677,"line":342},[16049,16054,16059,16063,16068,16072,16076,16080],{"type":29,"tag":127,"props":16050,"children":16051},{"style":688},[16052],{"type":56,"value":16053},"server=/fritz.box/",{"type":29,"tag":127,"props":16055,"children":16056},{"style":2303},[16057],{"type":56,"value":16058},"192",{"type":29,"tag":127,"props":16060,"children":16061},{"style":688},[16062],{"type":56,"value":1651},{"type":29,"tag":127,"props":16064,"children":16065},{"style":2303},[16066],{"type":56,"value":16067},"168",{"type":29,"tag":127,"props":16069,"children":16070},{"style":688},[16071],{"type":56,"value":1651},{"type":29,"tag":127,"props":16073,"children":16074},{"style":2303},[16075],{"type":56,"value":450},{"type":29,"tag":127,"props":16077,"children":16078},{"style":688},[16079],{"type":56,"value":1651},{"type":29,"tag":127,"props":16081,"children":16082},{"style":2303},[16083],{"type":56,"value":16084},"1\n",{"type":29,"tag":48,"props":16086,"children":16087},{},[16088,16093,16095,16100],{"type":29,"tag":672,"props":16089,"children":16091},{"className":16090},[],[16092],{"type":56,"value":15895},{"type":56,"value":16094}," ist die Domain, die über den VPN-Dnsserver aufgelöst werden soll, in diesem Beispiel ",{"type":29,"tag":672,"props":16096,"children":16098},{"className":16097},[],[16099],{"type":56,"value":15993},{"type":56,"value":1651},{"type":29,"tag":48,"props":16102,"children":16103},{},[16104,16105,16110,16112,16117,16119,16125],{"type":56,"value":6227},{"type":29,"tag":52,"props":16106,"children":16107},{},[16108],{"type":56,"value":16109},"Resolv-Datei",{"type":56,"value":16111}," wird ",{"type":29,"tag":672,"props":16113,"children":16115},{"className":16114},[],[16116],{"type":56,"value":16020},{"type":56,"value":16118}," mitteilen, wie es seine DNS-Anfragen auflösen soll, falls es keine anderen Regeln\ngibt, also erstellen wir ",{"type":29,"tag":672,"props":16120,"children":16122},{"className":16121},[],[16123],{"type":56,"value":16124},"/etc/resolv.dnsmasq.conf",{"type":56,"value":16126},"\nmit dem Inhalt",{"type":29,"tag":659,"props":16128,"children":16130},{"className":15837,"code":16129,"language":15839,"meta":7,"style":7},"Nameserver 1.1.1.1\n",[16131],{"type":29,"tag":672,"props":16132,"children":16133},{"__ignoreMap":7},[16134],{"type":29,"tag":127,"props":16135,"children":16136},{"class":677,"line":678},[16137,16142,16146,16150,16154,16158,16162,16166],{"type":29,"tag":127,"props":16138,"children":16139},{"style":688},[16140],{"type":56,"value":16141},"Nameserver ",{"type":29,"tag":127,"props":16143,"children":16144},{"style":2303},[16145],{"type":56,"value":450},{"type":29,"tag":127,"props":16147,"children":16148},{"style":688},[16149],{"type":56,"value":1651},{"type":29,"tag":127,"props":16151,"children":16152},{"style":2303},[16153],{"type":56,"value":450},{"type":29,"tag":127,"props":16155,"children":16156},{"style":688},[16157],{"type":56,"value":1651},{"type":29,"tag":127,"props":16159,"children":16160},{"style":2303},[16161],{"type":56,"value":450},{"type":29,"tag":127,"props":16163,"children":16164},{"style":688},[16165],{"type":56,"value":1651},{"type":29,"tag":127,"props":16167,"children":16168},{"style":2303},[16169],{"type":56,"value":16084},{"type":29,"tag":48,"props":16171,"children":16172},{},[16173,16175,16181,16183,16189,16191,16197],{"type":56,"value":16174},"Wenn Sie eine statische Netzwerkkonfiguration verwenden, können Sie diese jetzt einfach bearbeiten, um ",{"type":29,"tag":672,"props":16176,"children":16178},{"className":16177},[],[16179],{"type":56,"value":16180},"127.0.0.1",{"type":56,"value":16182}," als\nNameserver zu verwenden. Wenn Sie\nautomatische IP-Konfiguration mit dhcp verwenden, müssen Sie Ihren dhcp-Client so konfigurieren, dass er den neuen\nlokalen DNS-Server verwendet. Unter Debian,\nist der Standard ",{"type":29,"tag":672,"props":16184,"children":16186},{"className":16185},[],[16187],{"type":56,"value":16188},"dhclient",{"type":56,"value":16190},". In diesem Fall editieren Sie ",{"type":29,"tag":672,"props":16192,"children":16194},{"className":16193},[],[16195],{"type":56,"value":16196},"/etc/dhcp/dhclient.conf",{"type":56,"value":16198}," und fügen hinzu:",{"type":29,"tag":659,"props":16200,"children":16202},{"className":15837,"code":16201,"language":15839,"meta":7,"style":7},"domain-name-servers 127.0.0.1 vorangestellt;\n\n",[16203],{"type":29,"tag":672,"props":16204,"children":16205},{"__ignoreMap":7},[16206],{"type":29,"tag":127,"props":16207,"children":16208},{"class":677,"line":678},[16209,16214,16219,16223,16228,16232,16236,16240,16244],{"type":29,"tag":127,"props":16210,"children":16211},{"style":688},[16212],{"type":56,"value":16213},"domain-name-servers ",{"type":29,"tag":127,"props":16215,"children":16216},{"style":2303},[16217],{"type":56,"value":16218},"127",{"type":29,"tag":127,"props":16220,"children":16221},{"style":688},[16222],{"type":56,"value":1651},{"type":29,"tag":127,"props":16224,"children":16225},{"style":2303},[16226],{"type":56,"value":16227},"0",{"type":29,"tag":127,"props":16229,"children":16230},{"style":688},[16231],{"type":56,"value":1651},{"type":29,"tag":127,"props":16233,"children":16234},{"style":2303},[16235],{"type":56,"value":16227},{"type":29,"tag":127,"props":16237,"children":16238},{"style":688},[16239],{"type":56,"value":1651},{"type":29,"tag":127,"props":16241,"children":16242},{"style":2303},[16243],{"type":56,"value":450},{"type":29,"tag":127,"props":16245,"children":16246},{"style":688},[16247],{"type":56,"value":16248}," vorangestellt;\n",{"type":29,"tag":48,"props":16250,"children":16251},{},[16252,16254,16259,16261,16266],{"type":56,"value":16253},"Das war's. Alles, was Sie jetzt noch tun müssen, ist ",{"type":29,"tag":672,"props":16255,"children":16257},{"className":16256},[],[16258],{"type":56,"value":16020},{"type":56,"value":16260}," neu zu starten, damit es seine Konfiguration neu lädt und ",{"type":29,"tag":672,"props":16262,"children":16264},{"className":16263},[],[16265],{"type":56,"value":16188},{"type":56,"value":16267}," neu zu verbinden/starten\n(das Trennen und erneute Verbinden des Netzwerks kann funktionieren, im Zweifelsfall starten Sie den Rechner neu).",{"type":29,"tag":48,"props":16269,"children":16270},{},[16271,16273,16279],{"type":56,"value":16272},"Jetzt können Sie überprüfen, ob die Datei ",{"type":29,"tag":672,"props":16274,"children":16276},{"className":16275},[],[16277],{"type":56,"value":16278},"/etc/resolv.conf",{"type":56,"value":16280}," folgendes enthält",{"type":29,"tag":659,"props":16282,"children":16284},{"className":15837,"code":16283,"language":15839,"meta":7,"style":7},"nameserver 127.0.0.1\n",[16285],{"type":29,"tag":672,"props":16286,"children":16287},{"__ignoreMap":7},[16288],{"type":29,"tag":127,"props":16289,"children":16290},{"class":677,"line":678},[16291,16296,16300,16304,16308,16312,16316,16320],{"type":29,"tag":127,"props":16292,"children":16293},{"style":688},[16294],{"type":56,"value":16295},"nameserver ",{"type":29,"tag":127,"props":16297,"children":16298},{"style":2303},[16299],{"type":56,"value":16218},{"type":29,"tag":127,"props":16301,"children":16302},{"style":688},[16303],{"type":56,"value":1651},{"type":29,"tag":127,"props":16305,"children":16306},{"style":2303},[16307],{"type":56,"value":16227},{"type":29,"tag":127,"props":16309,"children":16310},{"style":688},[16311],{"type":56,"value":1651},{"type":29,"tag":127,"props":16313,"children":16314},{"style":2303},[16315],{"type":56,"value":16227},{"type":29,"tag":127,"props":16317,"children":16318},{"style":688},[16319],{"type":56,"value":1651},{"type":29,"tag":127,"props":16321,"children":16322},{"style":2303},[16323],{"type":56,"value":16084},{"type":29,"tag":48,"props":16325,"children":16326},{},[16327,16329,16334],{"type":56,"value":16328},"als ersten Nameserver enthält. Wenn dies der Fall ist, sollte die ausgewählte Domain (in meinem Beispiel ",{"type":29,"tag":672,"props":16330,"children":16332},{"className":16331},[],[16333],{"type":56,"value":15895},{"type":56,"value":16335},")\nnun aufgelöst werden.",{"type":29,"tag":48,"props":16337,"children":16338},{},[16339,16341,16346,16348,16354],{"type":56,"value":16340},"Bei ",{"type":29,"tag":672,"props":16342,"children":16344},{"className":16343},[],[16345],{"type":56,"value":16020},{"type":56,"value":16347}," können Sie mehrere ",{"type":29,"tag":672,"props":16349,"children":16351},{"className":16350},[],[16352],{"type":56,"value":16353},"server=",{"type":56,"value":16355},"-Zeilen hinzufügen, was praktisch ist, wenn Sie mehrere Domains haben, die\nüber verschiedene DNS-Server aufgelöst werden müssen.",{"type":29,"tag":1838,"props":16357,"children":16358},{},[16359],{"type":56,"value":1842},{"title":7,"searchDepth":342,"depth":342,"links":16361},[16362,16363,16364],{"id":15821,"depth":342,"text":15824},{"id":15866,"depth":342,"text":15869},{"id":15917,"depth":342,"text":15920},{"_path":623,"_dir":515,"_draft":6,"_partial":6,"_locale":7,"title":624,"description":625,"author":170,"image":626,"releaseDate":627,"blogCategories":16366,"articleTags":16367,"tags":16368,"body":16369,"_type":346,"_id":632,"_source":348,"_file":633,"_stem":634,"_extension":351},[579,591],[630],[24],{"type":26,"children":16370,"toc":16834},[16371,16377,16389,16395,16400,16406,16411,16450,16456,16461,16467,16479,16597,16615,16621,16777,16782,16788,16824,16830],{"type":29,"tag":90,"props":16372,"children":16374},{"id":16373},"was-ist-btrfs-fragmentierung",[16375],{"type":56,"value":16376},"Was ist BTRFS-Fragmentierung?",{"type":29,"tag":48,"props":16378,"children":16379},{},[16380,16382,16387],{"type":56,"value":16381},"Die meisten der besten BTRFS-Funktionen beruhen auf der ",{"type":29,"tag":14566,"props":16383,"children":16384},{},[16385],{"type":56,"value":16386},"Copy-on-Write-Technologie",{"type":56,"value":16388},". Wenn eine Anwendung einen Teil einer Datei umschreiben will, z.B. das erste MegaByte, werden die Daten nicht an Ort und Stelle geschrieben, sondern in einer sogenannten Erweiterung. Dadurch ist BTRFS in der Lage, mehrere Versionen von teilweise umgeschriebenen Dateien aufzubewahren, wobei nur der den Änderungen zugewiesene Speicherplatz beansprucht wird und nicht mehrere vollständige Kopien einer Datei. Die alten Daten können zu einem bestimmten Zeitpunkt verworfen werden (z.B. wenn sie nicht mehr von Snapshots verwendet werden) und die Erweiterung dient der aktuellen Version der Datei.",{"type":29,"tag":90,"props":16390,"children":16392},{"id":16391},"btrfs-fragmentierung-kann-die-leistung-ihres-systems-beeinträchtigen",[16393],{"type":56,"value":16394},"BTRFS-Fragmentierung kann die Leistung Ihres Systems beeinträchtigen",{"type":29,"tag":48,"props":16396,"children":16397},{},[16398],{"type":56,"value":16399},"Sie können sich vorstellen, dass das Lesen einer Datei mit 100k+ Erweiterungen und das Hinzufügen weiterer Erweiterungen eine Menge Buchführung und Speichersuchvorgänge von Ihrem System erfordert. Diese 10 GB große Datei ist intern in 100k+ Teile zerlegt, die gesammelt werden müssen, wenn Sie die gesamte Datei lesen wollen. Dies erhöht eindeutig die Komplexität - und verringert die Leistung.",{"type":29,"tag":90,"props":16401,"children":16403},{"id":16402},"btrfs-fragmentierung-kann-große-mengen-an-speicherplatz-blockieren",[16404],{"type":56,"value":16405},"BTRFS-Fragmentierung kann große Mengen an Speicherplatz blockieren",{"type":29,"tag":48,"props":16407,"children":16408},{},[16409],{"type":56,"value":16410},"Ja, BTRFS muss die Speicherorte dieser 100k Erweiterungen irgendwo speichern, was leicht einige zusätzliche GB an belegtem Speicherplatz zu Ihrem System hinzufügen kann. Das Schlimme daran ist, dass BTRFS Ihnen das nicht mitteilt.",{"type":29,"tag":48,"props":16412,"children":16413},{},[16414,16416,16421,16423,16428,16429,16434,16436,16441,16443,16448],{"type":56,"value":16415},"Wenn Sie sehen, dass Ihr btrfs-Dateisystem ",{"type":29,"tag":52,"props":16417,"children":16418},{},[16419],{"type":56,"value":16420},"80GB",{"type":56,"value":16422}," in ",{"type":29,"tag":14566,"props":16424,"children":16425},{},[16426],{"type":56,"value":16427},"df",{"type":56,"value":9692},{"type":29,"tag":14566,"props":16430,"children":16431},{},[16432],{"type":56,"value":16433},"btrfs fi show",{"type":56,"value":16435}," verwendet, während ",{"type":29,"tag":14566,"props":16437,"children":16438},{},[16439],{"type":56,"value":16440},"du -hsx",{"type":56,"value":16442}," nur ",{"type":29,"tag":52,"props":16444,"children":16445},{},[16446],{"type":56,"value":16447},"54GB",{"type":56,"value":16449}," anzeigt, gibt es nur zwei Gründe, die mir bekannt sind: entweder Sie haben Snapshots, die alte Erweiterungen behalten - oder Sie haben eine massive Fragmentierung.",{"type":29,"tag":90,"props":16451,"children":16453},{"id":16452},"btrfs-dateisystem-defragmentieren",[16454],{"type":56,"value":16455},"BTRFS-Dateisystem defragmentieren",{"type":29,"tag":48,"props":16457,"children":16458},{},[16459],{"type":56,"value":16460},"Es ist möglich, das BTRFS-Dateisystem auf dem gesamten Dateisystem zu defragmentieren, aber das führt dazu, dass alle Snapshots die Daten duplizieren. Es verursacht auch eine Menge IO, so dass dies nichts ist, was Sie auf Ihrem Produktionsserver ohne Grund tun wollen. Es macht wirklich keinen Sinn, statische Dateien zu defragmentieren, die fast nie geändert werden.",{"type":29,"tag":90,"props":16462,"children":16464},{"id":16463},"finden-sie-die-am-meisten-fragmentierten-dateien-auf-ihrem-system",[16465],{"type":56,"value":16466},"Finden Sie die am meisten fragmentierten Dateien auf Ihrem System",{"type":29,"tag":48,"props":16468,"children":16469},{},[16470,16472,16477],{"type":56,"value":16471},"Es gibt ein Linux-Tool namens ",{"type":29,"tag":14566,"props":16473,"children":16474},{},[16475],{"type":56,"value":16476},"filefrag",{"type":56,"value":16478},", das anzeigt, aus wie vielen Fragmenten eine Datei besteht. Also dachte ich ... \"warum nicht versuchen, die am meisten fragmentierten Dateien zu finden und nur diese zu reparieren?\" Hier ist es:",{"type":29,"tag":659,"props":16480,"children":16482},{"className":15954,"code":16481,"language":15956,"meta":7,"style":7},"find / -xdev -type f| xargs filefrag 2>/dev/null | sed 's/^\\(.*\\): \\([0-9]\\+\\) extent.*/\\2 \\1/' | awk -F ' ' '$1 > 500' | sort -n -r\n",[16483],{"type":29,"tag":672,"props":16484,"children":16485},{"__ignoreMap":7},[16486],{"type":29,"tag":127,"props":16487,"children":16488},{"class":677,"line":678},[16489,16494,16499,16504,16509,16514,16519,16524,16529,16534,16539,16544,16549,16554,16558,16563,16568,16573,16578,16582,16587,16592],{"type":29,"tag":127,"props":16490,"children":16491},{"style":3033},[16492],{"type":56,"value":16493},"find",{"type":29,"tag":127,"props":16495,"children":16496},{"style":720},[16497],{"type":56,"value":16498}," /",{"type":29,"tag":127,"props":16500,"children":16501},{"style":2303},[16502],{"type":56,"value":16503}," -xdev",{"type":29,"tag":127,"props":16505,"children":16506},{"style":2303},[16507],{"type":56,"value":16508}," -type",{"type":29,"tag":127,"props":16510,"children":16511},{"style":720},[16512],{"type":56,"value":16513}," f",{"type":29,"tag":127,"props":16515,"children":16516},{"style":4942},[16517],{"type":56,"value":16518},"|",{"type":29,"tag":127,"props":16520,"children":16521},{"style":3033},[16522],{"type":56,"value":16523}," xargs",{"type":29,"tag":127,"props":16525,"children":16526},{"style":720},[16527],{"type":56,"value":16528}," filefrag",{"type":29,"tag":127,"props":16530,"children":16531},{"style":4942},[16532],{"type":56,"value":16533}," 2>",{"type":29,"tag":127,"props":16535,"children":16536},{"style":720},[16537],{"type":56,"value":16538},"/dev/null",{"type":29,"tag":127,"props":16540,"children":16541},{"style":4942},[16542],{"type":56,"value":16543}," |",{"type":29,"tag":127,"props":16545,"children":16546},{"style":3033},[16547],{"type":56,"value":16548}," sed",{"type":29,"tag":127,"props":16550,"children":16551},{"style":720},[16552],{"type":56,"value":16553}," 's/^\\(.*\\): \\([0-9]\\+\\) extent.*/\\2 \\1/'",{"type":29,"tag":127,"props":16555,"children":16556},{"style":4942},[16557],{"type":56,"value":16543},{"type":29,"tag":127,"props":16559,"children":16560},{"style":3033},[16561],{"type":56,"value":16562}," awk",{"type":29,"tag":127,"props":16564,"children":16565},{"style":2303},[16566],{"type":56,"value":16567}," -F",{"type":29,"tag":127,"props":16569,"children":16570},{"style":720},[16571],{"type":56,"value":16572}," ' '",{"type":29,"tag":127,"props":16574,"children":16575},{"style":720},[16576],{"type":56,"value":16577}," '$1 > 500'",{"type":29,"tag":127,"props":16579,"children":16580},{"style":4942},[16581],{"type":56,"value":16543},{"type":29,"tag":127,"props":16583,"children":16584},{"style":3033},[16585],{"type":56,"value":16586}," sort",{"type":29,"tag":127,"props":16588,"children":16589},{"style":2303},[16590],{"type":56,"value":16591}," -n",{"type":29,"tag":127,"props":16593,"children":16594},{"style":2303},[16595],{"type":56,"value":16596}," -r\n",{"type":29,"tag":48,"props":16598,"children":16599},{},[16600,16602,16607,16609,16613],{"type":56,"value":16601},"Sie sollten diese Liste überprüfen. Wenn es etwas mit mehr als 10k Erstreckungen gibt, ist es ein Kandidat, um als ",{"type":29,"tag":14566,"props":16603,"children":16604},{},[16605],{"type":56,"value":16606},"nodatacow",{"type":56,"value":16608}," gekennzeichnet zu werden. In meinem Fall habe ich festgestellt, dass die Fail2ban-Sqlite-Datenbank 170k Erweiterungen verwendet, was sehr viel ist! Wenn Sie Datenbankdateien mit einer hohen Fragmentierung haben, während Sie ",{"type":29,"tag":14566,"props":16610,"children":16611},{},[16612],{"type":56,"value":16606},{"type":56,"value":16614}," verwenden, ist es besser, eine \"optimize table\" auf ihnen laufen zu lassen, da dies auch die datenbankbezogene Fragmentierung von häufig neu geschriebenen Tabellen bereinigt. Wenn Sie Snapshots verwenden, stellen Sie sicher, dass Sie etwas freien Speicherplatz haben, da die Defragmentierung eine Kopie der Dateien an Ort und Stelle erstellt, während Snapshots die Freigabe der alten Version blockieren.",{"type":29,"tag":90,"props":16616,"children":16618},{"id":16617},"wenn-alles-in-ordnung-ist-können-sie-fortfahren-und-alle-dateien-in-dieser-liste-defragmentieren",[16619],{"type":56,"value":16620},"Wenn alles in Ordnung ist, können Sie fortfahren und alle Dateien in dieser Liste defragmentieren",{"type":29,"tag":659,"props":16622,"children":16624},{"className":15954,"code":16623,"language":15956,"meta":7,"style":7},"find / -xdev -type f| xargs filefrag 2>/dev/null | sed 's/^\\(.*\\): \\([0-9]\\+\\) extent.*/\\2 \\1/' |\nawk -F ' ' '$1 > 500' | cut -d ' ' -f2 2>/dev/null | xargs -r btrfs fi defrag -f -v\n",[16625],{"type":29,"tag":672,"props":16626,"children":16627},{"__ignoreMap":7},[16628,16688],{"type":29,"tag":127,"props":16629,"children":16630},{"class":677,"line":678},[16631,16635,16639,16643,16647,16651,16655,16659,16663,16667,16671,16675,16679,16683],{"type":29,"tag":127,"props":16632,"children":16633},{"style":3033},[16634],{"type":56,"value":16493},{"type":29,"tag":127,"props":16636,"children":16637},{"style":720},[16638],{"type":56,"value":16498},{"type":29,"tag":127,"props":16640,"children":16641},{"style":2303},[16642],{"type":56,"value":16503},{"type":29,"tag":127,"props":16644,"children":16645},{"style":2303},[16646],{"type":56,"value":16508},{"type":29,"tag":127,"props":16648,"children":16649},{"style":720},[16650],{"type":56,"value":16513},{"type":29,"tag":127,"props":16652,"children":16653},{"style":4942},[16654],{"type":56,"value":16518},{"type":29,"tag":127,"props":16656,"children":16657},{"style":3033},[16658],{"type":56,"value":16523},{"type":29,"tag":127,"props":16660,"children":16661},{"style":720},[16662],{"type":56,"value":16528},{"type":29,"tag":127,"props":16664,"children":16665},{"style":4942},[16666],{"type":56,"value":16533},{"type":29,"tag":127,"props":16668,"children":16669},{"style":720},[16670],{"type":56,"value":16538},{"type":29,"tag":127,"props":16672,"children":16673},{"style":4942},[16674],{"type":56,"value":16543},{"type":29,"tag":127,"props":16676,"children":16677},{"style":3033},[16678],{"type":56,"value":16548},{"type":29,"tag":127,"props":16680,"children":16681},{"style":720},[16682],{"type":56,"value":16553},{"type":29,"tag":127,"props":16684,"children":16685},{"style":4942},[16686],{"type":56,"value":16687}," |\n",{"type":29,"tag":127,"props":16689,"children":16690},{"class":677,"line":342},[16691,16696,16700,16704,16708,16712,16717,16722,16726,16731,16735,16739,16743,16747,16752,16757,16762,16767,16772],{"type":29,"tag":127,"props":16692,"children":16693},{"style":3033},[16694],{"type":56,"value":16695},"awk",{"type":29,"tag":127,"props":16697,"children":16698},{"style":2303},[16699],{"type":56,"value":16567},{"type":29,"tag":127,"props":16701,"children":16702},{"style":720},[16703],{"type":56,"value":16572},{"type":29,"tag":127,"props":16705,"children":16706},{"style":720},[16707],{"type":56,"value":16577},{"type":29,"tag":127,"props":16709,"children":16710},{"style":4942},[16711],{"type":56,"value":16543},{"type":29,"tag":127,"props":16713,"children":16714},{"style":3033},[16715],{"type":56,"value":16716}," cut",{"type":29,"tag":127,"props":16718,"children":16719},{"style":2303},[16720],{"type":56,"value":16721}," -d",{"type":29,"tag":127,"props":16723,"children":16724},{"style":720},[16725],{"type":56,"value":16572},{"type":29,"tag":127,"props":16727,"children":16728},{"style":2303},[16729],{"type":56,"value":16730}," -f2",{"type":29,"tag":127,"props":16732,"children":16733},{"style":4942},[16734],{"type":56,"value":16533},{"type":29,"tag":127,"props":16736,"children":16737},{"style":720},[16738],{"type":56,"value":16538},{"type":29,"tag":127,"props":16740,"children":16741},{"style":4942},[16742],{"type":56,"value":16543},{"type":29,"tag":127,"props":16744,"children":16745},{"style":3033},[16746],{"type":56,"value":16523},{"type":29,"tag":127,"props":16748,"children":16749},{"style":2303},[16750],{"type":56,"value":16751}," -r",{"type":29,"tag":127,"props":16753,"children":16754},{"style":720},[16755],{"type":56,"value":16756}," btrfs",{"type":29,"tag":127,"props":16758,"children":16759},{"style":720},[16760],{"type":56,"value":16761}," fi",{"type":29,"tag":127,"props":16763,"children":16764},{"style":720},[16765],{"type":56,"value":16766}," defrag",{"type":29,"tag":127,"props":16768,"children":16769},{"style":2303},[16770],{"type":56,"value":16771}," -f",{"type":29,"tag":127,"props":16773,"children":16774},{"style":2303},[16775],{"type":56,"value":16776}," -v\n",{"type":29,"tag":48,"props":16778,"children":16779},{},[16780],{"type":56,"value":16781},"Dies gibt alle Dateinamen aus, die verarbeitet wurden.",{"type":29,"tag":90,"props":16783,"children":16785},{"id":16784},"eine-kurze-erklärung-des-befehls",[16786],{"type":56,"value":16787},"Eine kurze Erklärung des Befehls",{"type":29,"tag":48,"props":16789,"children":16790},{},[16791,16795,16797,16802,16804,16808,16810,16815,16817,16822],{"type":29,"tag":14566,"props":16792,"children":16793},{},[16794],{"type":56,"value":16493},{"type":56,"value":16796}," ermittelt alle Dateien auf dem angegebenen Pfad (/), ohne in andere eingehängte Dateisysteme zu gehen (-xdev). Dann bestimmt filefrag die Fragmentierung, der Befehl ",{"type":29,"tag":14566,"props":16798,"children":16799},{},[16800],{"type":56,"value":16801},"sed",{"type":56,"value":16803}," formatiert die Ausgabe so um, dass die Anzahl der Erweiterungen an erster Stelle steht, gefolgt vom Dateinamen. Dann analysiert ",{"type":29,"tag":14566,"props":16805,"children":16806},{},[16807],{"type":56,"value":16695},{"type":56,"value":16809}," diese Liste und filtert nur Dateien, die mehr als 500 Erweiterungen haben. Danach wird die Ausgabe so \"geschnitten\", dass sie nur die Dateinamen enthält, und an ",{"type":29,"tag":14566,"props":16811,"children":16812},{},[16813],{"type":56,"value":16814},"btrfs defrag",{"type":56,"value":16816}," zur Defragmentierung übergeben. Die Option ",{"type":29,"tag":14566,"props":16818,"children":16819},{},[16820],{"type":56,"value":16821},"-v",{"type":56,"value":16823}," des Defrag-Befehls gibt alle verarbeiteten Dateien aus. Werfen Sie auch einen Blick auf die langfristige IO-Nutzung vor und nach der Defragmentierung, um zu sehen, wie groß der Unterschied in der realen Welt ist.",{"type":29,"tag":90,"props":16825,"children":16827},{"id":16826},"viel-spaß",[16828],{"type":56,"value":16829},"Viel Spaß!",{"type":29,"tag":1838,"props":16831,"children":16832},{},[16833],{"type":56,"value":1842},{"title":7,"searchDepth":342,"depth":342,"links":16835},[16836,16837,16838,16839,16840,16841,16842,16843],{"id":16373,"depth":342,"text":16376},{"id":16391,"depth":342,"text":16394},{"id":16402,"depth":342,"text":16405},{"id":16452,"depth":342,"text":16455},{"id":16463,"depth":342,"text":16466},{"id":16617,"depth":342,"text":16620},{"id":16784,"depth":342,"text":16787},{"id":16826,"depth":342,"text":16829},{"_path":16845,"_dir":354,"_draft":6,"_partial":6,"_locale":7,"slug":518,"teams":16846,"primaryTeam":357,"firstName":16848,"lastName":16849,"prefixTitle":7,"suffixTitle":16850,"education":16851,"role":16856,"workingSince":16857,"inTheCompanySince":16858,"techSkills":16859,"skills":16882,"projects":16895,"contactDetails":16904,"_image":16907,"image":16908,"_id":16909,"_type":454,"title":16910,"_source":354,"_file":16911,"_stem":16912,"_extension":454},"/employees/robert-juzak",[16847,357],"appDev","Robert","Juzak","B.Sc.",[16852],[16853,16854,16855],"Bachelor of Computer Science","Technische Universität Breslau","2016",[371,471,370,373],"2015","2018",[16860,16861,16862,16865,16868,16871,16872,16875,16876,16877,16878,16879,16880],{"name":378,"level":379,"icon":380},{"name":9707,"level":379},{"name":16863,"level":379,"icon":16864},"Kubernetes","/images/Kubernetes.svg",{"name":16866,"level":379,"icon":16867},"PHPUnit","/images/PHP-Unit.svg",{"name":16869,"level":379,"icon":16870},"Portainer","/images/Portainer.svg",{"name":14660,"level":379},{"name":16873,"level":379,"icon":16874},"Sonarqube","/images/Sonarqube.svg",{"name":382,"level":379,"icon":383},{"name":411,"level":405,"icon":412},{"name":414,"level":405,"icon":415},{"name":395,"level":405},{"name":401,"level":405,"icon":402},{"name":16881,"level":405,"icon":421},"VueJS",[16883,16884,16885,16886,16888,16890,16892,16893,16894],{"name":5277,"level":379},{"name":433,"level":379},{"name":357,"level":379},{"name":16887,"level":379},"testDrivenBugfix",{"name":16889,"level":379},"testDrivenDevelopment",{"name":16891,"level":405},"accessibility",{"name":23,"level":405},{"name":429,"level":405},{"name":431,"level":405},[16896,16900,16902],{"project":439,"position":16897},[16898,16899],"Dev-Ops","Frontend Developer",{"project":16901,"position":16899},"Huawei-Calibration-aaS",{"project":16903,"position":16899},"Huawei-Inspect-3D",{"eMail":16905,"phone":16906,"visibility":450},"robert.juzak@helmundwalter.de","+49 351 799 035 26","images/employees/Portraits/robert_juzak.webp","images/employees/Portraits/RobertJuzak_MS.webp","employees:employees:6.robert-juzak.json","Robert Juzak","employees/6.robert-juzak.json","employees/6.robert-juzak",{"_path":16914,"_dir":354,"_draft":6,"_partial":6,"_locale":7,"slug":601,"teams":16915,"primaryTeam":16847,"firstName":16916,"lastName":16917,"prefixTitle":16918,"suffixTitle":7,"executiveRole":16919,"education":16920,"role":16927,"workingSince":364,"inTheCompanySince":16924,"techSkills":16929,"skills":16947,"projects":16958,"contactDetails":16962,"certifications":16965,"image":16971,"_id":16972,"_type":454,"title":16973,"_source":354,"_file":16974,"_stem":16975,"_extension":454},"/employees/jens-bornschein",[16847],"Jens","Bornschein","Dr. Ing.","Projektmanager | Consultant",[16921,16925],[16922,16923,16924],"Doktor-Ingenieur der Informatik","TU Dresden","2020",[16926,16923,364],"Diplom-Medieninformatiker (TU)",[470,371,471,16928,16891,373],"UI/UX",[16930,16931,16932,16933,16934,16935,16936,16939,16942,16945],{"name":395,"level":379},{"name":408,"level":379,"icon":409},{"name":411,"level":405,"icon":412},{"name":414,"level":405,"icon":415},{"name":420,"level":405,"icon":421},{"name":397,"level":405},{"name":16937,"level":379,"icon":16938},"Adobe Photoshop","/images/adobeps-logo.svg",{"name":16940,"level":379,"icon":16941},"Adobe Illustrator","/images/adobeai-logo.svg",{"name":16943,"level":405,"icon":16944},"Adobe XD","/images/adobexd-logo.svg",{"name":16946,"level":405},"Gitlab",[16948,16949,16950,16951,16953,16955,16956],{"name":483,"level":379},{"name":16891,"level":379},{"name":16928,"level":379},{"name":16952,"level":405},"consulting",{"name":16954,"level":405},"scrum",{"name":431,"level":405},{"name":16957,"level":405},"training",[16959,16961],{"project":441,"position":16960},"project manager",{"project":446,"position":16960},{"eMail":16963,"phone":16964,"visibility":450},"jens.bornschein@helmundwalter.de","+49 351 799 035 24",[16966],{"image":16967,"link":16968,"title":16969,"pdf":16970},"/images/certifications/KHZG_Badge.svg","https://www.bundesamtsozialesicherung.de/de/themen/innovationsfonds-und-krankenhausstrukturfonds/krankenhausstrukturfonds/","Berechtigung nach § 21 Absatz 5 Satz 1 KHSFV - Management für KHZG geförderte Vorhaben","/certificates/jb_KHSFV_Zertifikat.pdf","images/employees/Portraits/JensBornschein_MS.webp","employees:employees:5.jens-bornschein.json","Jens Bornschein","employees/5.jens-bornschein.json","employees/5.jens-bornschein",{"_path":353,"_dir":354,"_draft":6,"_partial":6,"_locale":7,"slug":170,"teams":16977,"primaryTeam":357,"firstName":358,"lastName":359,"prefixTitle":7,"suffixTitle":7,"education":16978,"executiveRole":365,"role":16980,"workingSince":374,"inTheCompanySince":375,"techSkills":16981,"skills":16998,"projects":17005,"contactDetails":17011,"_image":451,"image":452,"_id":453,"_type":454,"title":455,"_source":354,"_file":456,"_stem":457,"_extension":454},[356,357],[16979],[362,363,364],[367,368,357,369,370,371,372,373],[16982,16983,16984,16985,16986,16987,16988,16989,16990,16991,16992,16993,16994,16995,16996,16997],{"name":378,"level":379,"icon":380},{"name":382,"level":379,"icon":383},{"name":385,"level":379},{"name":387,"level":379,"icon":388},{"name":390,"level":379},{"name":392,"level":379,"icon":393},{"name":395,"level":379},{"name":397,"level":379},{"name":399,"level":379},{"name":401,"level":379,"icon":402},{"name":404,"level":405,"icon":406},{"name":408,"level":405,"icon":409},{"name":411,"level":405,"icon":412},{"name":414,"level":405,"icon":415},{"name":417,"level":405,"icon":418},{"name":420,"level":405,"icon":421},[16999,17000,17001,17002,17003,17004],{"name":424,"level":379},{"name":426,"level":379},{"name":23,"level":379},{"name":429,"level":379},{"name":431,"level":379},{"name":433,"level":405},[17006,17007,17008,17009,17010],{"project":436,"position":437},{"project":439,"position":437},{"project":441,"position":437},{"project":443,"position":444},{"project":446,"position":437},{"eMail":448,"phone":449,"visibility":450},1782284050675]