[{"data":1,"prerenderedAt":7324},["ShallowReactive",2],{"blog-current-shopware-plugin-gitlab-pipeline-release-en":3,"blog-previous-shopware-plugin-gitlab-pipeline-release-en":4485,"blog-next-shopware-plugin-gitlab-pipeline-release-en":4496,"blog-alt-de-shopware-plugin-gitlab-pipeline-release-en":4507,"blog-alt-en-shopware-plugin-gitlab-pipeline-release-en":4509,"employee-robert-juzak":4510,"content-query-TPh1lFGN9c":4607,"content-query-GCsGFnjSrZ":6086,"content-query-KtO3wftRle":7239,"related-refs-shopware_devops--en":7274},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"author":10,"image":11,"releaseDate":12,"blogCategories":13,"articleTags":16,"tags":19,"body":22,"_type":4479,"_id":4480,"_source":4481,"_file":4482,"_stem":4483,"_extension":4484},"/en/blog/shopware-plugin-gitlab-pipeline-release","blog",false,"","Test, build and release a Shopware 6 Plugin with GitLab CI - Part 1: release","Part 1 - release - of using GitLab for testing, building and releasing a Shopware 6 Plugin","robert-juzak","/images/dev-ops-dark.svg","2026-02-26",[14,15],"What moves us","DevOps",[15,17,18],"Open Source","Shopware",[20,21],"shopware","devops",{"type":23,"children":24,"toc":4467},"root",[25,34,41,55,60,65,104,109,116,121,128,140,1226,1231,1259,1269,1273,1286,1309,1446,1459,1464,1470,1482,1502,1904,1945,1950,1971,2113,2125,2131,2142,2147,2159,2194,2199,3126,3131,3230,3235,3294,3305,3310,3331,3466,3476,3482,3503,3506,3510,3516,3522,3527,3543,3593,3753,3759,3764,3775,3788,4011,4416,4421,4461],{"type":26,"tag":27,"props":28,"children":33},"element","img",{"alt":7,"aspect-ratio":29,"height":30,"object-fit":31,"src":32},"1.78",300,"fill","/blog/shopware-plugin-release.png",[],{"type":26,"tag":35,"props":36,"children":37},"p",{},[38],{"type":39,"value":40},"text","There are many ways to install Shopware 6 plugins. You can download them directly in the admin panel or install them with composer.",{"type":26,"tag":35,"props":42,"children":43},{},[44,46,53],{"type":39,"value":45},"There is a detailed comparison in the ",{"type":26,"tag":47,"props":48,"children":50},"a",{"href":49},"https://developer.shopware.com/docs/guides/plugins/plugins/",[51],{"type":39,"value":52},"official documentation",{"type":39,"value":54},".",{"type":26,"tag":35,"props":56,"children":57},{},[58],{"type":39,"value":59},"As a developer and maintainer of themes, customizations, third part API's, etc., I'm focused on Static Plugins.",{"type":26,"tag":35,"props":61,"children":62},{},[63],{"type":39,"value":64},"The workflow is simple:",{"type":26,"tag":66,"props":67,"children":68},"ol",{},[69,82,93],{"type":26,"tag":70,"props":71,"children":72},"li",{},[73,75],{"type":39,"value":74},"Create a plugin with ",{"type":26,"tag":76,"props":77,"children":79},"code",{"className":78},[],[80],{"type":39,"value":81},"bin/console plugin:create --static",{"type":26,"tag":70,"props":83,"children":84},{},[85,87],{"type":39,"value":86},"Require it with ",{"type":26,"tag":47,"props":88,"children":90},{"href":89},"https://developer.shopware.com/docs/guides/plugins/plugins/#static-plugins",[91],{"type":39,"value":92},"composer",{"type":26,"tag":70,"props":94,"children":95},{},[96,98],{"type":39,"value":97},"Build the project with ",{"type":26,"tag":47,"props":99,"children":101},{"href":100},"https://developer.shopware.com/docs/products/cli/project-commands/build.html#example-docker-image",[102],{"type":39,"value":103},"shopware-cli",{"type":26,"tag":35,"props":105,"children":106},{},[107],{"type":39,"value":108},"When we need the same plugin in more than one shop, we could create the same plugin more than ones,\nbut this wouldn't be great for maintenance.",{"type":26,"tag":110,"props":111,"children":113},"h2",{"id":112},"extracting-the-plugin",[114],{"type":39,"value":115},"Extracting the plugin",{"type":26,"tag":35,"props":117,"children":118},{},[119],{"type":39,"value":120},"Let's move the source code of our plugin to a separate repository. To make things easier for now, we make the repository public.",{"type":26,"tag":122,"props":123,"children":125},"h3",{"id":124},"download-with-git",[126],{"type":39,"value":127},"Download with git",{"type":26,"tag":35,"props":129,"children":130},{},[131,133,138],{"type":39,"value":132},"We just need to tell ",{"type":26,"tag":76,"props":134,"children":136},{"className":135},[],[137],{"type":39,"value":92},{"type":39,"value":139}," where to find our plugin",{"type":26,"tag":141,"props":142,"children":152},"pre",{"className":143,"code":144,"filename":145,"highlights":146,"language":151,"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",[147,148,149,150],36,37,38,39,"json",[153],{"type":26,"tag":76,"props":154,"children":155},{"__ignoreMap":7},[156,168,194,216,238,252,274,296,318,340,361,382,400,409,423,432,454,476,489,508,517,526,534,554,575,587,603,611,619,627,647,668,680,696,704,712,721,742,759,768,777,790,803,832,840,848,870,883,896,917,934,942,963,980,988,1001,1014,1032,1040,1053,1062,1071,1084,1092,1101,1109,1122,1135,1156,1169,1182,1191,1200,1208,1217],{"type":26,"tag":157,"props":158,"children":161},"span",{"class":159,"line":160},"line",1,[162],{"type":26,"tag":157,"props":163,"children":165},{"style":164},"--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2",[166],{"type":39,"value":167},"{\n",{"type":26,"tag":157,"props":169,"children":171},{"class":159,"line":170},2,[172,178,183,189],{"type":26,"tag":157,"props":173,"children":175},{"style":174},"--shiki-default:#79B8FF;--shiki-default-font-style:inherit;--shiki-dark:#79B8FF;--shiki-dark-font-style:inherit;--shiki-sepia:#66D9EF;--shiki-sepia-font-style:italic",[176],{"type":39,"value":177},"  \"name\"",{"type":26,"tag":157,"props":179,"children":180},{"style":164},[181],{"type":39,"value":182},": ",{"type":26,"tag":157,"props":184,"children":186},{"style":185},"--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#CFCFC2",[187],{"type":39,"value":188},"\"shopware/production\"",{"type":26,"tag":157,"props":190,"children":191},{"style":164},[192],{"type":39,"value":193},",\n",{"type":26,"tag":157,"props":195,"children":197},{"class":159,"line":196},3,[198,203,207,212],{"type":26,"tag":157,"props":199,"children":200},{"style":174},[201],{"type":39,"value":202},"  \"license\"",{"type":26,"tag":157,"props":204,"children":205},{"style":164},[206],{"type":39,"value":182},{"type":26,"tag":157,"props":208,"children":209},{"style":185},[210],{"type":39,"value":211},"\"MIT\"",{"type":26,"tag":157,"props":213,"children":214},{"style":164},[215],{"type":39,"value":193},{"type":26,"tag":157,"props":217,"children":219},{"class":159,"line":218},4,[220,225,229,234],{"type":26,"tag":157,"props":221,"children":222},{"style":174},[223],{"type":39,"value":224},"  \"type\"",{"type":26,"tag":157,"props":226,"children":227},{"style":164},[228],{"type":39,"value":182},{"type":26,"tag":157,"props":230,"children":231},{"style":185},[232],{"type":39,"value":233},"\"project\"",{"type":26,"tag":157,"props":235,"children":236},{"style":164},[237],{"type":39,"value":193},{"type":26,"tag":157,"props":239,"children":241},{"class":159,"line":240},5,[242,247],{"type":26,"tag":157,"props":243,"children":244},{"style":174},[245],{"type":39,"value":246},"  \"require\"",{"type":26,"tag":157,"props":248,"children":249},{"style":164},[250],{"type":39,"value":251},": {\n",{"type":26,"tag":157,"props":253,"children":255},{"class":159,"line":254},6,[256,261,265,270],{"type":26,"tag":157,"props":257,"children":258},{"style":174},[259],{"type":39,"value":260},"    \"composer-runtime-api\"",{"type":26,"tag":157,"props":262,"children":263},{"style":164},[264],{"type":39,"value":182},{"type":26,"tag":157,"props":266,"children":267},{"style":185},[268],{"type":39,"value":269},"\"^2.0\"",{"type":26,"tag":157,"props":271,"children":272},{"style":164},[273],{"type":39,"value":193},{"type":26,"tag":157,"props":275,"children":277},{"class":159,"line":276},7,[278,283,287,292],{"type":26,"tag":157,"props":279,"children":280},{"style":174},[281],{"type":39,"value":282},"    \"acme/sample-plugin\"",{"type":26,"tag":157,"props":284,"children":285},{"style":164},[286],{"type":39,"value":182},{"type":26,"tag":157,"props":288,"children":289},{"style":185},[290],{"type":39,"value":291},"\"^1.0\"",{"type":26,"tag":157,"props":293,"children":294},{"style":164},[295],{"type":39,"value":193},{"type":26,"tag":157,"props":297,"children":299},{"class":159,"line":298},8,[300,305,309,314],{"type":26,"tag":157,"props":301,"children":302},{"style":174},[303],{"type":39,"value":304},"    \"shopware/administration\"",{"type":26,"tag":157,"props":306,"children":307},{"style":164},[308],{"type":39,"value":182},{"type":26,"tag":157,"props":310,"children":311},{"style":185},[312],{"type":39,"value":313},"\"*\"",{"type":26,"tag":157,"props":315,"children":316},{"style":164},[317],{"type":39,"value":193},{"type":26,"tag":157,"props":319,"children":321},{"class":159,"line":320},9,[322,327,331,336],{"type":26,"tag":157,"props":323,"children":324},{"style":174},[325],{"type":39,"value":326},"    \"shopware/core\"",{"type":26,"tag":157,"props":328,"children":329},{"style":164},[330],{"type":39,"value":182},{"type":26,"tag":157,"props":332,"children":333},{"style":185},[334],{"type":39,"value":335},"\"6.6.10.2\"",{"type":26,"tag":157,"props":337,"children":338},{"style":164},[339],{"type":39,"value":193},{"type":26,"tag":157,"props":341,"children":343},{"class":159,"line":342},10,[344,349,353,357],{"type":26,"tag":157,"props":345,"children":346},{"style":174},[347],{"type":39,"value":348},"    \"shopware/elasticsearch\"",{"type":26,"tag":157,"props":350,"children":351},{"style":164},[352],{"type":39,"value":182},{"type":26,"tag":157,"props":354,"children":355},{"style":185},[356],{"type":39,"value":313},{"type":26,"tag":157,"props":358,"children":359},{"style":164},[360],{"type":39,"value":193},{"type":26,"tag":157,"props":362,"children":364},{"class":159,"line":363},11,[365,370,374,378],{"type":26,"tag":157,"props":366,"children":367},{"style":174},[368],{"type":39,"value":369},"    \"shopware/storefront\"",{"type":26,"tag":157,"props":371,"children":372},{"style":164},[373],{"type":39,"value":182},{"type":26,"tag":157,"props":375,"children":376},{"style":185},[377],{"type":39,"value":313},{"type":26,"tag":157,"props":379,"children":380},{"style":164},[381],{"type":39,"value":193},{"type":26,"tag":157,"props":383,"children":385},{"class":159,"line":384},12,[386,391,395],{"type":26,"tag":157,"props":387,"children":388},{"style":174},[389],{"type":39,"value":390},"    \"symfony/flex\"",{"type":26,"tag":157,"props":392,"children":393},{"style":164},[394],{"type":39,"value":182},{"type":26,"tag":157,"props":396,"children":397},{"style":185},[398],{"type":39,"value":399},"\"~2\"\n",{"type":26,"tag":157,"props":401,"children":403},{"class":159,"line":402},13,[404],{"type":26,"tag":157,"props":405,"children":406},{"style":164},[407],{"type":39,"value":408},"  },\n",{"type":26,"tag":157,"props":410,"children":412},{"class":159,"line":411},14,[413,418],{"type":26,"tag":157,"props":414,"children":415},{"style":174},[416],{"type":39,"value":417},"  \"repositories\"",{"type":26,"tag":157,"props":419,"children":420},{"style":164},[421],{"type":39,"value":422},": [\n",{"type":26,"tag":157,"props":424,"children":426},{"class":159,"line":425},15,[427],{"type":26,"tag":157,"props":428,"children":429},{"style":164},[430],{"type":39,"value":431},"    {\n",{"type":26,"tag":157,"props":433,"children":435},{"class":159,"line":434},16,[436,441,445,450],{"type":26,"tag":157,"props":437,"children":438},{"style":174},[439],{"type":39,"value":440},"      \"type\"",{"type":26,"tag":157,"props":442,"children":443},{"style":164},[444],{"type":39,"value":182},{"type":26,"tag":157,"props":446,"children":447},{"style":185},[448],{"type":39,"value":449},"\"path\"",{"type":26,"tag":157,"props":451,"children":452},{"style":164},[453],{"type":39,"value":193},{"type":26,"tag":157,"props":455,"children":457},{"class":159,"line":456},17,[458,463,467,472],{"type":26,"tag":157,"props":459,"children":460},{"style":174},[461],{"type":39,"value":462},"      \"url\"",{"type":26,"tag":157,"props":464,"children":465},{"style":164},[466],{"type":39,"value":182},{"type":26,"tag":157,"props":468,"children":469},{"style":185},[470],{"type":39,"value":471},"\"custom/plugins/*\"",{"type":26,"tag":157,"props":473,"children":474},{"style":164},[475],{"type":39,"value":193},{"type":26,"tag":157,"props":477,"children":479},{"class":159,"line":478},18,[480,485],{"type":26,"tag":157,"props":481,"children":482},{"style":174},[483],{"type":39,"value":484},"      \"options\"",{"type":26,"tag":157,"props":486,"children":487},{"style":164},[488],{"type":39,"value":251},{"type":26,"tag":157,"props":490,"children":492},{"class":159,"line":491},19,[493,498,502],{"type":26,"tag":157,"props":494,"children":495},{"style":174},[496],{"type":39,"value":497},"        \"symlink\"",{"type":26,"tag":157,"props":499,"children":500},{"style":164},[501],{"type":39,"value":182},{"type":26,"tag":157,"props":503,"children":505},{"style":504},"--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF",[506],{"type":39,"value":507},"true\n",{"type":26,"tag":157,"props":509,"children":511},{"class":159,"line":510},20,[512],{"type":26,"tag":157,"props":513,"children":514},{"style":164},[515],{"type":39,"value":516},"      }\n",{"type":26,"tag":157,"props":518,"children":520},{"class":159,"line":519},21,[521],{"type":26,"tag":157,"props":522,"children":523},{"style":164},[524],{"type":39,"value":525},"    },\n",{"type":26,"tag":157,"props":527,"children":529},{"class":159,"line":528},22,[530],{"type":26,"tag":157,"props":531,"children":532},{"style":164},[533],{"type":39,"value":431},{"type":26,"tag":157,"props":535,"children":537},{"class":159,"line":536},23,[538,542,546,550],{"type":26,"tag":157,"props":539,"children":540},{"style":174},[541],{"type":39,"value":440},{"type":26,"tag":157,"props":543,"children":544},{"style":164},[545],{"type":39,"value":182},{"type":26,"tag":157,"props":547,"children":548},{"style":185},[549],{"type":39,"value":449},{"type":26,"tag":157,"props":551,"children":552},{"style":164},[553],{"type":39,"value":193},{"type":26,"tag":157,"props":555,"children":557},{"class":159,"line":556},24,[558,562,566,571],{"type":26,"tag":157,"props":559,"children":560},{"style":174},[561],{"type":39,"value":462},{"type":26,"tag":157,"props":563,"children":564},{"style":164},[565],{"type":39,"value":182},{"type":26,"tag":157,"props":567,"children":568},{"style":185},[569],{"type":39,"value":570},"\"custom/plugins/*/packages/*\"",{"type":26,"tag":157,"props":572,"children":573},{"style":164},[574],{"type":39,"value":193},{"type":26,"tag":157,"props":576,"children":578},{"class":159,"line":577},25,[579,583],{"type":26,"tag":157,"props":580,"children":581},{"style":174},[582],{"type":39,"value":484},{"type":26,"tag":157,"props":584,"children":585},{"style":164},[586],{"type":39,"value":251},{"type":26,"tag":157,"props":588,"children":590},{"class":159,"line":589},26,[591,595,599],{"type":26,"tag":157,"props":592,"children":593},{"style":174},[594],{"type":39,"value":497},{"type":26,"tag":157,"props":596,"children":597},{"style":164},[598],{"type":39,"value":182},{"type":26,"tag":157,"props":600,"children":601},{"style":504},[602],{"type":39,"value":507},{"type":26,"tag":157,"props":604,"children":606},{"class":159,"line":605},27,[607],{"type":26,"tag":157,"props":608,"children":609},{"style":164},[610],{"type":39,"value":516},{"type":26,"tag":157,"props":612,"children":614},{"class":159,"line":613},28,[615],{"type":26,"tag":157,"props":616,"children":617},{"style":164},[618],{"type":39,"value":525},{"type":26,"tag":157,"props":620,"children":622},{"class":159,"line":621},29,[623],{"type":26,"tag":157,"props":624,"children":625},{"style":164},[626],{"type":39,"value":431},{"type":26,"tag":157,"props":628,"children":630},{"class":159,"line":629},30,[631,635,639,643],{"type":26,"tag":157,"props":632,"children":633},{"style":174},[634],{"type":39,"value":440},{"type":26,"tag":157,"props":636,"children":637},{"style":164},[638],{"type":39,"value":182},{"type":26,"tag":157,"props":640,"children":641},{"style":185},[642],{"type":39,"value":449},{"type":26,"tag":157,"props":644,"children":645},{"style":164},[646],{"type":39,"value":193},{"type":26,"tag":157,"props":648,"children":650},{"class":159,"line":649},31,[651,655,659,664],{"type":26,"tag":157,"props":652,"children":653},{"style":174},[654],{"type":39,"value":462},{"type":26,"tag":157,"props":656,"children":657},{"style":164},[658],{"type":39,"value":182},{"type":26,"tag":157,"props":660,"children":661},{"style":185},[662],{"type":39,"value":663},"\"custom/static-plugins/*\"",{"type":26,"tag":157,"props":665,"children":666},{"style":164},[667],{"type":39,"value":193},{"type":26,"tag":157,"props":669,"children":671},{"class":159,"line":670},32,[672,676],{"type":26,"tag":157,"props":673,"children":674},{"style":174},[675],{"type":39,"value":484},{"type":26,"tag":157,"props":677,"children":678},{"style":164},[679],{"type":39,"value":251},{"type":26,"tag":157,"props":681,"children":683},{"class":159,"line":682},33,[684,688,692],{"type":26,"tag":157,"props":685,"children":686},{"style":174},[687],{"type":39,"value":497},{"type":26,"tag":157,"props":689,"children":690},{"style":164},[691],{"type":39,"value":182},{"type":26,"tag":157,"props":693,"children":694},{"style":504},[695],{"type":39,"value":507},{"type":26,"tag":157,"props":697,"children":699},{"class":159,"line":698},34,[700],{"type":26,"tag":157,"props":701,"children":702},{"style":164},[703],{"type":39,"value":516},{"type":26,"tag":157,"props":705,"children":707},{"class":159,"line":706},35,[708],{"type":26,"tag":157,"props":709,"children":710},{"style":164},[711],{"type":39,"value":525},{"type":26,"tag":157,"props":713,"children":716},{"class":714,"line":147},[159,715],"highlight",[717],{"type":26,"tag":157,"props":718,"children":719},{"style":164},[720],{"type":39,"value":431},{"type":26,"tag":157,"props":722,"children":724},{"class":723,"line":148},[159,715],[725,729,733,738],{"type":26,"tag":157,"props":726,"children":727},{"style":174},[728],{"type":39,"value":440},{"type":26,"tag":157,"props":730,"children":731},{"style":164},[732],{"type":39,"value":182},{"type":26,"tag":157,"props":734,"children":735},{"style":185},[736],{"type":39,"value":737},"\"git\"",{"type":26,"tag":157,"props":739,"children":740},{"style":164},[741],{"type":39,"value":193},{"type":26,"tag":157,"props":743,"children":745},{"class":744,"line":149},[159,715],[746,750,754],{"type":26,"tag":157,"props":747,"children":748},{"style":174},[749],{"type":39,"value":462},{"type":26,"tag":157,"props":751,"children":752},{"style":164},[753],{"type":39,"value":182},{"type":26,"tag":157,"props":755,"children":756},{"style":185},[757],{"type":39,"value":758},"\"https://\u003CDOMAIN-NAME>/\u003Cgroup>/\u003Crepo>.git\"\n",{"type":26,"tag":157,"props":760,"children":762},{"class":761,"line":150},[159,715],[763],{"type":26,"tag":157,"props":764,"children":765},{"style":164},[766],{"type":39,"value":767},"    }\n",{"type":26,"tag":157,"props":769,"children":771},{"class":159,"line":770},40,[772],{"type":26,"tag":157,"props":773,"children":774},{"style":164},[775],{"type":39,"value":776},"  ],\n",{"type":26,"tag":157,"props":778,"children":780},{"class":159,"line":779},41,[781,786],{"type":26,"tag":157,"props":782,"children":783},{"style":174},[784],{"type":39,"value":785},"  \"autoload\"",{"type":26,"tag":157,"props":787,"children":788},{"style":164},[789],{"type":39,"value":251},{"type":26,"tag":157,"props":791,"children":793},{"class":159,"line":792},42,[794,799],{"type":26,"tag":157,"props":795,"children":796},{"style":174},[797],{"type":39,"value":798},"    \"psr-4\"",{"type":26,"tag":157,"props":800,"children":801},{"style":164},[802],{"type":39,"value":251},{"type":26,"tag":157,"props":804,"children":806},{"class":159,"line":805},43,[807,812,818,823,827],{"type":26,"tag":157,"props":808,"children":809},{"style":174},[810],{"type":39,"value":811},"      \"App",{"type":26,"tag":157,"props":813,"children":815},{"style":814},"--shiki-default:#79B8FF;--shiki-default-font-style:inherit;--shiki-dark:#79B8FF;--shiki-dark-font-style:inherit;--shiki-sepia:#AE81FF;--shiki-sepia-font-style:italic",[816],{"type":39,"value":817},"\\\\",{"type":26,"tag":157,"props":819,"children":820},{"style":174},[821],{"type":39,"value":822},"\"",{"type":26,"tag":157,"props":824,"children":825},{"style":164},[826],{"type":39,"value":182},{"type":26,"tag":157,"props":828,"children":829},{"style":185},[830],{"type":39,"value":831},"\"src/\"\n",{"type":26,"tag":157,"props":833,"children":835},{"class":159,"line":834},44,[836],{"type":26,"tag":157,"props":837,"children":838},{"style":164},[839],{"type":39,"value":767},{"type":26,"tag":157,"props":841,"children":843},{"class":159,"line":842},45,[844],{"type":26,"tag":157,"props":845,"children":846},{"style":164},[847],{"type":39,"value":408},{"type":26,"tag":157,"props":849,"children":851},{"class":159,"line":850},46,[852,857,861,866],{"type":26,"tag":157,"props":853,"children":854},{"style":174},[855],{"type":39,"value":856},"  \"prefer-stable\"",{"type":26,"tag":157,"props":858,"children":859},{"style":164},[860],{"type":39,"value":182},{"type":26,"tag":157,"props":862,"children":863},{"style":504},[864],{"type":39,"value":865},"true",{"type":26,"tag":157,"props":867,"children":868},{"style":164},[869],{"type":39,"value":193},{"type":26,"tag":157,"props":871,"children":873},{"class":159,"line":872},47,[874,879],{"type":26,"tag":157,"props":875,"children":876},{"style":174},[877],{"type":39,"value":878},"  \"config\"",{"type":26,"tag":157,"props":880,"children":881},{"style":164},[882],{"type":39,"value":251},{"type":26,"tag":157,"props":884,"children":886},{"class":159,"line":885},48,[887,892],{"type":26,"tag":157,"props":888,"children":889},{"style":174},[890],{"type":39,"value":891},"    \"allow-plugins\"",{"type":26,"tag":157,"props":893,"children":894},{"style":164},[895],{"type":39,"value":251},{"type":26,"tag":157,"props":897,"children":899},{"class":159,"line":898},49,[900,905,909,913],{"type":26,"tag":157,"props":901,"children":902},{"style":174},[903],{"type":39,"value":904},"      \"symfony/flex\"",{"type":26,"tag":157,"props":906,"children":907},{"style":164},[908],{"type":39,"value":182},{"type":26,"tag":157,"props":910,"children":911},{"style":504},[912],{"type":39,"value":865},{"type":26,"tag":157,"props":914,"children":915},{"style":164},[916],{"type":39,"value":193},{"type":26,"tag":157,"props":918,"children":920},{"class":159,"line":919},50,[921,926,930],{"type":26,"tag":157,"props":922,"children":923},{"style":174},[924],{"type":39,"value":925},"      \"symfony/runtime\"",{"type":26,"tag":157,"props":927,"children":928},{"style":164},[929],{"type":39,"value":182},{"type":26,"tag":157,"props":931,"children":932},{"style":504},[933],{"type":39,"value":507},{"type":26,"tag":157,"props":935,"children":937},{"class":159,"line":936},51,[938],{"type":26,"tag":157,"props":939,"children":940},{"style":164},[941],{"type":39,"value":525},{"type":26,"tag":157,"props":943,"children":945},{"class":159,"line":944},52,[946,951,955,959],{"type":26,"tag":157,"props":947,"children":948},{"style":174},[949],{"type":39,"value":950},"    \"optimize-autoloader\"",{"type":26,"tag":157,"props":952,"children":953},{"style":164},[954],{"type":39,"value":182},{"type":26,"tag":157,"props":956,"children":957},{"style":504},[958],{"type":39,"value":865},{"type":26,"tag":157,"props":960,"children":961},{"style":164},[962],{"type":39,"value":193},{"type":26,"tag":157,"props":964,"children":966},{"class":159,"line":965},53,[967,972,976],{"type":26,"tag":157,"props":968,"children":969},{"style":174},[970],{"type":39,"value":971},"    \"sort-packages\"",{"type":26,"tag":157,"props":973,"children":974},{"style":164},[975],{"type":39,"value":182},{"type":26,"tag":157,"props":977,"children":978},{"style":504},[979],{"type":39,"value":507},{"type":26,"tag":157,"props":981,"children":983},{"class":159,"line":982},54,[984],{"type":26,"tag":157,"props":985,"children":986},{"style":164},[987],{"type":39,"value":408},{"type":26,"tag":157,"props":989,"children":991},{"class":159,"line":990},55,[992,997],{"type":26,"tag":157,"props":993,"children":994},{"style":174},[995],{"type":39,"value":996},"  \"scripts\"",{"type":26,"tag":157,"props":998,"children":999},{"style":164},[1000],{"type":39,"value":251},{"type":26,"tag":157,"props":1002,"children":1004},{"class":159,"line":1003},56,[1005,1010],{"type":26,"tag":157,"props":1006,"children":1007},{"style":174},[1008],{"type":39,"value":1009},"    \"auto-scripts\"",{"type":26,"tag":157,"props":1011,"children":1012},{"style":164},[1013],{"type":39,"value":251},{"type":26,"tag":157,"props":1015,"children":1017},{"class":159,"line":1016},57,[1018,1023,1027],{"type":26,"tag":157,"props":1019,"children":1020},{"style":174},[1021],{"type":39,"value":1022},"      \"assets:install\"",{"type":26,"tag":157,"props":1024,"children":1025},{"style":164},[1026],{"type":39,"value":182},{"type":26,"tag":157,"props":1028,"children":1029},{"style":185},[1030],{"type":39,"value":1031},"\"symfony-cmd\"\n",{"type":26,"tag":157,"props":1033,"children":1035},{"class":159,"line":1034},58,[1036],{"type":26,"tag":157,"props":1037,"children":1038},{"style":164},[1039],{"type":39,"value":525},{"type":26,"tag":157,"props":1041,"children":1043},{"class":159,"line":1042},59,[1044,1049],{"type":26,"tag":157,"props":1045,"children":1046},{"style":174},[1047],{"type":39,"value":1048},"    \"post-install-cmd\"",{"type":26,"tag":157,"props":1050,"children":1051},{"style":164},[1052],{"type":39,"value":422},{"type":26,"tag":157,"props":1054,"children":1056},{"class":159,"line":1055},60,[1057],{"type":26,"tag":157,"props":1058,"children":1059},{"style":185},[1060],{"type":39,"value":1061},"      \"@auto-scripts\"\n",{"type":26,"tag":157,"props":1063,"children":1065},{"class":159,"line":1064},61,[1066],{"type":26,"tag":157,"props":1067,"children":1068},{"style":164},[1069],{"type":39,"value":1070},"    ],\n",{"type":26,"tag":157,"props":1072,"children":1074},{"class":159,"line":1073},62,[1075,1080],{"type":26,"tag":157,"props":1076,"children":1077},{"style":174},[1078],{"type":39,"value":1079},"    \"post-update-cmd\"",{"type":26,"tag":157,"props":1081,"children":1082},{"style":164},[1083],{"type":39,"value":422},{"type":26,"tag":157,"props":1085,"children":1087},{"class":159,"line":1086},63,[1088],{"type":26,"tag":157,"props":1089,"children":1090},{"style":185},[1091],{"type":39,"value":1061},{"type":26,"tag":157,"props":1093,"children":1095},{"class":159,"line":1094},64,[1096],{"type":26,"tag":157,"props":1097,"children":1098},{"style":164},[1099],{"type":39,"value":1100},"    ]\n",{"type":26,"tag":157,"props":1102,"children":1104},{"class":159,"line":1103},65,[1105],{"type":26,"tag":157,"props":1106,"children":1107},{"style":164},[1108],{"type":39,"value":408},{"type":26,"tag":157,"props":1110,"children":1112},{"class":159,"line":1111},66,[1113,1118],{"type":26,"tag":157,"props":1114,"children":1115},{"style":174},[1116],{"type":39,"value":1117},"  \"extra\"",{"type":26,"tag":157,"props":1119,"children":1120},{"style":164},[1121],{"type":39,"value":251},{"type":26,"tag":157,"props":1123,"children":1125},{"class":159,"line":1124},67,[1126,1131],{"type":26,"tag":157,"props":1127,"children":1128},{"style":174},[1129],{"type":39,"value":1130},"    \"symfony\"",{"type":26,"tag":157,"props":1132,"children":1133},{"style":164},[1134],{"type":39,"value":251},{"type":26,"tag":157,"props":1136,"children":1138},{"class":159,"line":1137},68,[1139,1144,1148,1152],{"type":26,"tag":157,"props":1140,"children":1141},{"style":174},[1142],{"type":39,"value":1143},"      \"allow-contrib\"",{"type":26,"tag":157,"props":1145,"children":1146},{"style":164},[1147],{"type":39,"value":182},{"type":26,"tag":157,"props":1149,"children":1150},{"style":504},[1151],{"type":39,"value":865},{"type":26,"tag":157,"props":1153,"children":1154},{"style":164},[1155],{"type":39,"value":193},{"type":26,"tag":157,"props":1157,"children":1159},{"class":159,"line":1158},69,[1160,1165],{"type":26,"tag":157,"props":1161,"children":1162},{"style":174},[1163],{"type":39,"value":1164},"      \"endpoint\"",{"type":26,"tag":157,"props":1166,"children":1167},{"style":164},[1168],{"type":39,"value":422},{"type":26,"tag":157,"props":1170,"children":1172},{"class":159,"line":1171},70,[1173,1178],{"type":26,"tag":157,"props":1174,"children":1175},{"style":185},[1176],{"type":39,"value":1177},"        \"https://raw.githubusercontent.com/shopware/recipes/flex/main/index.json\"",{"type":26,"tag":157,"props":1179,"children":1180},{"style":164},[1181],{"type":39,"value":193},{"type":26,"tag":157,"props":1183,"children":1185},{"class":159,"line":1184},71,[1186],{"type":26,"tag":157,"props":1187,"children":1188},{"style":185},[1189],{"type":39,"value":1190},"        \"flex://defaults\"\n",{"type":26,"tag":157,"props":1192,"children":1194},{"class":159,"line":1193},72,[1195],{"type":26,"tag":157,"props":1196,"children":1197},{"style":164},[1198],{"type":39,"value":1199},"      ]\n",{"type":26,"tag":157,"props":1201,"children":1203},{"class":159,"line":1202},73,[1204],{"type":26,"tag":157,"props":1205,"children":1206},{"style":164},[1207],{"type":39,"value":767},{"type":26,"tag":157,"props":1209,"children":1211},{"class":159,"line":1210},74,[1212],{"type":26,"tag":157,"props":1213,"children":1214},{"style":164},[1215],{"type":39,"value":1216},"  }\n",{"type":26,"tag":157,"props":1218,"children":1220},{"class":159,"line":1219},75,[1221],{"type":26,"tag":157,"props":1222,"children":1223},{"style":164},[1224],{"type":39,"value":1225},"}\n",{"type":26,"tag":35,"props":1227,"children":1228},{},[1229],{"type":39,"value":1230},"and require it with",{"type":26,"tag":141,"props":1232,"children":1236},{"className":1233,"code":1234,"language":1235,"meta":7,"style":7},"language-shell shiki shiki-themes github-dark github-dark monokai","composer req acme/sample-plugin\n","shell",[1237],{"type":26,"tag":76,"props":1238,"children":1239},{"__ignoreMap":7},[1240],{"type":26,"tag":157,"props":1241,"children":1242},{"class":159,"line":160},[1243,1248,1254],{"type":26,"tag":157,"props":1244,"children":1246},{"style":1245},"--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E",[1247],{"type":39,"value":92},{"type":26,"tag":157,"props":1249,"children":1251},{"style":1250},"--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74",[1252],{"type":39,"value":1253}," req",{"type":26,"tag":157,"props":1255,"children":1256},{"style":1250},[1257],{"type":39,"value":1258}," acme/sample-plugin\n",{"type":26,"tag":1260,"props":1261,"children":1263},"v-alert",{"type":1262},"error",[1264],{"type":26,"tag":35,"props":1265,"children":1266},{},[1267],{"type":39,"value":1268},"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":26,"tag":1270,"props":1271,"children":1272},"br",{},[],{"type":26,"tag":35,"props":1274,"children":1275},{},[1276,1278,1284],{"type":39,"value":1277},"Yes... this is the downside. We need to use ",{"type":26,"tag":76,"props":1279,"children":1281},{"className":1280},[],[1282],{"type":39,"value":1283},"dev-master",{"type":39,"value":1285}," as a version",{"type":26,"tag":141,"props":1287,"children":1289},{"className":1233,"code":1288,"language":1235,"meta":7,"style":7},"composer req acme/sample-plugin:dev-master\n",[1290],{"type":26,"tag":76,"props":1291,"children":1292},{"__ignoreMap":7},[1293],{"type":26,"tag":157,"props":1294,"children":1295},{"class":159,"line":160},[1296,1300,1304],{"type":26,"tag":157,"props":1297,"children":1298},{"style":1245},[1299],{"type":39,"value":92},{"type":26,"tag":157,"props":1301,"children":1302},{"style":1250},[1303],{"type":39,"value":1253},{"type":26,"tag":157,"props":1305,"children":1306},{"style":1250},[1307],{"type":39,"value":1308}," acme/sample-plugin:dev-master\n",{"type":26,"tag":141,"props":1310,"children":1314},{"className":1311,"code":1312,"language":1313,"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",[1315],{"type":26,"tag":76,"props":1316,"children":1317},{"__ignoreMap":7},[1318,1326,1334,1342,1350,1358,1366,1374,1382,1390,1398,1406,1414,1423,1431,1438],{"type":26,"tag":157,"props":1319,"children":1320},{"class":159,"line":160},[1321],{"type":26,"tag":157,"props":1322,"children":1323},{},[1324],{"type":39,"value":1325},"./composer.json has been updated\n",{"type":26,"tag":157,"props":1327,"children":1328},{"class":159,"line":170},[1329],{"type":26,"tag":157,"props":1330,"children":1331},{},[1332],{"type":39,"value":1333},"Running composer update acme/sample-plugin\n",{"type":26,"tag":157,"props":1335,"children":1336},{"class":159,"line":196},[1337],{"type":26,"tag":157,"props":1338,"children":1339},{},[1340],{"type":39,"value":1341},"Loading composer repositories with package information                                                                \n",{"type":26,"tag":157,"props":1343,"children":1344},{"class":159,"line":218},[1345],{"type":26,"tag":157,"props":1346,"children":1347},{},[1348],{"type":39,"value":1349},"Updating dependencies                                 \n",{"type":26,"tag":157,"props":1351,"children":1352},{"class":159,"line":240},[1353],{"type":26,"tag":157,"props":1354,"children":1355},{},[1356],{"type":39,"value":1357},"Lock file operations: 1 install, 0 updates, 0 removals\n",{"type":26,"tag":157,"props":1359,"children":1360},{"class":159,"line":254},[1361],{"type":26,"tag":157,"props":1362,"children":1363},{},[1364],{"type":39,"value":1365},"  - Locking acme/sample-plugin (dev-master 294414d)\n",{"type":26,"tag":157,"props":1367,"children":1368},{"class":159,"line":276},[1369],{"type":26,"tag":157,"props":1370,"children":1371},{},[1372],{"type":39,"value":1373},"Writing lock file\n",{"type":26,"tag":157,"props":1375,"children":1376},{"class":159,"line":298},[1377],{"type":26,"tag":157,"props":1378,"children":1379},{},[1380],{"type":39,"value":1381},"Installing dependencies from lock file (including require-dev)\n",{"type":26,"tag":157,"props":1383,"children":1384},{"class":159,"line":320},[1385],{"type":26,"tag":157,"props":1386,"children":1387},{},[1388],{"type":39,"value":1389},"Package operations: 1 install, 0 updates, 0 removals\n",{"type":26,"tag":157,"props":1391,"children":1392},{"class":159,"line":342},[1393],{"type":26,"tag":157,"props":1394,"children":1395},{},[1396],{"type":39,"value":1397},"  - Syncing acme/sample-plugin (dev-master 294414d) into cache\n",{"type":26,"tag":157,"props":1399,"children":1400},{"class":159,"line":363},[1401],{"type":26,"tag":157,"props":1402,"children":1403},{},[1404],{"type":39,"value":1405},"  - Installing acme/sample-plugin (dev-master 294414d): Cloning 294414deb2 from cache\n",{"type":26,"tag":157,"props":1407,"children":1408},{"class":159,"line":384},[1409],{"type":26,"tag":157,"props":1410,"children":1411},{},[1412],{"type":39,"value":1413},"Generating optimized autoload files\n",{"type":26,"tag":157,"props":1415,"children":1416},{"class":159,"line":402},[1417],{"type":26,"tag":157,"props":1418,"children":1420},{"emptyLinePlaceholder":1419},true,[1421],{"type":39,"value":1422},"\n",{"type":26,"tag":157,"props":1424,"children":1425},{"class":159,"line":411},[1426],{"type":26,"tag":157,"props":1427,"children":1428},{},[1429],{"type":39,"value":1430},"Run composer recipes at any time to see the status of your Symfony recipes.\n",{"type":26,"tag":157,"props":1432,"children":1433},{"class":159,"line":425},[1434],{"type":26,"tag":157,"props":1435,"children":1436},{"emptyLinePlaceholder":1419},[1437],{"type":39,"value":1422},{"type":26,"tag":157,"props":1439,"children":1440},{"class":159,"line":434},[1441],{"type":26,"tag":157,"props":1442,"children":1443},{},[1444],{"type":39,"value":1445},"Executing script assets:install [OK]\n",{"type":26,"tag":35,"props":1447,"children":1448},{},[1449,1451,1457],{"type":39,"value":1450},"Composer will use ",{"type":26,"tag":76,"props":1452,"children":1454},{"className":1453},[],[1455],{"type":39,"value":1456},"git",{"type":39,"value":1458}," to clone our repo and use the default branch and the commit hash to track the release.",{"type":26,"tag":35,"props":1460,"children":1461},{},[1462],{"type":39,"value":1463},"This works, but we can do better.",{"type":26,"tag":122,"props":1465,"children":1467},{"id":1466},"git-tags",[1468],{"type":39,"value":1469},"Git tags",{"type":26,"tag":35,"props":1471,"children":1472},{},[1473,1475,1481],{"type":39,"value":1474},"Let's tag our plugin with ",{"type":26,"tag":76,"props":1476,"children":1478},{"className":1477},[],[1479],{"type":39,"value":1480},"v1.0.0",{"type":39,"value":54},{"type":26,"tag":35,"props":1483,"children":1484},{},[1485,1487,1493,1495,1501],{"type":39,"value":1486},"Make sure to set the ",{"type":26,"tag":76,"props":1488,"children":1490},{"className":1489},[],[1491],{"type":39,"value":1492},"version",{"type":39,"value":1494}," in ",{"type":26,"tag":76,"props":1496,"children":1498},{"className":1497},[],[1499],{"type":39,"value":1500},"composer.json",{"type":39,"value":54},{"type":26,"tag":141,"props":1503,"children":1507},{"className":143,"code":1504,"filename":1505,"highlights":1506,"language":151,"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",[240],[1508],{"type":26,"tag":76,"props":1509,"children":1510},{"__ignoreMap":7},[1511,1518,1539,1559,1580,1602,1622,1634,1651,1658,1670,1700,1712,1733,1750,1758,1765,1777,1789,1813,1820,1827,1839,1850,1883,1890,1897],{"type":26,"tag":157,"props":1512,"children":1513},{"class":159,"line":160},[1514],{"type":26,"tag":157,"props":1515,"children":1516},{"style":164},[1517],{"type":39,"value":167},{"type":26,"tag":157,"props":1519,"children":1520},{"class":159,"line":170},[1521,1526,1530,1535],{"type":26,"tag":157,"props":1522,"children":1523},{"style":174},[1524],{"type":39,"value":1525},"    \"name\"",{"type":26,"tag":157,"props":1527,"children":1528},{"style":164},[1529],{"type":39,"value":182},{"type":26,"tag":157,"props":1531,"children":1532},{"style":185},[1533],{"type":39,"value":1534},"\"acme/sample-plugin\"",{"type":26,"tag":157,"props":1536,"children":1537},{"style":164},[1538],{"type":39,"value":193},{"type":26,"tag":157,"props":1540,"children":1541},{"class":159,"line":196},[1542,1547,1551,1555],{"type":26,"tag":157,"props":1543,"children":1544},{"style":174},[1545],{"type":39,"value":1546},"    \"description\"",{"type":26,"tag":157,"props":1548,"children":1549},{"style":164},[1550],{"type":39,"value":182},{"type":26,"tag":157,"props":1552,"children":1553},{"style":185},[1554],{"type":39,"value":1534},{"type":26,"tag":157,"props":1556,"children":1557},{"style":164},[1558],{"type":39,"value":193},{"type":26,"tag":157,"props":1560,"children":1561},{"class":159,"line":218},[1562,1567,1571,1576],{"type":26,"tag":157,"props":1563,"children":1564},{"style":174},[1565],{"type":39,"value":1566},"    \"type\"",{"type":26,"tag":157,"props":1568,"children":1569},{"style":164},[1570],{"type":39,"value":182},{"type":26,"tag":157,"props":1572,"children":1573},{"style":185},[1574],{"type":39,"value":1575},"\"shopware-platform-plugin\"",{"type":26,"tag":157,"props":1577,"children":1578},{"style":164},[1579],{"type":39,"value":193},{"type":26,"tag":157,"props":1581,"children":1583},{"class":1582,"line":240},[159,715],[1584,1589,1593,1598],{"type":26,"tag":157,"props":1585,"children":1586},{"style":174},[1587],{"type":39,"value":1588},"    \"version\"",{"type":26,"tag":157,"props":1590,"children":1591},{"style":164},[1592],{"type":39,"value":182},{"type":26,"tag":157,"props":1594,"children":1595},{"style":185},[1596],{"type":39,"value":1597},"\"1.0.0\"",{"type":26,"tag":157,"props":1599,"children":1600},{"style":164},[1601],{"type":39,"value":193},{"type":26,"tag":157,"props":1603,"children":1604},{"class":159,"line":254},[1605,1610,1614,1618],{"type":26,"tag":157,"props":1606,"children":1607},{"style":174},[1608],{"type":39,"value":1609},"    \"license\"",{"type":26,"tag":157,"props":1611,"children":1612},{"style":164},[1613],{"type":39,"value":182},{"type":26,"tag":157,"props":1615,"children":1616},{"style":185},[1617],{"type":39,"value":211},{"type":26,"tag":157,"props":1619,"children":1620},{"style":164},[1621],{"type":39,"value":193},{"type":26,"tag":157,"props":1623,"children":1624},{"class":159,"line":276},[1625,1630],{"type":26,"tag":157,"props":1626,"children":1627},{"style":174},[1628],{"type":39,"value":1629},"    \"require\"",{"type":26,"tag":157,"props":1631,"children":1632},{"style":164},[1633],{"type":39,"value":251},{"type":26,"tag":157,"props":1635,"children":1636},{"class":159,"line":298},[1637,1642,1646],{"type":26,"tag":157,"props":1638,"children":1639},{"style":174},[1640],{"type":39,"value":1641},"        \"shopware/core\"",{"type":26,"tag":157,"props":1643,"children":1644},{"style":164},[1645],{"type":39,"value":182},{"type":26,"tag":157,"props":1647,"children":1648},{"style":185},[1649],{"type":39,"value":1650},"\"~6.6.0\"\n",{"type":26,"tag":157,"props":1652,"children":1653},{"class":159,"line":320},[1654],{"type":26,"tag":157,"props":1655,"children":1656},{"style":164},[1657],{"type":39,"value":525},{"type":26,"tag":157,"props":1659,"children":1660},{"class":159,"line":342},[1661,1666],{"type":26,"tag":157,"props":1662,"children":1663},{"style":174},[1664],{"type":39,"value":1665},"    \"extra\"",{"type":26,"tag":157,"props":1667,"children":1668},{"style":164},[1669],{"type":39,"value":251},{"type":26,"tag":157,"props":1671,"children":1672},{"class":159,"line":363},[1673,1678,1682,1687,1691,1696],{"type":26,"tag":157,"props":1674,"children":1675},{"style":174},[1676],{"type":39,"value":1677},"        \"shopware-plugin-class\"",{"type":26,"tag":157,"props":1679,"children":1680},{"style":164},[1681],{"type":39,"value":182},{"type":26,"tag":157,"props":1683,"children":1684},{"style":185},[1685],{"type":39,"value":1686},"\"Acme",{"type":26,"tag":157,"props":1688,"children":1689},{"style":504},[1690],{"type":39,"value":817},{"type":26,"tag":157,"props":1692,"children":1693},{"style":185},[1694],{"type":39,"value":1695},"SamplePlugin\"",{"type":26,"tag":157,"props":1697,"children":1698},{"style":164},[1699],{"type":39,"value":193},{"type":26,"tag":157,"props":1701,"children":1702},{"class":159,"line":384},[1703,1708],{"type":26,"tag":157,"props":1704,"children":1705},{"style":174},[1706],{"type":39,"value":1707},"        \"label\"",{"type":26,"tag":157,"props":1709,"children":1710},{"style":164},[1711],{"type":39,"value":251},{"type":26,"tag":157,"props":1713,"children":1714},{"class":159,"line":402},[1715,1720,1724,1729],{"type":26,"tag":157,"props":1716,"children":1717},{"style":174},[1718],{"type":39,"value":1719},"            \"de-DE\"",{"type":26,"tag":157,"props":1721,"children":1722},{"style":164},[1723],{"type":39,"value":182},{"type":26,"tag":157,"props":1725,"children":1726},{"style":185},[1727],{"type":39,"value":1728},"\"Skeleton plugin\"",{"type":26,"tag":157,"props":1730,"children":1731},{"style":164},[1732],{"type":39,"value":193},{"type":26,"tag":157,"props":1734,"children":1735},{"class":159,"line":411},[1736,1741,1745],{"type":26,"tag":157,"props":1737,"children":1738},{"style":174},[1739],{"type":39,"value":1740},"            \"en-GB\"",{"type":26,"tag":157,"props":1742,"children":1743},{"style":164},[1744],{"type":39,"value":182},{"type":26,"tag":157,"props":1746,"children":1747},{"style":185},[1748],{"type":39,"value":1749},"\"Skeleton plugin\"\n",{"type":26,"tag":157,"props":1751,"children":1752},{"class":159,"line":425},[1753],{"type":26,"tag":157,"props":1754,"children":1755},{"style":164},[1756],{"type":39,"value":1757},"        }\n",{"type":26,"tag":157,"props":1759,"children":1760},{"class":159,"line":434},[1761],{"type":26,"tag":157,"props":1762,"children":1763},{"style":164},[1764],{"type":39,"value":525},{"type":26,"tag":157,"props":1766,"children":1767},{"class":159,"line":456},[1768,1773],{"type":26,"tag":157,"props":1769,"children":1770},{"style":174},[1771],{"type":39,"value":1772},"    \"autoload\"",{"type":26,"tag":157,"props":1774,"children":1775},{"style":164},[1776],{"type":39,"value":251},{"type":26,"tag":157,"props":1778,"children":1779},{"class":159,"line":478},[1780,1785],{"type":26,"tag":157,"props":1781,"children":1782},{"style":174},[1783],{"type":39,"value":1784},"        \"psr-4\"",{"type":26,"tag":157,"props":1786,"children":1787},{"style":164},[1788],{"type":39,"value":251},{"type":26,"tag":157,"props":1790,"children":1791},{"class":159,"line":491},[1792,1797,1801,1805,1809],{"type":26,"tag":157,"props":1793,"children":1794},{"style":174},[1795],{"type":39,"value":1796},"            \"Acme",{"type":26,"tag":157,"props":1798,"children":1799},{"style":814},[1800],{"type":39,"value":817},{"type":26,"tag":157,"props":1802,"children":1803},{"style":174},[1804],{"type":39,"value":822},{"type":26,"tag":157,"props":1806,"children":1807},{"style":164},[1808],{"type":39,"value":182},{"type":26,"tag":157,"props":1810,"children":1811},{"style":185},[1812],{"type":39,"value":831},{"type":26,"tag":157,"props":1814,"children":1815},{"class":159,"line":510},[1816],{"type":26,"tag":157,"props":1817,"children":1818},{"style":164},[1819],{"type":39,"value":1757},{"type":26,"tag":157,"props":1821,"children":1822},{"class":159,"line":519},[1823],{"type":26,"tag":157,"props":1824,"children":1825},{"style":164},[1826],{"type":39,"value":525},{"type":26,"tag":157,"props":1828,"children":1829},{"class":159,"line":528},[1830,1835],{"type":26,"tag":157,"props":1831,"children":1832},{"style":174},[1833],{"type":39,"value":1834},"    \"autoload-dev\"",{"type":26,"tag":157,"props":1836,"children":1837},{"style":164},[1838],{"type":39,"value":251},{"type":26,"tag":157,"props":1840,"children":1841},{"class":159,"line":536},[1842,1846],{"type":26,"tag":157,"props":1843,"children":1844},{"style":174},[1845],{"type":39,"value":1784},{"type":26,"tag":157,"props":1847,"children":1848},{"style":164},[1849],{"type":39,"value":251},{"type":26,"tag":157,"props":1851,"children":1852},{"class":159,"line":556},[1853,1857,1861,1866,1870,1874,1878],{"type":26,"tag":157,"props":1854,"children":1855},{"style":174},[1856],{"type":39,"value":1796},{"type":26,"tag":157,"props":1858,"children":1859},{"style":814},[1860],{"type":39,"value":817},{"type":26,"tag":157,"props":1862,"children":1863},{"style":174},[1864],{"type":39,"value":1865},"Tests",{"type":26,"tag":157,"props":1867,"children":1868},{"style":814},[1869],{"type":39,"value":817},{"type":26,"tag":157,"props":1871,"children":1872},{"style":174},[1873],{"type":39,"value":822},{"type":26,"tag":157,"props":1875,"children":1876},{"style":164},[1877],{"type":39,"value":182},{"type":26,"tag":157,"props":1879,"children":1880},{"style":185},[1881],{"type":39,"value":1882},"\"tests/\"\n",{"type":26,"tag":157,"props":1884,"children":1885},{"class":159,"line":577},[1886],{"type":26,"tag":157,"props":1887,"children":1888},{"style":164},[1889],{"type":39,"value":1757},{"type":26,"tag":157,"props":1891,"children":1892},{"class":159,"line":589},[1893],{"type":26,"tag":157,"props":1894,"children":1895},{"style":164},[1896],{"type":39,"value":767},{"type":26,"tag":157,"props":1898,"children":1899},{"class":159,"line":605},[1900],{"type":26,"tag":157,"props":1901,"children":1902},{"style":164},[1903],{"type":39,"value":1225},{"type":26,"tag":141,"props":1905,"children":1907},{"className":1233,"code":1906,"language":1235,"meta":7,"style":7},"git tag v1.0.0\ngit push --tags\n",[1908],{"type":26,"tag":76,"props":1909,"children":1910},{"__ignoreMap":7},[1911,1928],{"type":26,"tag":157,"props":1912,"children":1913},{"class":159,"line":160},[1914,1918,1923],{"type":26,"tag":157,"props":1915,"children":1916},{"style":1245},[1917],{"type":39,"value":1456},{"type":26,"tag":157,"props":1919,"children":1920},{"style":1250},[1921],{"type":39,"value":1922}," tag",{"type":26,"tag":157,"props":1924,"children":1925},{"style":1250},[1926],{"type":39,"value":1927}," v1.0.0\n",{"type":26,"tag":157,"props":1929,"children":1930},{"class":159,"line":170},[1931,1935,1940],{"type":26,"tag":157,"props":1932,"children":1933},{"style":1245},[1934],{"type":39,"value":1456},{"type":26,"tag":157,"props":1936,"children":1937},{"style":1250},[1938],{"type":39,"value":1939}," push",{"type":26,"tag":157,"props":1941,"children":1942},{"style":504},[1943],{"type":39,"value":1944}," --tags\n",{"type":26,"tag":35,"props":1946,"children":1947},{},[1948],{"type":39,"value":1949},"Now this will work:",{"type":26,"tag":141,"props":1951,"children":1952},{"className":1233,"code":1234,"language":1235,"meta":7,"style":7},[1953],{"type":26,"tag":76,"props":1954,"children":1955},{"__ignoreMap":7},[1956],{"type":26,"tag":157,"props":1957,"children":1958},{"class":159,"line":160},[1959,1963,1967],{"type":26,"tag":157,"props":1960,"children":1961},{"style":1245},[1962],{"type":39,"value":92},{"type":26,"tag":157,"props":1964,"children":1965},{"style":1250},[1966],{"type":39,"value":1253},{"type":26,"tag":157,"props":1968,"children":1969},{"style":1250},[1970],{"type":39,"value":1258},{"type":26,"tag":141,"props":1972,"children":1976},{"className":1973,"code":1974,"language":1975,"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",[1977],{"type":26,"tag":76,"props":1978,"children":1979},{"__ignoreMap":7},[1980,1988,1995,2003,2011,2018,2026,2033,2040,2047,2055,2063,2070,2077,2084,2091,2098,2105],{"type":26,"tag":157,"props":1981,"children":1982},{"class":159,"line":160},[1983],{"type":26,"tag":157,"props":1984,"children":1985},{},[1986],{"type":39,"value":1987},"./composer.json has been updated                                                                                                            \n",{"type":26,"tag":157,"props":1989,"children":1990},{"class":159,"line":170},[1991],{"type":26,"tag":157,"props":1992,"children":1993},{},[1994],{"type":39,"value":1333},{"type":26,"tag":157,"props":1996,"children":1997},{"class":159,"line":196},[1998],{"type":26,"tag":157,"props":1999,"children":2000},{},[2001],{"type":39,"value":2002},"Loading composer repositories with package information\n",{"type":26,"tag":157,"props":2004,"children":2005},{"class":159,"line":218},[2006],{"type":26,"tag":157,"props":2007,"children":2008},{},[2009],{"type":39,"value":2010},"Updating dependencies\n",{"type":26,"tag":157,"props":2012,"children":2013},{"class":159,"line":240},[2014],{"type":26,"tag":157,"props":2015,"children":2016},{},[2017],{"type":39,"value":1357},{"type":26,"tag":157,"props":2019,"children":2020},{"class":159,"line":254},[2021],{"type":26,"tag":157,"props":2022,"children":2023},{},[2024],{"type":39,"value":2025},"  - Locking acme/sample-plugin (1.0.0)\n",{"type":26,"tag":157,"props":2027,"children":2028},{"class":159,"line":276},[2029],{"type":26,"tag":157,"props":2030,"children":2031},{},[2032],{"type":39,"value":1373},{"type":26,"tag":157,"props":2034,"children":2035},{"class":159,"line":298},[2036],{"type":26,"tag":157,"props":2037,"children":2038},{},[2039],{"type":39,"value":1381},{"type":26,"tag":157,"props":2041,"children":2042},{"class":159,"line":320},[2043],{"type":26,"tag":157,"props":2044,"children":2045},{},[2046],{"type":39,"value":1389},{"type":26,"tag":157,"props":2048,"children":2049},{"class":159,"line":342},[2050],{"type":26,"tag":157,"props":2051,"children":2052},{},[2053],{"type":39,"value":2054},"  - Syncing acme/sample-plugin (1.0.0) into cache\n",{"type":26,"tag":157,"props":2056,"children":2057},{"class":159,"line":363},[2058],{"type":26,"tag":157,"props":2059,"children":2060},{},[2061],{"type":39,"value":2062},"  - Installing acme/sample-plugin (1.0.0): Cloning 294414deb2 from cache\n",{"type":26,"tag":157,"props":2064,"children":2065},{"class":159,"line":384},[2066],{"type":26,"tag":157,"props":2067,"children":2068},{},[2069],{"type":39,"value":1413},{"type":26,"tag":157,"props":2071,"children":2072},{"class":159,"line":402},[2073],{"type":26,"tag":157,"props":2074,"children":2075},{"emptyLinePlaceholder":1419},[2076],{"type":39,"value":1422},{"type":26,"tag":157,"props":2078,"children":2079},{"class":159,"line":411},[2080],{"type":26,"tag":157,"props":2081,"children":2082},{},[2083],{"type":39,"value":1430},{"type":26,"tag":157,"props":2085,"children":2086},{"class":159,"line":425},[2087],{"type":26,"tag":157,"props":2088,"children":2089},{"emptyLinePlaceholder":1419},[2090],{"type":39,"value":1422},{"type":26,"tag":157,"props":2092,"children":2093},{"class":159,"line":434},[2094],{"type":26,"tag":157,"props":2095,"children":2096},{},[2097],{"type":39,"value":1445},{"type":26,"tag":157,"props":2099,"children":2100},{"class":159,"line":456},[2101],{"type":26,"tag":157,"props":2102,"children":2103},{"emptyLinePlaceholder":1419},[2104],{"type":39,"value":1422},{"type":26,"tag":157,"props":2106,"children":2107},{"class":159,"line":478},[2108],{"type":26,"tag":157,"props":2109,"children":2110},{},[2111],{"type":39,"value":2112},"Using version ^1.0 for acme/sample-plugin\n",{"type":26,"tag":35,"props":2114,"children":2115},{},[2116,2118,2123],{"type":39,"value":2117},"This is better, but we are still using ",{"type":26,"tag":76,"props":2119,"children":2121},{"className":2120},[],[2122],{"type":39,"value":1456},{"type":39,"value":2124}," to fetch the plugin. We can do better.",{"type":26,"tag":122,"props":2126,"children":2128},{"id":2127},"gitlab-package-registry",[2129],{"type":39,"value":2130},"GitLab Package registry",{"type":26,"tag":35,"props":2132,"children":2133},{},[2134,2136,2141],{"type":39,"value":2135},"Here is where the GitLab part starts. For more details refer to the ",{"type":26,"tag":47,"props":2137,"children":2139},{"href":2138},"https://docs.gitlab.com/18.3/user/packages/composer_repository/",[2140],{"type":39,"value":52},{"type":39,"value":54},{"type":26,"tag":35,"props":2143,"children":2144},{},[2145],{"type":39,"value":2146},"At this point, it doesn't matter if our project in public or not, because we will need to authenticate with the package registry anyway.",{"type":26,"tag":35,"props":2148,"children":2149},{},[2150,2152,2157],{"type":39,"value":2151},"Let's release our ",{"type":26,"tag":76,"props":2153,"children":2155},{"className":2154},[],[2156],{"type":39,"value":1480},{"type":39,"value":2158}," tag as a composer package.",{"type":26,"tag":141,"props":2160,"children":2162},{"className":1233,"code":2161,"language":1235,"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",[2163],{"type":26,"tag":76,"props":2164,"children":2165},{"__ignoreMap":7},[2166],{"type":26,"tag":157,"props":2167,"children":2168},{"class":159,"line":160},[2169,2174,2179,2184,2189],{"type":26,"tag":157,"props":2170,"children":2171},{"style":1245},[2172],{"type":39,"value":2173},"curl",{"type":26,"tag":157,"props":2175,"children":2176},{"style":504},[2177],{"type":39,"value":2178}," --fail-with-body",{"type":26,"tag":157,"props":2180,"children":2181},{"style":504},[2182],{"type":39,"value":2183}," --data",{"type":26,"tag":157,"props":2185,"children":2186},{"style":1250},[2187],{"type":39,"value":2188}," tag=v1.0.0",{"type":26,"tag":157,"props":2190,"children":2191},{"style":1250},[2192],{"type":39,"value":2193}," \"https://__token__:\u003Cpersonal-access-token>@\u003CDOMAIN-NAME>/api/v4/projects/\u003Cproject_id>/packages/composer\"\n",{"type":26,"tag":35,"props":2195,"children":2196},{},[2197],{"type":39,"value":2198},"Now we need to update the repository information:",{"type":26,"tag":141,"props":2200,"children":2203},{"className":143,"code":2201,"filename":145,"highlights":2202,"language":151,"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",[147,148,149,150],[2204],{"type":26,"tag":76,"props":2205,"children":2206},{"__ignoreMap":7},[2207,2214,2233,2252,2271,2282,2301,2320,2339,2358,2377,2396,2411,2418,2429,2436,2455,2474,2485,2500,2507,2514,2521,2540,2559,2570,2585,2592,2599,2606,2625,2644,2655,2670,2677,2684,2692,2713,2730,2738,2745,2756,2767,2790,2797,2804,2823,2834,2845,2864,2879,2886,2905,2920,2927,2938,2949,2964,2971,2982,2989,2996,3007,3014,3021,3028,3039,3050,3069,3080,3091,3098,3105,3112,3119],{"type":26,"tag":157,"props":2208,"children":2209},{"class":159,"line":160},[2210],{"type":26,"tag":157,"props":2211,"children":2212},{"style":164},[2213],{"type":39,"value":167},{"type":26,"tag":157,"props":2215,"children":2216},{"class":159,"line":170},[2217,2221,2225,2229],{"type":26,"tag":157,"props":2218,"children":2219},{"style":174},[2220],{"type":39,"value":177},{"type":26,"tag":157,"props":2222,"children":2223},{"style":164},[2224],{"type":39,"value":182},{"type":26,"tag":157,"props":2226,"children":2227},{"style":185},[2228],{"type":39,"value":188},{"type":26,"tag":157,"props":2230,"children":2231},{"style":164},[2232],{"type":39,"value":193},{"type":26,"tag":157,"props":2234,"children":2235},{"class":159,"line":196},[2236,2240,2244,2248],{"type":26,"tag":157,"props":2237,"children":2238},{"style":174},[2239],{"type":39,"value":202},{"type":26,"tag":157,"props":2241,"children":2242},{"style":164},[2243],{"type":39,"value":182},{"type":26,"tag":157,"props":2245,"children":2246},{"style":185},[2247],{"type":39,"value":211},{"type":26,"tag":157,"props":2249,"children":2250},{"style":164},[2251],{"type":39,"value":193},{"type":26,"tag":157,"props":2253,"children":2254},{"class":159,"line":218},[2255,2259,2263,2267],{"type":26,"tag":157,"props":2256,"children":2257},{"style":174},[2258],{"type":39,"value":224},{"type":26,"tag":157,"props":2260,"children":2261},{"style":164},[2262],{"type":39,"value":182},{"type":26,"tag":157,"props":2264,"children":2265},{"style":185},[2266],{"type":39,"value":233},{"type":26,"tag":157,"props":2268,"children":2269},{"style":164},[2270],{"type":39,"value":193},{"type":26,"tag":157,"props":2272,"children":2273},{"class":159,"line":240},[2274,2278],{"type":26,"tag":157,"props":2275,"children":2276},{"style":174},[2277],{"type":39,"value":246},{"type":26,"tag":157,"props":2279,"children":2280},{"style":164},[2281],{"type":39,"value":251},{"type":26,"tag":157,"props":2283,"children":2284},{"class":159,"line":254},[2285,2289,2293,2297],{"type":26,"tag":157,"props":2286,"children":2287},{"style":174},[2288],{"type":39,"value":260},{"type":26,"tag":157,"props":2290,"children":2291},{"style":164},[2292],{"type":39,"value":182},{"type":26,"tag":157,"props":2294,"children":2295},{"style":185},[2296],{"type":39,"value":269},{"type":26,"tag":157,"props":2298,"children":2299},{"style":164},[2300],{"type":39,"value":193},{"type":26,"tag":157,"props":2302,"children":2303},{"class":159,"line":276},[2304,2308,2312,2316],{"type":26,"tag":157,"props":2305,"children":2306},{"style":174},[2307],{"type":39,"value":282},{"type":26,"tag":157,"props":2309,"children":2310},{"style":164},[2311],{"type":39,"value":182},{"type":26,"tag":157,"props":2313,"children":2314},{"style":185},[2315],{"type":39,"value":291},{"type":26,"tag":157,"props":2317,"children":2318},{"style":164},[2319],{"type":39,"value":193},{"type":26,"tag":157,"props":2321,"children":2322},{"class":159,"line":298},[2323,2327,2331,2335],{"type":26,"tag":157,"props":2324,"children":2325},{"style":174},[2326],{"type":39,"value":304},{"type":26,"tag":157,"props":2328,"children":2329},{"style":164},[2330],{"type":39,"value":182},{"type":26,"tag":157,"props":2332,"children":2333},{"style":185},[2334],{"type":39,"value":313},{"type":26,"tag":157,"props":2336,"children":2337},{"style":164},[2338],{"type":39,"value":193},{"type":26,"tag":157,"props":2340,"children":2341},{"class":159,"line":320},[2342,2346,2350,2354],{"type":26,"tag":157,"props":2343,"children":2344},{"style":174},[2345],{"type":39,"value":326},{"type":26,"tag":157,"props":2347,"children":2348},{"style":164},[2349],{"type":39,"value":182},{"type":26,"tag":157,"props":2351,"children":2352},{"style":185},[2353],{"type":39,"value":335},{"type":26,"tag":157,"props":2355,"children":2356},{"style":164},[2357],{"type":39,"value":193},{"type":26,"tag":157,"props":2359,"children":2360},{"class":159,"line":342},[2361,2365,2369,2373],{"type":26,"tag":157,"props":2362,"children":2363},{"style":174},[2364],{"type":39,"value":348},{"type":26,"tag":157,"props":2366,"children":2367},{"style":164},[2368],{"type":39,"value":182},{"type":26,"tag":157,"props":2370,"children":2371},{"style":185},[2372],{"type":39,"value":313},{"type":26,"tag":157,"props":2374,"children":2375},{"style":164},[2376],{"type":39,"value":193},{"type":26,"tag":157,"props":2378,"children":2379},{"class":159,"line":363},[2380,2384,2388,2392],{"type":26,"tag":157,"props":2381,"children":2382},{"style":174},[2383],{"type":39,"value":369},{"type":26,"tag":157,"props":2385,"children":2386},{"style":164},[2387],{"type":39,"value":182},{"type":26,"tag":157,"props":2389,"children":2390},{"style":185},[2391],{"type":39,"value":313},{"type":26,"tag":157,"props":2393,"children":2394},{"style":164},[2395],{"type":39,"value":193},{"type":26,"tag":157,"props":2397,"children":2398},{"class":159,"line":384},[2399,2403,2407],{"type":26,"tag":157,"props":2400,"children":2401},{"style":174},[2402],{"type":39,"value":390},{"type":26,"tag":157,"props":2404,"children":2405},{"style":164},[2406],{"type":39,"value":182},{"type":26,"tag":157,"props":2408,"children":2409},{"style":185},[2410],{"type":39,"value":399},{"type":26,"tag":157,"props":2412,"children":2413},{"class":159,"line":402},[2414],{"type":26,"tag":157,"props":2415,"children":2416},{"style":164},[2417],{"type":39,"value":408},{"type":26,"tag":157,"props":2419,"children":2420},{"class":159,"line":411},[2421,2425],{"type":26,"tag":157,"props":2422,"children":2423},{"style":174},[2424],{"type":39,"value":417},{"type":26,"tag":157,"props":2426,"children":2427},{"style":164},[2428],{"type":39,"value":422},{"type":26,"tag":157,"props":2430,"children":2431},{"class":159,"line":425},[2432],{"type":26,"tag":157,"props":2433,"children":2434},{"style":164},[2435],{"type":39,"value":431},{"type":26,"tag":157,"props":2437,"children":2438},{"class":159,"line":434},[2439,2443,2447,2451],{"type":26,"tag":157,"props":2440,"children":2441},{"style":174},[2442],{"type":39,"value":440},{"type":26,"tag":157,"props":2444,"children":2445},{"style":164},[2446],{"type":39,"value":182},{"type":26,"tag":157,"props":2448,"children":2449},{"style":185},[2450],{"type":39,"value":449},{"type":26,"tag":157,"props":2452,"children":2453},{"style":164},[2454],{"type":39,"value":193},{"type":26,"tag":157,"props":2456,"children":2457},{"class":159,"line":456},[2458,2462,2466,2470],{"type":26,"tag":157,"props":2459,"children":2460},{"style":174},[2461],{"type":39,"value":462},{"type":26,"tag":157,"props":2463,"children":2464},{"style":164},[2465],{"type":39,"value":182},{"type":26,"tag":157,"props":2467,"children":2468},{"style":185},[2469],{"type":39,"value":471},{"type":26,"tag":157,"props":2471,"children":2472},{"style":164},[2473],{"type":39,"value":193},{"type":26,"tag":157,"props":2475,"children":2476},{"class":159,"line":478},[2477,2481],{"type":26,"tag":157,"props":2478,"children":2479},{"style":174},[2480],{"type":39,"value":484},{"type":26,"tag":157,"props":2482,"children":2483},{"style":164},[2484],{"type":39,"value":251},{"type":26,"tag":157,"props":2486,"children":2487},{"class":159,"line":491},[2488,2492,2496],{"type":26,"tag":157,"props":2489,"children":2490},{"style":174},[2491],{"type":39,"value":497},{"type":26,"tag":157,"props":2493,"children":2494},{"style":164},[2495],{"type":39,"value":182},{"type":26,"tag":157,"props":2497,"children":2498},{"style":504},[2499],{"type":39,"value":507},{"type":26,"tag":157,"props":2501,"children":2502},{"class":159,"line":510},[2503],{"type":26,"tag":157,"props":2504,"children":2505},{"style":164},[2506],{"type":39,"value":516},{"type":26,"tag":157,"props":2508,"children":2509},{"class":159,"line":519},[2510],{"type":26,"tag":157,"props":2511,"children":2512},{"style":164},[2513],{"type":39,"value":525},{"type":26,"tag":157,"props":2515,"children":2516},{"class":159,"line":528},[2517],{"type":26,"tag":157,"props":2518,"children":2519},{"style":164},[2520],{"type":39,"value":431},{"type":26,"tag":157,"props":2522,"children":2523},{"class":159,"line":536},[2524,2528,2532,2536],{"type":26,"tag":157,"props":2525,"children":2526},{"style":174},[2527],{"type":39,"value":440},{"type":26,"tag":157,"props":2529,"children":2530},{"style":164},[2531],{"type":39,"value":182},{"type":26,"tag":157,"props":2533,"children":2534},{"style":185},[2535],{"type":39,"value":449},{"type":26,"tag":157,"props":2537,"children":2538},{"style":164},[2539],{"type":39,"value":193},{"type":26,"tag":157,"props":2541,"children":2542},{"class":159,"line":556},[2543,2547,2551,2555],{"type":26,"tag":157,"props":2544,"children":2545},{"style":174},[2546],{"type":39,"value":462},{"type":26,"tag":157,"props":2548,"children":2549},{"style":164},[2550],{"type":39,"value":182},{"type":26,"tag":157,"props":2552,"children":2553},{"style":185},[2554],{"type":39,"value":570},{"type":26,"tag":157,"props":2556,"children":2557},{"style":164},[2558],{"type":39,"value":193},{"type":26,"tag":157,"props":2560,"children":2561},{"class":159,"line":577},[2562,2566],{"type":26,"tag":157,"props":2563,"children":2564},{"style":174},[2565],{"type":39,"value":484},{"type":26,"tag":157,"props":2567,"children":2568},{"style":164},[2569],{"type":39,"value":251},{"type":26,"tag":157,"props":2571,"children":2572},{"class":159,"line":589},[2573,2577,2581],{"type":26,"tag":157,"props":2574,"children":2575},{"style":174},[2576],{"type":39,"value":497},{"type":26,"tag":157,"props":2578,"children":2579},{"style":164},[2580],{"type":39,"value":182},{"type":26,"tag":157,"props":2582,"children":2583},{"style":504},[2584],{"type":39,"value":507},{"type":26,"tag":157,"props":2586,"children":2587},{"class":159,"line":605},[2588],{"type":26,"tag":157,"props":2589,"children":2590},{"style":164},[2591],{"type":39,"value":516},{"type":26,"tag":157,"props":2593,"children":2594},{"class":159,"line":613},[2595],{"type":26,"tag":157,"props":2596,"children":2597},{"style":164},[2598],{"type":39,"value":525},{"type":26,"tag":157,"props":2600,"children":2601},{"class":159,"line":621},[2602],{"type":26,"tag":157,"props":2603,"children":2604},{"style":164},[2605],{"type":39,"value":431},{"type":26,"tag":157,"props":2607,"children":2608},{"class":159,"line":629},[2609,2613,2617,2621],{"type":26,"tag":157,"props":2610,"children":2611},{"style":174},[2612],{"type":39,"value":440},{"type":26,"tag":157,"props":2614,"children":2615},{"style":164},[2616],{"type":39,"value":182},{"type":26,"tag":157,"props":2618,"children":2619},{"style":185},[2620],{"type":39,"value":449},{"type":26,"tag":157,"props":2622,"children":2623},{"style":164},[2624],{"type":39,"value":193},{"type":26,"tag":157,"props":2626,"children":2627},{"class":159,"line":649},[2628,2632,2636,2640],{"type":26,"tag":157,"props":2629,"children":2630},{"style":174},[2631],{"type":39,"value":462},{"type":26,"tag":157,"props":2633,"children":2634},{"style":164},[2635],{"type":39,"value":182},{"type":26,"tag":157,"props":2637,"children":2638},{"style":185},[2639],{"type":39,"value":663},{"type":26,"tag":157,"props":2641,"children":2642},{"style":164},[2643],{"type":39,"value":193},{"type":26,"tag":157,"props":2645,"children":2646},{"class":159,"line":670},[2647,2651],{"type":26,"tag":157,"props":2648,"children":2649},{"style":174},[2650],{"type":39,"value":484},{"type":26,"tag":157,"props":2652,"children":2653},{"style":164},[2654],{"type":39,"value":251},{"type":26,"tag":157,"props":2656,"children":2657},{"class":159,"line":682},[2658,2662,2666],{"type":26,"tag":157,"props":2659,"children":2660},{"style":174},[2661],{"type":39,"value":497},{"type":26,"tag":157,"props":2663,"children":2664},{"style":164},[2665],{"type":39,"value":182},{"type":26,"tag":157,"props":2667,"children":2668},{"style":504},[2669],{"type":39,"value":507},{"type":26,"tag":157,"props":2671,"children":2672},{"class":159,"line":698},[2673],{"type":26,"tag":157,"props":2674,"children":2675},{"style":164},[2676],{"type":39,"value":516},{"type":26,"tag":157,"props":2678,"children":2679},{"class":159,"line":706},[2680],{"type":26,"tag":157,"props":2681,"children":2682},{"style":164},[2683],{"type":39,"value":525},{"type":26,"tag":157,"props":2685,"children":2687},{"class":2686,"line":147},[159,715],[2688],{"type":26,"tag":157,"props":2689,"children":2690},{"style":164},[2691],{"type":39,"value":431},{"type":26,"tag":157,"props":2693,"children":2695},{"class":2694,"line":148},[159,715],[2696,2700,2704,2709],{"type":26,"tag":157,"props":2697,"children":2698},{"style":174},[2699],{"type":39,"value":440},{"type":26,"tag":157,"props":2701,"children":2702},{"style":164},[2703],{"type":39,"value":182},{"type":26,"tag":157,"props":2705,"children":2706},{"style":185},[2707],{"type":39,"value":2708},"\"composer\"",{"type":26,"tag":157,"props":2710,"children":2711},{"style":164},[2712],{"type":39,"value":193},{"type":26,"tag":157,"props":2714,"children":2716},{"class":2715,"line":149},[159,715],[2717,2721,2725],{"type":26,"tag":157,"props":2718,"children":2719},{"style":174},[2720],{"type":39,"value":462},{"type":26,"tag":157,"props":2722,"children":2723},{"style":164},[2724],{"type":39,"value":182},{"type":26,"tag":157,"props":2726,"children":2727},{"style":185},[2728],{"type":39,"value":2729},"\"https://\u003CDOMAIN-NAME>/api/v4/api/v4/group/\u003Cgroup_id>/-/packages/composer/packages.json\"\n",{"type":26,"tag":157,"props":2731,"children":2733},{"class":2732,"line":150},[159,715],[2734],{"type":26,"tag":157,"props":2735,"children":2736},{"style":164},[2737],{"type":39,"value":767},{"type":26,"tag":157,"props":2739,"children":2740},{"class":159,"line":770},[2741],{"type":26,"tag":157,"props":2742,"children":2743},{"style":164},[2744],{"type":39,"value":776},{"type":26,"tag":157,"props":2746,"children":2747},{"class":159,"line":779},[2748,2752],{"type":26,"tag":157,"props":2749,"children":2750},{"style":174},[2751],{"type":39,"value":785},{"type":26,"tag":157,"props":2753,"children":2754},{"style":164},[2755],{"type":39,"value":251},{"type":26,"tag":157,"props":2757,"children":2758},{"class":159,"line":792},[2759,2763],{"type":26,"tag":157,"props":2760,"children":2761},{"style":174},[2762],{"type":39,"value":798},{"type":26,"tag":157,"props":2764,"children":2765},{"style":164},[2766],{"type":39,"value":251},{"type":26,"tag":157,"props":2768,"children":2769},{"class":159,"line":805},[2770,2774,2778,2782,2786],{"type":26,"tag":157,"props":2771,"children":2772},{"style":174},[2773],{"type":39,"value":811},{"type":26,"tag":157,"props":2775,"children":2776},{"style":814},[2777],{"type":39,"value":817},{"type":26,"tag":157,"props":2779,"children":2780},{"style":174},[2781],{"type":39,"value":822},{"type":26,"tag":157,"props":2783,"children":2784},{"style":164},[2785],{"type":39,"value":182},{"type":26,"tag":157,"props":2787,"children":2788},{"style":185},[2789],{"type":39,"value":831},{"type":26,"tag":157,"props":2791,"children":2792},{"class":159,"line":834},[2793],{"type":26,"tag":157,"props":2794,"children":2795},{"style":164},[2796],{"type":39,"value":767},{"type":26,"tag":157,"props":2798,"children":2799},{"class":159,"line":842},[2800],{"type":26,"tag":157,"props":2801,"children":2802},{"style":164},[2803],{"type":39,"value":408},{"type":26,"tag":157,"props":2805,"children":2806},{"class":159,"line":850},[2807,2811,2815,2819],{"type":26,"tag":157,"props":2808,"children":2809},{"style":174},[2810],{"type":39,"value":856},{"type":26,"tag":157,"props":2812,"children":2813},{"style":164},[2814],{"type":39,"value":182},{"type":26,"tag":157,"props":2816,"children":2817},{"style":504},[2818],{"type":39,"value":865},{"type":26,"tag":157,"props":2820,"children":2821},{"style":164},[2822],{"type":39,"value":193},{"type":26,"tag":157,"props":2824,"children":2825},{"class":159,"line":872},[2826,2830],{"type":26,"tag":157,"props":2827,"children":2828},{"style":174},[2829],{"type":39,"value":878},{"type":26,"tag":157,"props":2831,"children":2832},{"style":164},[2833],{"type":39,"value":251},{"type":26,"tag":157,"props":2835,"children":2836},{"class":159,"line":885},[2837,2841],{"type":26,"tag":157,"props":2838,"children":2839},{"style":174},[2840],{"type":39,"value":891},{"type":26,"tag":157,"props":2842,"children":2843},{"style":164},[2844],{"type":39,"value":251},{"type":26,"tag":157,"props":2846,"children":2847},{"class":159,"line":898},[2848,2852,2856,2860],{"type":26,"tag":157,"props":2849,"children":2850},{"style":174},[2851],{"type":39,"value":904},{"type":26,"tag":157,"props":2853,"children":2854},{"style":164},[2855],{"type":39,"value":182},{"type":26,"tag":157,"props":2857,"children":2858},{"style":504},[2859],{"type":39,"value":865},{"type":26,"tag":157,"props":2861,"children":2862},{"style":164},[2863],{"type":39,"value":193},{"type":26,"tag":157,"props":2865,"children":2866},{"class":159,"line":919},[2867,2871,2875],{"type":26,"tag":157,"props":2868,"children":2869},{"style":174},[2870],{"type":39,"value":925},{"type":26,"tag":157,"props":2872,"children":2873},{"style":164},[2874],{"type":39,"value":182},{"type":26,"tag":157,"props":2876,"children":2877},{"style":504},[2878],{"type":39,"value":507},{"type":26,"tag":157,"props":2880,"children":2881},{"class":159,"line":936},[2882],{"type":26,"tag":157,"props":2883,"children":2884},{"style":164},[2885],{"type":39,"value":525},{"type":26,"tag":157,"props":2887,"children":2888},{"class":159,"line":944},[2889,2893,2897,2901],{"type":26,"tag":157,"props":2890,"children":2891},{"style":174},[2892],{"type":39,"value":950},{"type":26,"tag":157,"props":2894,"children":2895},{"style":164},[2896],{"type":39,"value":182},{"type":26,"tag":157,"props":2898,"children":2899},{"style":504},[2900],{"type":39,"value":865},{"type":26,"tag":157,"props":2902,"children":2903},{"style":164},[2904],{"type":39,"value":193},{"type":26,"tag":157,"props":2906,"children":2907},{"class":159,"line":965},[2908,2912,2916],{"type":26,"tag":157,"props":2909,"children":2910},{"style":174},[2911],{"type":39,"value":971},{"type":26,"tag":157,"props":2913,"children":2914},{"style":164},[2915],{"type":39,"value":182},{"type":26,"tag":157,"props":2917,"children":2918},{"style":504},[2919],{"type":39,"value":507},{"type":26,"tag":157,"props":2921,"children":2922},{"class":159,"line":982},[2923],{"type":26,"tag":157,"props":2924,"children":2925},{"style":164},[2926],{"type":39,"value":408},{"type":26,"tag":157,"props":2928,"children":2929},{"class":159,"line":990},[2930,2934],{"type":26,"tag":157,"props":2931,"children":2932},{"style":174},[2933],{"type":39,"value":996},{"type":26,"tag":157,"props":2935,"children":2936},{"style":164},[2937],{"type":39,"value":251},{"type":26,"tag":157,"props":2939,"children":2940},{"class":159,"line":1003},[2941,2945],{"type":26,"tag":157,"props":2942,"children":2943},{"style":174},[2944],{"type":39,"value":1009},{"type":26,"tag":157,"props":2946,"children":2947},{"style":164},[2948],{"type":39,"value":251},{"type":26,"tag":157,"props":2950,"children":2951},{"class":159,"line":1016},[2952,2956,2960],{"type":26,"tag":157,"props":2953,"children":2954},{"style":174},[2955],{"type":39,"value":1022},{"type":26,"tag":157,"props":2957,"children":2958},{"style":164},[2959],{"type":39,"value":182},{"type":26,"tag":157,"props":2961,"children":2962},{"style":185},[2963],{"type":39,"value":1031},{"type":26,"tag":157,"props":2965,"children":2966},{"class":159,"line":1034},[2967],{"type":26,"tag":157,"props":2968,"children":2969},{"style":164},[2970],{"type":39,"value":525},{"type":26,"tag":157,"props":2972,"children":2973},{"class":159,"line":1042},[2974,2978],{"type":26,"tag":157,"props":2975,"children":2976},{"style":174},[2977],{"type":39,"value":1048},{"type":26,"tag":157,"props":2979,"children":2980},{"style":164},[2981],{"type":39,"value":422},{"type":26,"tag":157,"props":2983,"children":2984},{"class":159,"line":1055},[2985],{"type":26,"tag":157,"props":2986,"children":2987},{"style":185},[2988],{"type":39,"value":1061},{"type":26,"tag":157,"props":2990,"children":2991},{"class":159,"line":1064},[2992],{"type":26,"tag":157,"props":2993,"children":2994},{"style":164},[2995],{"type":39,"value":1070},{"type":26,"tag":157,"props":2997,"children":2998},{"class":159,"line":1073},[2999,3003],{"type":26,"tag":157,"props":3000,"children":3001},{"style":174},[3002],{"type":39,"value":1079},{"type":26,"tag":157,"props":3004,"children":3005},{"style":164},[3006],{"type":39,"value":422},{"type":26,"tag":157,"props":3008,"children":3009},{"class":159,"line":1086},[3010],{"type":26,"tag":157,"props":3011,"children":3012},{"style":185},[3013],{"type":39,"value":1061},{"type":26,"tag":157,"props":3015,"children":3016},{"class":159,"line":1094},[3017],{"type":26,"tag":157,"props":3018,"children":3019},{"style":164},[3020],{"type":39,"value":1100},{"type":26,"tag":157,"props":3022,"children":3023},{"class":159,"line":1103},[3024],{"type":26,"tag":157,"props":3025,"children":3026},{"style":164},[3027],{"type":39,"value":408},{"type":26,"tag":157,"props":3029,"children":3030},{"class":159,"line":1111},[3031,3035],{"type":26,"tag":157,"props":3032,"children":3033},{"style":174},[3034],{"type":39,"value":1117},{"type":26,"tag":157,"props":3036,"children":3037},{"style":164},[3038],{"type":39,"value":251},{"type":26,"tag":157,"props":3040,"children":3041},{"class":159,"line":1124},[3042,3046],{"type":26,"tag":157,"props":3043,"children":3044},{"style":174},[3045],{"type":39,"value":1130},{"type":26,"tag":157,"props":3047,"children":3048},{"style":164},[3049],{"type":39,"value":251},{"type":26,"tag":157,"props":3051,"children":3052},{"class":159,"line":1137},[3053,3057,3061,3065],{"type":26,"tag":157,"props":3054,"children":3055},{"style":174},[3056],{"type":39,"value":1143},{"type":26,"tag":157,"props":3058,"children":3059},{"style":164},[3060],{"type":39,"value":182},{"type":26,"tag":157,"props":3062,"children":3063},{"style":504},[3064],{"type":39,"value":865},{"type":26,"tag":157,"props":3066,"children":3067},{"style":164},[3068],{"type":39,"value":193},{"type":26,"tag":157,"props":3070,"children":3071},{"class":159,"line":1158},[3072,3076],{"type":26,"tag":157,"props":3073,"children":3074},{"style":174},[3075],{"type":39,"value":1164},{"type":26,"tag":157,"props":3077,"children":3078},{"style":164},[3079],{"type":39,"value":422},{"type":26,"tag":157,"props":3081,"children":3082},{"class":159,"line":1171},[3083,3087],{"type":26,"tag":157,"props":3084,"children":3085},{"style":185},[3086],{"type":39,"value":1177},{"type":26,"tag":157,"props":3088,"children":3089},{"style":164},[3090],{"type":39,"value":193},{"type":26,"tag":157,"props":3092,"children":3093},{"class":159,"line":1184},[3094],{"type":26,"tag":157,"props":3095,"children":3096},{"style":185},[3097],{"type":39,"value":1190},{"type":26,"tag":157,"props":3099,"children":3100},{"class":159,"line":1193},[3101],{"type":26,"tag":157,"props":3102,"children":3103},{"style":164},[3104],{"type":39,"value":1199},{"type":26,"tag":157,"props":3106,"children":3107},{"class":159,"line":1202},[3108],{"type":26,"tag":157,"props":3109,"children":3110},{"style":164},[3111],{"type":39,"value":767},{"type":26,"tag":157,"props":3113,"children":3114},{"class":159,"line":1210},[3115],{"type":26,"tag":157,"props":3116,"children":3117},{"style":164},[3118],{"type":39,"value":1216},{"type":26,"tag":157,"props":3120,"children":3121},{"class":159,"line":1219},[3122],{"type":26,"tag":157,"props":3123,"children":3124},{"style":164},[3125],{"type":39,"value":1225},{"type":26,"tag":35,"props":3127,"children":3128},{},[3129],{"type":39,"value":3130},"or by using the CLI:",{"type":26,"tag":141,"props":3132,"children":3134},{"className":1233,"code":3133,"language":1235,"meta":7,"style":7},"composer config repositories.\u003Cgroup_id> composer https://\u003CDOMAIN-NAME>/api/v4/group/\u003Cgroup_id>/-/packages/composer/packages.json\n",[3135],{"type":26,"tag":76,"props":3136,"children":3137},{"__ignoreMap":7},[3138],{"type":26,"tag":157,"props":3139,"children":3140},{"class":159,"line":160},[3141,3145,3150,3155,3161,3166,3171,3176,3181,3186,3190,3195,3200,3204,3209,3213,3217,3221,3225],{"type":26,"tag":157,"props":3142,"children":3143},{"style":1245},[3144],{"type":39,"value":92},{"type":26,"tag":157,"props":3146,"children":3147},{"style":1250},[3148],{"type":39,"value":3149}," config",{"type":26,"tag":157,"props":3151,"children":3152},{"style":1250},[3153],{"type":39,"value":3154}," repositories.",{"type":26,"tag":157,"props":3156,"children":3158},{"style":3157},"--shiki-default:#F97583;--shiki-dark:#F97583;--shiki-sepia:#F92672",[3159],{"type":39,"value":3160},"\u003C",{"type":26,"tag":157,"props":3162,"children":3163},{"style":1250},[3164],{"type":39,"value":3165},"group_i",{"type":26,"tag":157,"props":3167,"children":3168},{"style":164},[3169],{"type":39,"value":3170},"d",{"type":26,"tag":157,"props":3172,"children":3173},{"style":3157},[3174],{"type":39,"value":3175},">",{"type":26,"tag":157,"props":3177,"children":3178},{"style":1250},[3179],{"type":39,"value":3180}," composer",{"type":26,"tag":157,"props":3182,"children":3183},{"style":1250},[3184],{"type":39,"value":3185}," https://",{"type":26,"tag":157,"props":3187,"children":3188},{"style":3157},[3189],{"type":39,"value":3160},{"type":26,"tag":157,"props":3191,"children":3192},{"style":1250},[3193],{"type":39,"value":3194},"DOMAIN-NAM",{"type":26,"tag":157,"props":3196,"children":3197},{"style":164},[3198],{"type":39,"value":3199},"E",{"type":26,"tag":157,"props":3201,"children":3202},{"style":3157},[3203],{"type":39,"value":3175},{"type":26,"tag":157,"props":3205,"children":3206},{"style":1250},[3207],{"type":39,"value":3208},"/api/v4/group/",{"type":26,"tag":157,"props":3210,"children":3211},{"style":3157},[3212],{"type":39,"value":3160},{"type":26,"tag":157,"props":3214,"children":3215},{"style":1250},[3216],{"type":39,"value":3165},{"type":26,"tag":157,"props":3218,"children":3219},{"style":164},[3220],{"type":39,"value":3170},{"type":26,"tag":157,"props":3222,"children":3223},{"style":3157},[3224],{"type":39,"value":3175},{"type":26,"tag":157,"props":3226,"children":3227},{"style":1250},[3228],{"type":39,"value":3229},"/-/packages/composer/packages.json\n",{"type":26,"tag":35,"props":3231,"children":3232},{},[3233],{"type":39,"value":3234},"And setup GitLab credentials:",{"type":26,"tag":141,"props":3236,"children":3238},{"className":1233,"code":3237,"language":1235,"meta":7,"style":7},"composer config gitlab-token.\u003CDOMAIN-NAME> \u003Cpersonal_access_token>\n",[3239],{"type":26,"tag":76,"props":3240,"children":3241},{"__ignoreMap":7},[3242],{"type":26,"tag":157,"props":3243,"children":3244},{"class":159,"line":160},[3245,3249,3253,3258,3262,3266,3270,3274,3279,3284,3289],{"type":26,"tag":157,"props":3246,"children":3247},{"style":1245},[3248],{"type":39,"value":92},{"type":26,"tag":157,"props":3250,"children":3251},{"style":1250},[3252],{"type":39,"value":3149},{"type":26,"tag":157,"props":3254,"children":3255},{"style":1250},[3256],{"type":39,"value":3257}," gitlab-token.",{"type":26,"tag":157,"props":3259,"children":3260},{"style":3157},[3261],{"type":39,"value":3160},{"type":26,"tag":157,"props":3263,"children":3264},{"style":1250},[3265],{"type":39,"value":3194},{"type":26,"tag":157,"props":3267,"children":3268},{"style":164},[3269],{"type":39,"value":3199},{"type":26,"tag":157,"props":3271,"children":3272},{"style":3157},[3273],{"type":39,"value":3175},{"type":26,"tag":157,"props":3275,"children":3276},{"style":3157},[3277],{"type":39,"value":3278}," \u003C",{"type":26,"tag":157,"props":3280,"children":3281},{"style":1250},[3282],{"type":39,"value":3283},"personal_access_toke",{"type":26,"tag":157,"props":3285,"children":3286},{"style":164},[3287],{"type":39,"value":3288},"n",{"type":26,"tag":157,"props":3290,"children":3291},{"style":3157},[3292],{"type":39,"value":3293},">\n",{"type":26,"tag":35,"props":3295,"children":3296},{},[3297,3299,3304],{"type":39,"value":3298},"You can read more about this process in the ",{"type":26,"tag":47,"props":3300,"children":3302},{"href":3301},"https://docs.gitlab.com/user/packages/composer_repository/#install-a-composer-package",[3303],{"type":39,"value":52},{"type":39,"value":54},{"type":26,"tag":35,"props":3306,"children":3307},{},[3308],{"type":39,"value":3309},"Now we require our package us usual:",{"type":26,"tag":141,"props":3311,"children":3312},{"className":1233,"code":1234,"language":1235,"meta":7,"style":7},[3313],{"type":26,"tag":76,"props":3314,"children":3315},{"__ignoreMap":7},[3316],{"type":26,"tag":157,"props":3317,"children":3318},{"class":159,"line":160},[3319,3323,3327],{"type":26,"tag":157,"props":3320,"children":3321},{"style":1245},[3322],{"type":39,"value":92},{"type":26,"tag":157,"props":3324,"children":3325},{"style":1250},[3326],{"type":39,"value":1253},{"type":26,"tag":157,"props":3328,"children":3329},{"style":1250},[3330],{"type":39,"value":1258},{"type":26,"tag":141,"props":3332,"children":3334},{"className":1973,"code":3333,"language":1975,"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",[3335],{"type":26,"tag":76,"props":3336,"children":3337},{"__ignoreMap":7},[3338,3345,3352,3359,3366,3373,3380,3387,3394,3401,3409,3417,3424,3431,3438,3445,3452,3459],{"type":26,"tag":157,"props":3339,"children":3340},{"class":159,"line":160},[3341],{"type":26,"tag":157,"props":3342,"children":3343},{},[3344],{"type":39,"value":1325},{"type":26,"tag":157,"props":3346,"children":3347},{"class":159,"line":170},[3348],{"type":26,"tag":157,"props":3349,"children":3350},{},[3351],{"type":39,"value":1333},{"type":26,"tag":157,"props":3353,"children":3354},{"class":159,"line":196},[3355],{"type":26,"tag":157,"props":3356,"children":3357},{},[3358],{"type":39,"value":2002},{"type":26,"tag":157,"props":3360,"children":3361},{"class":159,"line":218},[3362],{"type":26,"tag":157,"props":3363,"children":3364},{},[3365],{"type":39,"value":2010},{"type":26,"tag":157,"props":3367,"children":3368},{"class":159,"line":240},[3369],{"type":26,"tag":157,"props":3370,"children":3371},{},[3372],{"type":39,"value":1357},{"type":26,"tag":157,"props":3374,"children":3375},{"class":159,"line":254},[3376],{"type":26,"tag":157,"props":3377,"children":3378},{},[3379],{"type":39,"value":2025},{"type":26,"tag":157,"props":3381,"children":3382},{"class":159,"line":276},[3383],{"type":26,"tag":157,"props":3384,"children":3385},{},[3386],{"type":39,"value":1373},{"type":26,"tag":157,"props":3388,"children":3389},{"class":159,"line":298},[3390],{"type":26,"tag":157,"props":3391,"children":3392},{},[3393],{"type":39,"value":1381},{"type":26,"tag":157,"props":3395,"children":3396},{"class":159,"line":320},[3397],{"type":26,"tag":157,"props":3398,"children":3399},{},[3400],{"type":39,"value":1389},{"type":26,"tag":157,"props":3402,"children":3403},{"class":159,"line":342},[3404],{"type":26,"tag":157,"props":3405,"children":3406},{},[3407],{"type":39,"value":3408},"  - Downloading acme/sample-plugin (1.0.0)\n",{"type":26,"tag":157,"props":3410,"children":3411},{"class":159,"line":363},[3412],{"type":26,"tag":157,"props":3413,"children":3414},{},[3415],{"type":39,"value":3416},"  - Installing acme/sample-plugin (1.0.0): Extracting archive\n",{"type":26,"tag":157,"props":3418,"children":3419},{"class":159,"line":384},[3420],{"type":26,"tag":157,"props":3421,"children":3422},{},[3423],{"type":39,"value":1413},{"type":26,"tag":157,"props":3425,"children":3426},{"class":159,"line":402},[3427],{"type":26,"tag":157,"props":3428,"children":3429},{"emptyLinePlaceholder":1419},[3430],{"type":39,"value":1422},{"type":26,"tag":157,"props":3432,"children":3433},{"class":159,"line":411},[3434],{"type":26,"tag":157,"props":3435,"children":3436},{},[3437],{"type":39,"value":1430},{"type":26,"tag":157,"props":3439,"children":3440},{"class":159,"line":425},[3441],{"type":26,"tag":157,"props":3442,"children":3443},{"emptyLinePlaceholder":1419},[3444],{"type":39,"value":1422},{"type":26,"tag":157,"props":3446,"children":3447},{"class":159,"line":434},[3448],{"type":26,"tag":157,"props":3449,"children":3450},{},[3451],{"type":39,"value":1445},{"type":26,"tag":157,"props":3453,"children":3454},{"class":159,"line":456},[3455],{"type":26,"tag":157,"props":3456,"children":3457},{"emptyLinePlaceholder":1419},[3458],{"type":39,"value":1422},{"type":26,"tag":157,"props":3460,"children":3461},{"class":159,"line":478},[3462],{"type":26,"tag":157,"props":3463,"children":3464},{},[3465],{"type":39,"value":2112},{"type":26,"tag":35,"props":3467,"children":3468},{},[3469],{"type":26,"tag":157,"props":3470,"children":3473},{"className":3471},[3472],"text-h2",[3474],{"type":39,"value":3475},"Awesome. Direct package download!",{"type":26,"tag":122,"props":3477,"children":3479},{"id":3478},"why-bother",[3480],{"type":39,"value":3481},"Why bother?",{"type":26,"tag":35,"props":3483,"children":3484},{},[3485,3487,3493,3495,3501],{"type":39,"value":3486},"This is an excellent question. The main reason is package caching. When running in a ",{"type":26,"tag":76,"props":3488,"children":3490},{"className":3489},[],[3491],{"type":39,"value":3492},"CI/CD",{"type":39,"value":3494}," environment or ",{"type":26,"tag":76,"props":3496,"children":3498},{"className":3497},[],[3499],{"type":39,"value":3500},"docker build",{"type":39,"value":3502},",\ncaching packages can give you a massive performance boost.",{"type":26,"tag":1270,"props":3504,"children":3505},{},[],{"type":26,"tag":3507,"props":3508,"children":3509},"hr",{},[],{"type":26,"tag":110,"props":3511,"children":3513},{"id":3512},"release-pipeline",[3514],{"type":39,"value":3515},"Release pipeline",{"type":26,"tag":122,"props":3517,"children":3519},{"id":3518},"with-manual-tagging",[3520],{"type":39,"value":3521},"With manual tagging",{"type":26,"tag":35,"props":3523,"children":3524},{},[3525],{"type":39,"value":3526},"This is a simple pipeline when you need to manually create and push a git tag.",{"type":26,"tag":35,"props":3528,"children":3529},{},[3530,3532,3537,3538],{"type":39,"value":3531},"Make sure to always update the ",{"type":26,"tag":76,"props":3533,"children":3535},{"className":3534},[],[3536],{"type":39,"value":1492},{"type":39,"value":1494},{"type":26,"tag":76,"props":3539,"children":3541},{"className":3540},[],[3542],{"type":39,"value":1500},{"type":26,"tag":141,"props":3544,"children":3546},{"className":1233,"code":3545,"language":1235,"meta":7,"style":7},"git tag \u003Cversion>\ngit push --tags\n",[3547],{"type":26,"tag":76,"props":3548,"children":3549},{"__ignoreMap":7},[3550,3578],{"type":26,"tag":157,"props":3551,"children":3552},{"class":159,"line":160},[3553,3557,3561,3565,3570,3574],{"type":26,"tag":157,"props":3554,"children":3555},{"style":1245},[3556],{"type":39,"value":1456},{"type":26,"tag":157,"props":3558,"children":3559},{"style":1250},[3560],{"type":39,"value":1922},{"type":26,"tag":157,"props":3562,"children":3563},{"style":3157},[3564],{"type":39,"value":3278},{"type":26,"tag":157,"props":3566,"children":3567},{"style":1250},[3568],{"type":39,"value":3569},"versio",{"type":26,"tag":157,"props":3571,"children":3572},{"style":164},[3573],{"type":39,"value":3288},{"type":26,"tag":157,"props":3575,"children":3576},{"style":3157},[3577],{"type":39,"value":3293},{"type":26,"tag":157,"props":3579,"children":3580},{"class":159,"line":170},[3581,3585,3589],{"type":26,"tag":157,"props":3582,"children":3583},{"style":1245},[3584],{"type":39,"value":1456},{"type":26,"tag":157,"props":3586,"children":3587},{"style":1250},[3588],{"type":39,"value":1939},{"type":26,"tag":157,"props":3590,"children":3591},{"style":504},[3592],{"type":39,"value":1944},{"type":26,"tag":141,"props":3594,"children":3599},{"className":3595,"code":3596,"filename":3597,"language":3598,"meta":7,"style":7},"language-yaml shiki shiki-themes github-dark github-dark monokai","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","yaml",[3600],{"type":26,"tag":76,"props":3601,"children":3602},{"__ignoreMap":7},[3603,3617,3630,3637,3649,3666,3682,3694,3707,3724,3736],{"type":26,"tag":157,"props":3604,"children":3605},{"class":159,"line":160},[3606,3612],{"type":26,"tag":157,"props":3607,"children":3609},{"style":3608},"--shiki-default:#85E89D;--shiki-dark:#85E89D;--shiki-sepia:#F92672",[3610],{"type":39,"value":3611},"stages",{"type":26,"tag":157,"props":3613,"children":3614},{"style":164},[3615],{"type":39,"value":3616},":\n",{"type":26,"tag":157,"props":3618,"children":3619},{"class":159,"line":170},[3620,3625],{"type":26,"tag":157,"props":3621,"children":3622},{"style":164},[3623],{"type":39,"value":3624},"  - ",{"type":26,"tag":157,"props":3626,"children":3627},{"style":1250},[3628],{"type":39,"value":3629},"release\n",{"type":26,"tag":157,"props":3631,"children":3632},{"class":159,"line":196},[3633],{"type":26,"tag":157,"props":3634,"children":3635},{"emptyLinePlaceholder":1419},[3636],{"type":39,"value":1422},{"type":26,"tag":157,"props":3638,"children":3639},{"class":159,"line":218},[3640,3645],{"type":26,"tag":157,"props":3641,"children":3642},{"style":3608},[3643],{"type":39,"value":3644},"deploy",{"type":26,"tag":157,"props":3646,"children":3647},{"style":164},[3648],{"type":39,"value":3616},{"type":26,"tag":157,"props":3650,"children":3651},{"class":159,"line":240},[3652,3657,3661],{"type":26,"tag":157,"props":3653,"children":3654},{"style":3608},[3655],{"type":39,"value":3656},"  image",{"type":26,"tag":157,"props":3658,"children":3659},{"style":164},[3660],{"type":39,"value":182},{"type":26,"tag":157,"props":3662,"children":3663},{"style":1250},[3664],{"type":39,"value":3665},"alpine/curl\n",{"type":26,"tag":157,"props":3667,"children":3668},{"class":159,"line":254},[3669,3674,3678],{"type":26,"tag":157,"props":3670,"children":3671},{"style":3608},[3672],{"type":39,"value":3673},"  stage",{"type":26,"tag":157,"props":3675,"children":3676},{"style":164},[3677],{"type":39,"value":182},{"type":26,"tag":157,"props":3679,"children":3680},{"style":1250},[3681],{"type":39,"value":3629},{"type":26,"tag":157,"props":3683,"children":3684},{"class":159,"line":276},[3685,3690],{"type":26,"tag":157,"props":3686,"children":3687},{"style":3608},[3688],{"type":39,"value":3689},"  script",{"type":26,"tag":157,"props":3691,"children":3692},{"style":164},[3693],{"type":39,"value":3616},{"type":26,"tag":157,"props":3695,"children":3696},{"class":159,"line":298},[3697,3702],{"type":26,"tag":157,"props":3698,"children":3699},{"style":164},[3700],{"type":39,"value":3701},"    - ",{"type":26,"tag":157,"props":3703,"children":3704},{"style":1250},[3705],{"type":39,"value":3706},"'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":26,"tag":157,"props":3708,"children":3709},{"class":159,"line":320},[3710,3715,3719],{"type":26,"tag":157,"props":3711,"children":3712},{"style":3608},[3713],{"type":39,"value":3714},"  environment",{"type":26,"tag":157,"props":3716,"children":3717},{"style":164},[3718],{"type":39,"value":182},{"type":26,"tag":157,"props":3720,"children":3721},{"style":1250},[3722],{"type":39,"value":3723},"production\n",{"type":26,"tag":157,"props":3725,"children":3726},{"class":159,"line":342},[3727,3732],{"type":26,"tag":157,"props":3728,"children":3729},{"style":3608},[3730],{"type":39,"value":3731},"  rules",{"type":26,"tag":157,"props":3733,"children":3734},{"style":164},[3735],{"type":39,"value":3616},{"type":26,"tag":157,"props":3737,"children":3738},{"class":159,"line":363},[3739,3744,3748],{"type":26,"tag":157,"props":3740,"children":3741},{"style":3608},[3742],{"type":39,"value":3743},"    if",{"type":26,"tag":157,"props":3745,"children":3746},{"style":164},[3747],{"type":39,"value":182},{"type":26,"tag":157,"props":3749,"children":3750},{"style":1250},[3751],{"type":39,"value":3752},"$CI_COMMIT_TAG\n",{"type":26,"tag":122,"props":3754,"children":3756},{"id":3755},"with-semantic-release",[3757],{"type":39,"value":3758},"With semantic-release",{"type":26,"tag":35,"props":3760,"children":3761},{},[3762],{"type":39,"value":3763},"It would be a lot easier if we could just push our changes and don't care about versioning and tagging.",{"type":26,"tag":35,"props":3765,"children":3766},{},[3767,3773],{"type":26,"tag":47,"props":3768,"children":3770},{"href":3769},"https://github.com/semantic-release/semantic-release",[3771],{"type":39,"value":3772},"semantic-release",{"type":39,"value":3774}," automates the whole package release workflow.",{"type":26,"tag":35,"props":3776,"children":3777},{},[3778,3780,3786],{"type":39,"value":3779},"Please follow the ",{"type":26,"tag":47,"props":3781,"children":3783},{"href":3782},"https://github.com/semantic-release/gitlab?tab=readme-ov-file#gitlab-authentication",[3784],{"type":39,"value":3785},"GitLab authentication instruction",{"type":39,"value":3787}," before you continue to read.",{"type":26,"tag":141,"props":3789,"children":3792},{"className":3595,"code":3790,"filename":3791,"language":3598,"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",[3793],{"type":26,"tag":76,"props":3794,"children":3795},{"__ignoreMap":7},[3796,3807,3818,3825,3837,3852,3863,3880,3903,3919,3930,3942,3953,3974,3991],{"type":26,"tag":157,"props":3797,"children":3798},{"class":159,"line":160},[3799,3803],{"type":26,"tag":157,"props":3800,"children":3801},{"style":3608},[3802],{"type":39,"value":3611},{"type":26,"tag":157,"props":3804,"children":3805},{"style":164},[3806],{"type":39,"value":3616},{"type":26,"tag":157,"props":3808,"children":3809},{"class":159,"line":170},[3810,3814],{"type":26,"tag":157,"props":3811,"children":3812},{"style":164},[3813],{"type":39,"value":3624},{"type":26,"tag":157,"props":3815,"children":3816},{"style":1250},[3817],{"type":39,"value":3629},{"type":26,"tag":157,"props":3819,"children":3820},{"class":159,"line":196},[3821],{"type":26,"tag":157,"props":3822,"children":3823},{"emptyLinePlaceholder":1419},[3824],{"type":39,"value":1422},{"type":26,"tag":157,"props":3826,"children":3827},{"class":159,"line":218},[3828,3833],{"type":26,"tag":157,"props":3829,"children":3830},{"style":3608},[3831],{"type":39,"value":3832},"release",{"type":26,"tag":157,"props":3834,"children":3835},{"style":164},[3836],{"type":39,"value":3616},{"type":26,"tag":157,"props":3838,"children":3839},{"class":159,"line":240},[3840,3844,3848],{"type":26,"tag":157,"props":3841,"children":3842},{"style":3608},[3843],{"type":39,"value":3673},{"type":26,"tag":157,"props":3845,"children":3846},{"style":164},[3847],{"type":39,"value":182},{"type":26,"tag":157,"props":3849,"children":3850},{"style":1250},[3851],{"type":39,"value":3629},{"type":26,"tag":157,"props":3853,"children":3854},{"class":159,"line":254},[3855,3859],{"type":26,"tag":157,"props":3856,"children":3857},{"style":3608},[3858],{"type":39,"value":3656},{"type":26,"tag":157,"props":3860,"children":3861},{"style":164},[3862],{"type":39,"value":3616},{"type":26,"tag":157,"props":3864,"children":3865},{"class":159,"line":276},[3866,3871,3875],{"type":26,"tag":157,"props":3867,"children":3868},{"style":3608},[3869],{"type":39,"value":3870},"    name",{"type":26,"tag":157,"props":3872,"children":3873},{"style":164},[3874],{"type":39,"value":182},{"type":26,"tag":157,"props":3876,"children":3877},{"style":1250},[3878],{"type":39,"value":3879},"ghcr.io/voxpupuli/semantic-release:25.0.0-latest\n",{"type":26,"tag":157,"props":3881,"children":3882},{"class":159,"line":298},[3883,3888,3893,3898],{"type":26,"tag":157,"props":3884,"children":3885},{"style":3608},[3886],{"type":39,"value":3887},"    entrypoint",{"type":26,"tag":157,"props":3889,"children":3890},{"style":164},[3891],{"type":39,"value":3892},": [",{"type":26,"tag":157,"props":3894,"children":3895},{"style":1250},[3896],{"type":39,"value":3897},"\"\"",{"type":26,"tag":157,"props":3899,"children":3900},{"style":164},[3901],{"type":39,"value":3902},"]\n",{"type":26,"tag":157,"props":3904,"children":3905},{"class":159,"line":320},[3906,3911,3915],{"type":26,"tag":157,"props":3907,"children":3908},{"style":3608},[3909],{"type":39,"value":3910},"  interruptible",{"type":26,"tag":157,"props":3912,"children":3913},{"style":164},[3914],{"type":39,"value":182},{"type":26,"tag":157,"props":3916,"children":3917},{"style":504},[3918],{"type":39,"value":507},{"type":26,"tag":157,"props":3920,"children":3921},{"class":159,"line":342},[3922,3926],{"type":26,"tag":157,"props":3923,"children":3924},{"style":3608},[3925],{"type":39,"value":3689},{"type":26,"tag":157,"props":3927,"children":3928},{"style":164},[3929],{"type":39,"value":3616},{"type":26,"tag":157,"props":3931,"children":3932},{"class":159,"line":363},[3933,3937],{"type":26,"tag":157,"props":3934,"children":3935},{"style":164},[3936],{"type":39,"value":3701},{"type":26,"tag":157,"props":3938,"children":3939},{"style":1250},[3940],{"type":39,"value":3941},"/container-entrypoint.sh\n",{"type":26,"tag":157,"props":3943,"children":3944},{"class":159,"line":384},[3945,3949],{"type":26,"tag":157,"props":3946,"children":3947},{"style":3608},[3948],{"type":39,"value":3731},{"type":26,"tag":157,"props":3950,"children":3951},{"style":164},[3952],{"type":39,"value":3616},{"type":26,"tag":157,"props":3954,"children":3955},{"class":159,"line":402},[3956,3960,3965,3969],{"type":26,"tag":157,"props":3957,"children":3958},{"style":164},[3959],{"type":39,"value":3701},{"type":26,"tag":157,"props":3961,"children":3962},{"style":3608},[3963],{"type":39,"value":3964},"if",{"type":26,"tag":157,"props":3966,"children":3967},{"style":164},[3968],{"type":39,"value":182},{"type":26,"tag":157,"props":3970,"children":3971},{"style":1250},[3972],{"type":39,"value":3973},"$CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH\n",{"type":26,"tag":157,"props":3975,"children":3976},{"class":159,"line":411},[3977,3982,3986],{"type":26,"tag":157,"props":3978,"children":3979},{"style":3608},[3980],{"type":39,"value":3981},"      when",{"type":26,"tag":157,"props":3983,"children":3984},{"style":164},[3985],{"type":39,"value":182},{"type":26,"tag":157,"props":3987,"children":3988},{"style":1250},[3989],{"type":39,"value":3990},"never\n",{"type":26,"tag":157,"props":3992,"children":3993},{"class":159,"line":425},[3994,3998,4002,4006],{"type":26,"tag":157,"props":3995,"children":3996},{"style":164},[3997],{"type":39,"value":3701},{"type":26,"tag":157,"props":3999,"children":4000},{"style":3608},[4001],{"type":39,"value":3964},{"type":26,"tag":157,"props":4003,"children":4004},{"style":164},[4005],{"type":39,"value":182},{"type":26,"tag":157,"props":4007,"children":4008},{"style":1250},[4009],{"type":39,"value":4010},"$CI_COMMIT_BRANCH\n",{"type":26,"tag":141,"props":4012,"children":4015},{"className":143,"code":4013,"filename":4014,"language":151,"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",[4016],{"type":26,"tag":76,"props":4017,"children":4018},{"__ignoreMap":7},[4019,4026,4038,4050,4058,4070,4078,4090,4098,4120,4167,4209,4217,4225,4232,4239,4246,4258,4265,4285,4312,4319,4326,4333,4345,4352,4387,4394,4401,4409],{"type":26,"tag":157,"props":4020,"children":4021},{"class":159,"line":160},[4022],{"type":26,"tag":157,"props":4023,"children":4024},{"style":164},[4025],{"type":39,"value":167},{"type":26,"tag":157,"props":4027,"children":4028},{"class":159,"line":170},[4029,4034],{"type":26,"tag":157,"props":4030,"children":4031},{"style":174},[4032],{"type":39,"value":4033},"  \"plugins\"",{"type":26,"tag":157,"props":4035,"children":4036},{"style":164},[4037],{"type":39,"value":422},{"type":26,"tag":157,"props":4039,"children":4040},{"class":159,"line":196},[4041,4046],{"type":26,"tag":157,"props":4042,"children":4043},{"style":185},[4044],{"type":39,"value":4045},"    \"@semantic-release/commit-analyzer\"",{"type":26,"tag":157,"props":4047,"children":4048},{"style":164},[4049],{"type":39,"value":193},{"type":26,"tag":157,"props":4051,"children":4052},{"class":159,"line":218},[4053],{"type":26,"tag":157,"props":4054,"children":4055},{"style":164},[4056],{"type":39,"value":4057},"    [\n",{"type":26,"tag":157,"props":4059,"children":4060},{"class":159,"line":240},[4061,4066],{"type":26,"tag":157,"props":4062,"children":4063},{"style":185},[4064],{"type":39,"value":4065},"      \"semantic-release-replace-plugin\"",{"type":26,"tag":157,"props":4067,"children":4068},{"style":164},[4069],{"type":39,"value":193},{"type":26,"tag":157,"props":4071,"children":4072},{"class":159,"line":254},[4073],{"type":26,"tag":157,"props":4074,"children":4075},{"style":164},[4076],{"type":39,"value":4077},"      {\n",{"type":26,"tag":157,"props":4079,"children":4080},{"class":159,"line":276},[4081,4086],{"type":26,"tag":157,"props":4082,"children":4083},{"style":174},[4084],{"type":39,"value":4085},"        \"replacements\"",{"type":26,"tag":157,"props":4087,"children":4088},{"style":164},[4089],{"type":39,"value":422},{"type":26,"tag":157,"props":4091,"children":4092},{"class":159,"line":298},[4093],{"type":26,"tag":157,"props":4094,"children":4095},{"style":164},[4096],{"type":39,"value":4097},"          {\n",{"type":26,"tag":157,"props":4099,"children":4100},{"class":159,"line":320},[4101,4106,4110,4115],{"type":26,"tag":157,"props":4102,"children":4103},{"style":174},[4104],{"type":39,"value":4105},"            \"files\"",{"type":26,"tag":157,"props":4107,"children":4108},{"style":164},[4109],{"type":39,"value":3892},{"type":26,"tag":157,"props":4111,"children":4112},{"style":185},[4113],{"type":39,"value":4114},"\"composer.json\"",{"type":26,"tag":157,"props":4116,"children":4117},{"style":164},[4118],{"type":39,"value":4119},"],\n",{"type":26,"tag":157,"props":4121,"children":4122},{"class":159,"line":342},[4123,4128,4132,4137,4142,4146,4150,4155,4159,4163],{"type":26,"tag":157,"props":4124,"children":4125},{"style":174},[4126],{"type":39,"value":4127},"            \"from\"",{"type":26,"tag":157,"props":4129,"children":4130},{"style":164},[4131],{"type":39,"value":182},{"type":26,"tag":157,"props":4133,"children":4134},{"style":185},[4135],{"type":39,"value":4136},"\"version",{"type":26,"tag":157,"props":4138,"children":4139},{"style":504},[4140],{"type":39,"value":4141},"\\\"",{"type":26,"tag":157,"props":4143,"children":4144},{"style":185},[4145],{"type":39,"value":182},{"type":26,"tag":157,"props":4147,"children":4148},{"style":504},[4149],{"type":39,"value":4141},{"type":26,"tag":157,"props":4151,"children":4152},{"style":185},[4153],{"type":39,"value":4154},".*",{"type":26,"tag":157,"props":4156,"children":4157},{"style":504},[4158],{"type":39,"value":4141},{"type":26,"tag":157,"props":4160,"children":4161},{"style":185},[4162],{"type":39,"value":822},{"type":26,"tag":157,"props":4164,"children":4165},{"style":164},[4166],{"type":39,"value":193},{"type":26,"tag":157,"props":4168,"children":4169},{"class":159,"line":363},[4170,4175,4179,4183,4187,4191,4195,4200,4204],{"type":26,"tag":157,"props":4171,"children":4172},{"style":174},[4173],{"type":39,"value":4174},"            \"to\"",{"type":26,"tag":157,"props":4176,"children":4177},{"style":164},[4178],{"type":39,"value":182},{"type":26,"tag":157,"props":4180,"children":4181},{"style":185},[4182],{"type":39,"value":4136},{"type":26,"tag":157,"props":4184,"children":4185},{"style":504},[4186],{"type":39,"value":4141},{"type":26,"tag":157,"props":4188,"children":4189},{"style":185},[4190],{"type":39,"value":182},{"type":26,"tag":157,"props":4192,"children":4193},{"style":504},[4194],{"type":39,"value":4141},{"type":26,"tag":157,"props":4196,"children":4197},{"style":185},[4198],{"type":39,"value":4199},"${nextRelease.version}",{"type":26,"tag":157,"props":4201,"children":4202},{"style":504},[4203],{"type":39,"value":4141},{"type":26,"tag":157,"props":4205,"children":4206},{"style":185},[4207],{"type":39,"value":4208},"\"\n",{"type":26,"tag":157,"props":4210,"children":4211},{"class":159,"line":384},[4212],{"type":26,"tag":157,"props":4213,"children":4214},{"style":164},[4215],{"type":39,"value":4216},"          }\n",{"type":26,"tag":157,"props":4218,"children":4219},{"class":159,"line":402},[4220],{"type":26,"tag":157,"props":4221,"children":4222},{"style":164},[4223],{"type":39,"value":4224},"        ]\n",{"type":26,"tag":157,"props":4226,"children":4227},{"class":159,"line":411},[4228],{"type":26,"tag":157,"props":4229,"children":4230},{"style":164},[4231],{"type":39,"value":516},{"type":26,"tag":157,"props":4233,"children":4234},{"class":159,"line":425},[4235],{"type":26,"tag":157,"props":4236,"children":4237},{"style":164},[4238],{"type":39,"value":1070},{"type":26,"tag":157,"props":4240,"children":4241},{"class":159,"line":434},[4242],{"type":26,"tag":157,"props":4243,"children":4244},{"style":164},[4245],{"type":39,"value":4057},{"type":26,"tag":157,"props":4247,"children":4248},{"class":159,"line":456},[4249,4254],{"type":26,"tag":157,"props":4250,"children":4251},{"style":185},[4252],{"type":39,"value":4253},"      \"@semantic-release/git\"",{"type":26,"tag":157,"props":4255,"children":4256},{"style":164},[4257],{"type":39,"value":193},{"type":26,"tag":157,"props":4259,"children":4260},{"class":159,"line":478},[4261],{"type":26,"tag":157,"props":4262,"children":4263},{"style":164},[4264],{"type":39,"value":4077},{"type":26,"tag":157,"props":4266,"children":4267},{"class":159,"line":491},[4268,4273,4277,4281],{"type":26,"tag":157,"props":4269,"children":4270},{"style":174},[4271],{"type":39,"value":4272},"        \"assets\"",{"type":26,"tag":157,"props":4274,"children":4275},{"style":164},[4276],{"type":39,"value":3892},{"type":26,"tag":157,"props":4278,"children":4279},{"style":185},[4280],{"type":39,"value":4114},{"type":26,"tag":157,"props":4282,"children":4283},{"style":164},[4284],{"type":39,"value":4119},{"type":26,"tag":157,"props":4286,"children":4287},{"class":159,"line":510},[4288,4293,4297,4302,4307],{"type":26,"tag":157,"props":4289,"children":4290},{"style":174},[4291],{"type":39,"value":4292},"        \"message\"",{"type":26,"tag":157,"props":4294,"children":4295},{"style":164},[4296],{"type":39,"value":182},{"type":26,"tag":157,"props":4298,"children":4299},{"style":185},[4300],{"type":39,"value":4301},"\"chore(release): ${nextRelease.version} [skip ci]",{"type":26,"tag":157,"props":4303,"children":4304},{"style":504},[4305],{"type":39,"value":4306},"\\n\\n",{"type":26,"tag":157,"props":4308,"children":4309},{"style":185},[4310],{"type":39,"value":4311},"${nextRelease.notes}\"\n",{"type":26,"tag":157,"props":4313,"children":4314},{"class":159,"line":519},[4315],{"type":26,"tag":157,"props":4316,"children":4317},{"style":164},[4318],{"type":39,"value":516},{"type":26,"tag":157,"props":4320,"children":4321},{"class":159,"line":528},[4322],{"type":26,"tag":157,"props":4323,"children":4324},{"style":164},[4325],{"type":39,"value":1070},{"type":26,"tag":157,"props":4327,"children":4328},{"class":159,"line":536},[4329],{"type":26,"tag":157,"props":4330,"children":4331},{"style":164},[4332],{"type":39,"value":4057},{"type":26,"tag":157,"props":4334,"children":4335},{"class":159,"line":556},[4336,4341],{"type":26,"tag":157,"props":4337,"children":4338},{"style":185},[4339],{"type":39,"value":4340},"      \"@semantic-release/exec\"",{"type":26,"tag":157,"props":4342,"children":4343},{"style":164},[4344],{"type":39,"value":193},{"type":26,"tag":157,"props":4346,"children":4347},{"class":159,"line":577},[4348],{"type":26,"tag":157,"props":4349,"children":4350},{"style":164},[4351],{"type":39,"value":4077},{"type":26,"tag":157,"props":4353,"children":4354},{"class":159,"line":589},[4355,4360,4364,4369,4373,4378,4382],{"type":26,"tag":157,"props":4356,"children":4357},{"style":174},[4358],{"type":39,"value":4359},"        \"publishCmd\"",{"type":26,"tag":157,"props":4361,"children":4362},{"style":164},[4363],{"type":39,"value":182},{"type":26,"tag":157,"props":4365,"children":4366},{"style":185},[4367],{"type":39,"value":4368},"\"curl --fail-with-body --header ",{"type":26,"tag":157,"props":4370,"children":4371},{"style":504},[4372],{"type":39,"value":4141},{"type":26,"tag":157,"props":4374,"children":4375},{"style":185},[4376],{"type":39,"value":4377},"Job-Token: ${process.env.CI_JOB_TOKEN}",{"type":26,"tag":157,"props":4379,"children":4380},{"style":504},[4381],{"type":39,"value":4141},{"type":26,"tag":157,"props":4383,"children":4384},{"style":185},[4385],{"type":39,"value":4386}," --data tag=${nextRelease.gitTag} ${process.env.CI_API_V4_URL}/projects/${process.env.CI_PROJECT_ID}/packages/composer\"\n",{"type":26,"tag":157,"props":4388,"children":4389},{"class":159,"line":605},[4390],{"type":26,"tag":157,"props":4391,"children":4392},{"style":164},[4393],{"type":39,"value":516},{"type":26,"tag":157,"props":4395,"children":4396},{"class":159,"line":613},[4397],{"type":26,"tag":157,"props":4398,"children":4399},{"style":164},[4400],{"type":39,"value":1100},{"type":26,"tag":157,"props":4402,"children":4403},{"class":159,"line":621},[4404],{"type":26,"tag":157,"props":4405,"children":4406},{"style":164},[4407],{"type":39,"value":4408},"  ]\n",{"type":26,"tag":157,"props":4410,"children":4411},{"class":159,"line":629},[4412],{"type":26,"tag":157,"props":4413,"children":4414},{"style":164},[4415],{"type":39,"value":1225},{"type":26,"tag":35,"props":4417,"children":4418},{},[4419],{"type":39,"value":4420},"This will:",{"type":26,"tag":66,"props":4422,"children":4423},{},[4424,4429,4439,4451,4456],{"type":26,"tag":70,"props":4425,"children":4426},{},[4427],{"type":39,"value":4428},"Analise the commits from the last release to decide if a new version should be released",{"type":26,"tag":70,"props":4430,"children":4431},{},[4432,4434],{"type":39,"value":4433},"Update the version in ",{"type":26,"tag":76,"props":4435,"children":4437},{"className":4436},[],[4438],{"type":39,"value":1500},{"type":26,"tag":70,"props":4440,"children":4441},{},[4442,4444,4449],{"type":39,"value":4443},"Commit the ",{"type":26,"tag":76,"props":4445,"children":4447},{"className":4446},[],[4448],{"type":39,"value":1500},{"type":39,"value":4450}," back into the repo",{"type":26,"tag":70,"props":4452,"children":4453},{},[4454],{"type":39,"value":4455},"Create a tag",{"type":26,"tag":70,"props":4457,"children":4458},{},[4459],{"type":39,"value":4460},"Release a composer package from this tag",{"type":26,"tag":4462,"props":4463,"children":4464},"style",{},[4465],{"type":39,"value":4466},"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":170,"depth":170,"links":4468},[4469,4475],{"id":112,"depth":170,"text":115,"children":4470},[4471,4472,4473,4474],{"id":124,"depth":196,"text":127},{"id":1466,"depth":196,"text":1469},{"id":2127,"depth":196,"text":2130},{"id":3478,"depth":196,"text":3481},{"id":3512,"depth":170,"text":3515,"children":4476},[4477,4478],{"id":3518,"depth":196,"text":3521},{"id":3755,"depth":196,"text":3758},"markdown","common:en:blog:18.shopware-plugin-gitlab-pipeline-release.md","common","en/blog/18.shopware-plugin-gitlab-pipeline-release.md","en/blog/18.shopware-plugin-gitlab-pipeline-release","md",{"_path":4486,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":4487,"description":4488,"author":10,"image":11,"releaseDate":4489,"blogCategories":4490,"articleTags":4491,"tags":4492,"_type":4479,"_id":4493,"_source":4481,"_file":4494,"_stem":4495,"_extension":4484},"/en/blog/gitops-docker-renovate","Software management with GitLab, Renovate Bot and Docker","Managing software on a server is not easy. Is it?","2025-10-30",[14,15],[15,17],[21],"common:en:blog:17.gitops-docker-renovate.md","en/blog/17.gitops-docker-renovate.md","en/blog/17.gitops-docker-renovate",{"_path":4497,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":4498,"description":4499,"author":10,"image":11,"releaseDate":4500,"blogCategories":4501,"articleTags":4502,"tags":4503,"_type":4479,"_id":4504,"_source":4481,"_file":4505,"_stem":4506,"_extension":4484},"/en/blog/traefik-magic","Using Traefik as reverse proxy - convention over configuration","How to configure Traefik reverse proxy to get rid of any Traefik specific labels and automatically route to subdomains matching compose project name","2026-03-13",[14,15],[15],[21],"common:en:blog:21.traefik-magic.md","en/blog/21.traefik-magic.md","en/blog/21.traefik-magic",{"_path":4508},"/blog/shopware-plugin-gitlab-pipeline-release",{"_path":4},{"_path":4511,"_dir":4512,"_draft":6,"_partial":6,"_locale":7,"slug":10,"teams":4513,"primaryTeam":4515,"firstName":4516,"lastName":4517,"prefixTitle":7,"suffixTitle":4518,"education":4519,"role":4524,"workingSince":4529,"inTheCompanySince":4530,"techSkills":4531,"skills":4570,"projects":4587,"contactDetails":4597,"_image":4601,"image":4602,"_id":4603,"_type":151,"title":4604,"_source":4512,"_file":4605,"_stem":4606,"_extension":151},"/employees/robert-juzak","employees",[4514,4515],"appDev","devOps","Robert","Juzak","B.Sc.",[4520],[4521,4522,4523],"Bachelor of Computer Science","Technische Universität Breslau","2016",[4525,4526,4527,4528],"softwareDeveloper","fullstackDeveloper","admin","consultant","2015","2018",[4532,4536,4538,4541,4544,4547,4549,4552,4555,4559,4562,4564,4567],{"name":4533,"level":4534,"icon":4535},"Docker","expert","/images/Docker.svg",{"name":4537,"level":4534},"GitLab",{"name":4539,"level":4534,"icon":4540},"Kubernetes","/images/Kubernetes.svg",{"name":4542,"level":4534,"icon":4543},"PHPUnit","/images/PHP-Unit.svg",{"name":4545,"level":4534,"icon":4546},"Portainer","/images/Portainer.svg",{"name":4548,"level":4534},"Sentry",{"name":4550,"level":4534,"icon":4551},"Sonarqube","/images/Sonarqube.svg",{"name":4553,"level":4534,"icon":4554},"Linux","/images/linux_os-mono.svg",{"name":4556,"level":4557,"icon":4558},"CSS","advanced","/images/css.svg",{"name":4560,"level":4557,"icon":4561},"HTML","/images/html.svg",{"name":4563,"level":4557},"PHP",{"name":4565,"level":4557,"icon":4566},"SQL","/images/SQL.svg",{"name":4568,"level":4557,"icon":4569},"VueJS","/images/vuejs.svg",[4571,4572,4574,4575,4577,4579,4581,4583,4585],{"name":3492,"level":4534},{"name":4573,"level":4534},"qualityAssurance",{"name":4515,"level":4534},{"name":4576,"level":4534},"testDrivenBugfix",{"name":4578,"level":4534},"testDrivenDevelopment",{"name":4580,"level":4557},"accessibility",{"name":4582,"level":4557},"databases",{"name":4584,"level":4557},"linuxServerAdministration",{"name":4586,"level":4557},"softwareArchitect",[4588,4593,4595],{"project":4589,"position":4590},"Herole",[4591,4592],"Dev-Ops","Frontend Developer",{"project":4594,"position":4592},"Huawei-Calibration-aaS",{"project":4596,"position":4592},"Huawei-Inspect-3D",{"eMail":4598,"phone":4599,"visibility":4600},"robert.juzak@helmundwalter.de","+49 351 799 035 26","1","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":4486,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":4487,"description":4488,"author":10,"image":11,"releaseDate":4489,"blogCategories":4608,"articleTags":4609,"tags":4610,"body":4611,"_type":4479,"_id":4493,"_source":4481,"_file":4494,"_stem":4495,"_extension":4484},[14,15],[15,17],[21],{"type":23,"children":4612,"toc":6079},[4613,4618,4623,4628,4633,4638,4657,4662,4704,4710,4723,4736,4741,4747,4760,4773,4782,4788,4793,4906,5431,5466,5477,5480,5485,5647,5660,5666,5671,5741,5746,5752,5757,5768,5781,5815,5842,5854,5875,5888,5891,5896,5909,5927,5932,5937,6057,6075],{"type":26,"tag":35,"props":4614,"children":4615},{},[4616],{"type":39,"value":4617},"Managing a multiservice server can be tricky. Not every software is compatible with another, for example different requirements for database or PHP-versions.",{"type":26,"tag":35,"props":4619,"children":4620},{},[4621],{"type":39,"value":4622},"Additionally, all the software should be in the latest version, to mitigate possible security risks.",{"type":26,"tag":35,"props":4624,"children":4625},{},[4626],{"type":39,"value":4627},"There are many ways to handle this: Ansible, Chef etc.",{"type":26,"tag":35,"props":4629,"children":4630},{},[4631],{"type":39,"value":4632},"Out goal was to have an easy to use, automated and free solution.",{"type":26,"tag":35,"props":4634,"children":4635},{},[4636],{"type":39,"value":4637},"Here are the goals:",{"type":26,"tag":4639,"props":4640,"children":4641},"ul",{},[4642,4647,4652],{"type":26,"tag":70,"props":4643,"children":4644},{},[4645],{"type":39,"value":4646},"use the GitOps approach to store and version control the deployment",{"type":26,"tag":70,"props":4648,"children":4649},{},[4650],{"type":39,"value":4651},"use containers to run the software",{"type":26,"tag":70,"props":4653,"children":4654},{},[4655],{"type":39,"value":4656},"get automated security updates and opt in for minor/major version updates",{"type":26,"tag":35,"props":4658,"children":4659},{},[4660],{"type":39,"value":4661},"This is the stack we ended with:",{"type":26,"tag":4639,"props":4663,"children":4664},{},[4665,4683,4693],{"type":26,"tag":70,"props":4666,"children":4667},{},[4668,4673,4675,4681],{"type":26,"tag":47,"props":4669,"children":4671},{"href":4670},"https://www.docker.com/",[4672],{"type":39,"value":4533},{"type":39,"value":4674}," and ",{"type":26,"tag":47,"props":4676,"children":4678},{"href":4677},"https://docs.docker.com/compose/",[4679],{"type":39,"value":4680},"Docker Compose",{"type":39,"value":4682}," do manage the software",{"type":26,"tag":70,"props":4684,"children":4685},{},[4686,4691],{"type":26,"tag":47,"props":4687,"children":4689},{"href":4688},"https://about.gitlab.com/",[4690],{"type":39,"value":4537},{"type":39,"value":4692}," to store all the compose files",{"type":26,"tag":70,"props":4694,"children":4695},{},[4696,4702],{"type":26,"tag":47,"props":4697,"children":4699},{"href":4698},"https://docs.renovatebot.com",[4700],{"type":39,"value":4701},"Renovate Bot",{"type":39,"value":4703}," to keep the software up to date",{"type":26,"tag":110,"props":4705,"children":4707},{"id":4706},"about-the-stack",[4708],{"type":39,"value":4709},"About the stack",{"type":26,"tag":35,"props":4711,"children":4712},{},[4713,4715,4721],{"type":39,"value":4714},"We have been using Docker in production for some time now. Depending on the situation, we create the compose file directly on the server, manage it over portainer or ",{"type":26,"tag":76,"props":4716,"children":4718},{"className":4717},[],[4719],{"type":39,"value":4720},"scp",{"type":39,"value":4722}," it from a pipeline.",{"type":26,"tag":35,"props":4724,"children":4725},{},[4726,4728,4734],{"type":39,"value":4727},"GitLab is out primary tool for version control. Additionally, a ",{"type":26,"tag":47,"props":4729,"children":4731},{"href":4730},"https://docs.gitlab.com/runner/",[4732],{"type":39,"value":4733},"GitLab Runner",{"type":39,"value":4735}," takes care of running pipelines.",{"type":26,"tag":35,"props":4737,"children":4738},{},[4739],{"type":39,"value":4740},"Renovate automates dependency updates. PHP, Go, Python, Docker - to name a couple. We already use it for various projects.",{"type":26,"tag":110,"props":4742,"children":4744},{"id":4743},"container-with-docker-and-docker-compose",[4745],{"type":39,"value":4746},"Container with Docker and Docker Compose",{"type":26,"tag":35,"props":4748,"children":4749},{},[4750,4752,4758],{"type":39,"value":4751},"The main reason why we chose Docker is the ability to access a remote Docker host and execute Docker commands.\nRefer to ",{"type":26,"tag":47,"props":4753,"children":4755},{"href":4754},"https://docs.docker.com/reference/cli/docker/#host",[4756],{"type":39,"value":4757},"the official documentation",{"type":39,"value":4759}," for more information.",{"type":26,"tag":35,"props":4761,"children":4762},{},[4763,4765,4771],{"type":39,"value":4764},"We are using ",{"type":26,"tag":76,"props":4766,"children":4768},{"className":4767},[],[4769],{"type":39,"value":4770},"ssh",{"type":39,"value":4772}," to access our target server.",{"type":26,"tag":35,"props":4774,"children":4775},{},[4776],{"type":26,"tag":76,"props":4777,"children":4779},{"className":4778},[],[4780],{"type":39,"value":4781},"DOCKER_HOST=ssh://[username@]\u003CIP or host>[:port] docker compose up --wait",{"type":26,"tag":110,"props":4783,"children":4785},{"id":4784},"gitops-with-gitlab",[4786],{"type":39,"value":4787},"GitOps with GitLab",{"type":26,"tag":35,"props":4789,"children":4790},{},[4791],{"type":39,"value":4792},"The idea behind GitOps is to use a git repository to store the configuration. Here is an example:",{"type":26,"tag":141,"props":4794,"children":4796},{"className":1233,"code":4795,"language":1235,"meta":7,"style":7},".\n├──.gitlab-ci.yml             # pipeline definition\n├── renovate.json             # Renovate configuration\n├── nextcloud\n│   ├── docker-compose.yml   # Nextcloud file hosting and collaboration\n└── traefik\n    └── docker-compose.yml   # Traefik reverse proxy configuration\n\n",[4797],{"type":26,"tag":76,"props":4798,"children":4799},{"__ignoreMap":7},[4800,4809,4823,4841,4853,4876,4889],{"type":26,"tag":157,"props":4801,"children":4802},{"class":159,"line":160},[4803],{"type":26,"tag":157,"props":4804,"children":4806},{"style":4805},"--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#66D9EF",[4807],{"type":39,"value":4808},".\n",{"type":26,"tag":157,"props":4810,"children":4811},{"class":159,"line":170},[4812,4817],{"type":26,"tag":157,"props":4813,"children":4814},{"style":1245},[4815],{"type":39,"value":4816},"├──.gitlab-ci.yml",{"type":26,"tag":157,"props":4818,"children":4820},{"style":4819},"--shiki-default:#6A737D;--shiki-dark:#6A737D;--shiki-sepia:#88846F",[4821],{"type":39,"value":4822},"             # pipeline definition\n",{"type":26,"tag":157,"props":4824,"children":4825},{"class":159,"line":196},[4826,4831,4836],{"type":26,"tag":157,"props":4827,"children":4828},{"style":1245},[4829],{"type":39,"value":4830},"├──",{"type":26,"tag":157,"props":4832,"children":4833},{"style":1250},[4834],{"type":39,"value":4835}," renovate.json",{"type":26,"tag":157,"props":4837,"children":4838},{"style":4819},[4839],{"type":39,"value":4840},"             # Renovate configuration\n",{"type":26,"tag":157,"props":4842,"children":4843},{"class":159,"line":218},[4844,4848],{"type":26,"tag":157,"props":4845,"children":4846},{"style":1245},[4847],{"type":39,"value":4830},{"type":26,"tag":157,"props":4849,"children":4850},{"style":1250},[4851],{"type":39,"value":4852}," nextcloud\n",{"type":26,"tag":157,"props":4854,"children":4855},{"class":159,"line":240},[4856,4861,4866,4871],{"type":26,"tag":157,"props":4857,"children":4858},{"style":1245},[4859],{"type":39,"value":4860},"│",{"type":26,"tag":157,"props":4862,"children":4863},{"style":1250},[4864],{"type":39,"value":4865},"   ├──",{"type":26,"tag":157,"props":4867,"children":4868},{"style":1250},[4869],{"type":39,"value":4870}," docker-compose.yml",{"type":26,"tag":157,"props":4872,"children":4873},{"style":4819},[4874],{"type":39,"value":4875},"   # Nextcloud file hosting and collaboration\n",{"type":26,"tag":157,"props":4877,"children":4878},{"class":159,"line":254},[4879,4884],{"type":26,"tag":157,"props":4880,"children":4881},{"style":1245},[4882],{"type":39,"value":4883},"└──",{"type":26,"tag":157,"props":4885,"children":4886},{"style":1250},[4887],{"type":39,"value":4888}," traefik\n",{"type":26,"tag":157,"props":4890,"children":4891},{"class":159,"line":276},[4892,4897,4901],{"type":26,"tag":157,"props":4893,"children":4894},{"style":1245},[4895],{"type":39,"value":4896},"    └──",{"type":26,"tag":157,"props":4898,"children":4899},{"style":1250},[4900],{"type":39,"value":4870},{"type":26,"tag":157,"props":4902,"children":4903},{"style":4819},[4904],{"type":39,"value":4905},"   # Traefik reverse proxy configuration\n",{"type":26,"tag":141,"props":4907,"children":4910},{"className":3595,"code":4908,"filename":4909,"language":3598,"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",[4911],{"type":26,"tag":76,"props":4912,"children":4913},{"__ignoreMap":7},[4914,4926,4938,4950,4957,4969,4980,4997,5014,5026,5039,5051,5063,5075,5087,5099,5111,5123,5135,5147,5159,5208,5225,5242,5259,5266,5277,5293,5308,5320,5332,5349,5360,5372,5383,5395,5407,5419],{"type":26,"tag":157,"props":4915,"children":4916},{"class":159,"line":160},[4917,4922],{"type":26,"tag":157,"props":4918,"children":4919},{"style":3608},[4920],{"type":39,"value":4921},"volumes",{"type":26,"tag":157,"props":4923,"children":4924},{"style":164},[4925],{"type":39,"value":3616},{"type":26,"tag":157,"props":4927,"children":4928},{"class":159,"line":170},[4929,4934],{"type":26,"tag":157,"props":4930,"children":4931},{"style":3608},[4932],{"type":39,"value":4933},"  nextcloud",{"type":26,"tag":157,"props":4935,"children":4936},{"style":164},[4937],{"type":39,"value":3616},{"type":26,"tag":157,"props":4939,"children":4940},{"class":159,"line":196},[4941,4946],{"type":26,"tag":157,"props":4942,"children":4943},{"style":3608},[4944],{"type":39,"value":4945},"  db",{"type":26,"tag":157,"props":4947,"children":4948},{"style":164},[4949],{"type":39,"value":3616},{"type":26,"tag":157,"props":4951,"children":4952},{"class":159,"line":218},[4953],{"type":26,"tag":157,"props":4954,"children":4955},{"emptyLinePlaceholder":1419},[4956],{"type":39,"value":1422},{"type":26,"tag":157,"props":4958,"children":4959},{"class":159,"line":240},[4960,4965],{"type":26,"tag":157,"props":4961,"children":4962},{"style":3608},[4963],{"type":39,"value":4964},"services",{"type":26,"tag":157,"props":4966,"children":4967},{"style":164},[4968],{"type":39,"value":3616},{"type":26,"tag":157,"props":4970,"children":4971},{"class":159,"line":254},[4972,4976],{"type":26,"tag":157,"props":4973,"children":4974},{"style":3608},[4975],{"type":39,"value":4945},{"type":26,"tag":157,"props":4977,"children":4978},{"style":164},[4979],{"type":39,"value":3616},{"type":26,"tag":157,"props":4981,"children":4982},{"class":159,"line":276},[4983,4988,4992],{"type":26,"tag":157,"props":4984,"children":4985},{"style":3608},[4986],{"type":39,"value":4987},"    image",{"type":26,"tag":157,"props":4989,"children":4990},{"style":164},[4991],{"type":39,"value":182},{"type":26,"tag":157,"props":4993,"children":4994},{"style":1250},[4995],{"type":39,"value":4996},"mariadb:11.8\n",{"type":26,"tag":157,"props":4998,"children":4999},{"class":159,"line":298},[5000,5005,5009],{"type":26,"tag":157,"props":5001,"children":5002},{"style":3608},[5003],{"type":39,"value":5004},"    restart",{"type":26,"tag":157,"props":5006,"children":5007},{"style":164},[5008],{"type":39,"value":182},{"type":26,"tag":157,"props":5010,"children":5011},{"style":1250},[5012],{"type":39,"value":5013},"unless-stopped\n",{"type":26,"tag":157,"props":5015,"children":5016},{"class":159,"line":320},[5017,5022],{"type":26,"tag":157,"props":5018,"children":5019},{"style":3608},[5020],{"type":39,"value":5021},"    volumes",{"type":26,"tag":157,"props":5023,"children":5024},{"style":164},[5025],{"type":39,"value":3616},{"type":26,"tag":157,"props":5027,"children":5028},{"class":159,"line":342},[5029,5034],{"type":26,"tag":157,"props":5030,"children":5031},{"style":164},[5032],{"type":39,"value":5033},"      - ",{"type":26,"tag":157,"props":5035,"children":5036},{"style":1250},[5037],{"type":39,"value":5038},"db:/var/lib/mysql\n",{"type":26,"tag":157,"props":5040,"children":5041},{"class":159,"line":363},[5042,5047],{"type":26,"tag":157,"props":5043,"children":5044},{"style":3608},[5045],{"type":39,"value":5046},"    environment",{"type":26,"tag":157,"props":5048,"children":5049},{"style":164},[5050],{"type":39,"value":3616},{"type":26,"tag":157,"props":5052,"children":5053},{"class":159,"line":384},[5054,5058],{"type":26,"tag":157,"props":5055,"children":5056},{"style":164},[5057],{"type":39,"value":5033},{"type":26,"tag":157,"props":5059,"children":5060},{"style":1250},[5061],{"type":39,"value":5062},"MARIADB_ROOT_PASSWORD=${NEXTCLOUD_MARIADB_ROOT_PASSWORD:?error}\n",{"type":26,"tag":157,"props":5064,"children":5065},{"class":159,"line":402},[5066,5070],{"type":26,"tag":157,"props":5067,"children":5068},{"style":164},[5069],{"type":39,"value":5033},{"type":26,"tag":157,"props":5071,"children":5072},{"style":1250},[5073],{"type":39,"value":5074},"MARIADB_PASSWORD=${NEXTCLOUD_MARIADB_PASSWORD:?error}\n",{"type":26,"tag":157,"props":5076,"children":5077},{"class":159,"line":411},[5078,5082],{"type":26,"tag":157,"props":5079,"children":5080},{"style":164},[5081],{"type":39,"value":5033},{"type":26,"tag":157,"props":5083,"children":5084},{"style":1250},[5085],{"type":39,"value":5086},"MARIADB_DATABASE=nextcloud\n",{"type":26,"tag":157,"props":5088,"children":5089},{"class":159,"line":425},[5090,5094],{"type":26,"tag":157,"props":5091,"children":5092},{"style":164},[5093],{"type":39,"value":5033},{"type":26,"tag":157,"props":5095,"children":5096},{"style":1250},[5097],{"type":39,"value":5098},"MARIADB_USER=nextcloud\n",{"type":26,"tag":157,"props":5100,"children":5101},{"class":159,"line":434},[5102,5107],{"type":26,"tag":157,"props":5103,"children":5104},{"style":3608},[5105],{"type":39,"value":5106},"    command",{"type":26,"tag":157,"props":5108,"children":5109},{"style":164},[5110],{"type":39,"value":3616},{"type":26,"tag":157,"props":5112,"children":5113},{"class":159,"line":456},[5114,5118],{"type":26,"tag":157,"props":5115,"children":5116},{"style":164},[5117],{"type":39,"value":5033},{"type":26,"tag":157,"props":5119,"children":5120},{"style":1250},[5121],{"type":39,"value":5122},"--transaction-isolation=READ-COMMITTED\n",{"type":26,"tag":157,"props":5124,"children":5125},{"class":159,"line":478},[5126,5130],{"type":26,"tag":157,"props":5127,"children":5128},{"style":164},[5129],{"type":39,"value":5033},{"type":26,"tag":157,"props":5131,"children":5132},{"style":1250},[5133],{"type":39,"value":5134},"--log-bin=binlog\n",{"type":26,"tag":157,"props":5136,"children":5137},{"class":159,"line":491},[5138,5142],{"type":26,"tag":157,"props":5139,"children":5140},{"style":164},[5141],{"type":39,"value":5033},{"type":26,"tag":157,"props":5143,"children":5144},{"style":1250},[5145],{"type":39,"value":5146},"--binlog-format=ROW\n",{"type":26,"tag":157,"props":5148,"children":5149},{"class":159,"line":510},[5150,5155],{"type":26,"tag":157,"props":5151,"children":5152},{"style":3608},[5153],{"type":39,"value":5154},"    healthcheck",{"type":26,"tag":157,"props":5156,"children":5157},{"style":164},[5158],{"type":39,"value":3616},{"type":26,"tag":157,"props":5160,"children":5161},{"class":159,"line":519},[5162,5167,5171,5176,5181,5186,5190,5195,5199,5204],{"type":26,"tag":157,"props":5163,"children":5164},{"style":3608},[5165],{"type":39,"value":5166},"      test",{"type":26,"tag":157,"props":5168,"children":5169},{"style":164},[5170],{"type":39,"value":3892},{"type":26,"tag":157,"props":5172,"children":5173},{"style":1250},[5174],{"type":39,"value":5175},"\"CMD\"",{"type":26,"tag":157,"props":5177,"children":5178},{"style":164},[5179],{"type":39,"value":5180},", ",{"type":26,"tag":157,"props":5182,"children":5183},{"style":1250},[5184],{"type":39,"value":5185},"\"healthcheck.sh\"",{"type":26,"tag":157,"props":5187,"children":5188},{"style":164},[5189],{"type":39,"value":5180},{"type":26,"tag":157,"props":5191,"children":5192},{"style":1250},[5193],{"type":39,"value":5194},"\"--connect\"",{"type":26,"tag":157,"props":5196,"children":5197},{"style":164},[5198],{"type":39,"value":5180},{"type":26,"tag":157,"props":5200,"children":5201},{"style":1250},[5202],{"type":39,"value":5203},"\"--innodb_initialized\"",{"type":26,"tag":157,"props":5205,"children":5206},{"style":164},[5207],{"type":39,"value":3902},{"type":26,"tag":157,"props":5209,"children":5210},{"class":159,"line":528},[5211,5216,5220],{"type":26,"tag":157,"props":5212,"children":5213},{"style":3608},[5214],{"type":39,"value":5215},"      interval",{"type":26,"tag":157,"props":5217,"children":5218},{"style":164},[5219],{"type":39,"value":182},{"type":26,"tag":157,"props":5221,"children":5222},{"style":1250},[5223],{"type":39,"value":5224},"15s\n",{"type":26,"tag":157,"props":5226,"children":5227},{"class":159,"line":536},[5228,5233,5237],{"type":26,"tag":157,"props":5229,"children":5230},{"style":3608},[5231],{"type":39,"value":5232},"      timeout",{"type":26,"tag":157,"props":5234,"children":5235},{"style":164},[5236],{"type":39,"value":182},{"type":26,"tag":157,"props":5238,"children":5239},{"style":1250},[5240],{"type":39,"value":5241},"5s\n",{"type":26,"tag":157,"props":5243,"children":5244},{"class":159,"line":556},[5245,5250,5254],{"type":26,"tag":157,"props":5246,"children":5247},{"style":3608},[5248],{"type":39,"value":5249},"      retries",{"type":26,"tag":157,"props":5251,"children":5252},{"style":164},[5253],{"type":39,"value":182},{"type":26,"tag":157,"props":5255,"children":5256},{"style":504},[5257],{"type":39,"value":5258},"6\n",{"type":26,"tag":157,"props":5260,"children":5261},{"class":159,"line":577},[5262],{"type":26,"tag":157,"props":5263,"children":5264},{"emptyLinePlaceholder":1419},[5265],{"type":39,"value":1422},{"type":26,"tag":157,"props":5267,"children":5268},{"class":159,"line":589},[5269,5273],{"type":26,"tag":157,"props":5270,"children":5271},{"style":3608},[5272],{"type":39,"value":4933},{"type":26,"tag":157,"props":5274,"children":5275},{"style":164},[5276],{"type":39,"value":3616},{"type":26,"tag":157,"props":5278,"children":5279},{"class":159,"line":605},[5280,5284,5288],{"type":26,"tag":157,"props":5281,"children":5282},{"style":3608},[5283],{"type":39,"value":4987},{"type":26,"tag":157,"props":5285,"children":5286},{"style":164},[5287],{"type":39,"value":182},{"type":26,"tag":157,"props":5289,"children":5290},{"style":1250},[5291],{"type":39,"value":5292},"nextcloud:32.0.0\n",{"type":26,"tag":157,"props":5294,"children":5295},{"class":159,"line":613},[5296,5300,5304],{"type":26,"tag":157,"props":5297,"children":5298},{"style":3608},[5299],{"type":39,"value":5004},{"type":26,"tag":157,"props":5301,"children":5302},{"style":164},[5303],{"type":39,"value":182},{"type":26,"tag":157,"props":5305,"children":5306},{"style":1250},[5307],{"type":39,"value":5013},{"type":26,"tag":157,"props":5309,"children":5310},{"class":159,"line":621},[5311,5316],{"type":26,"tag":157,"props":5312,"children":5313},{"style":3608},[5314],{"type":39,"value":5315},"    depends_on",{"type":26,"tag":157,"props":5317,"children":5318},{"style":164},[5319],{"type":39,"value":3616},{"type":26,"tag":157,"props":5321,"children":5322},{"class":159,"line":629},[5323,5328],{"type":26,"tag":157,"props":5324,"children":5325},{"style":3608},[5326],{"type":39,"value":5327},"      db",{"type":26,"tag":157,"props":5329,"children":5330},{"style":164},[5331],{"type":39,"value":3616},{"type":26,"tag":157,"props":5333,"children":5334},{"class":159,"line":649},[5335,5340,5344],{"type":26,"tag":157,"props":5336,"children":5337},{"style":3608},[5338],{"type":39,"value":5339},"        condition",{"type":26,"tag":157,"props":5341,"children":5342},{"style":164},[5343],{"type":39,"value":182},{"type":26,"tag":157,"props":5345,"children":5346},{"style":1250},[5347],{"type":39,"value":5348},"service_healthy\n",{"type":26,"tag":157,"props":5350,"children":5351},{"class":159,"line":670},[5352,5356],{"type":26,"tag":157,"props":5353,"children":5354},{"style":3608},[5355],{"type":39,"value":5021},{"type":26,"tag":157,"props":5357,"children":5358},{"style":164},[5359],{"type":39,"value":3616},{"type":26,"tag":157,"props":5361,"children":5362},{"class":159,"line":682},[5363,5367],{"type":26,"tag":157,"props":5364,"children":5365},{"style":164},[5366],{"type":39,"value":5033},{"type":26,"tag":157,"props":5368,"children":5369},{"style":1250},[5370],{"type":39,"value":5371},"nextcloud:/var/www/html\n",{"type":26,"tag":157,"props":5373,"children":5374},{"class":159,"line":698},[5375,5379],{"type":26,"tag":157,"props":5376,"children":5377},{"style":3608},[5378],{"type":39,"value":5046},{"type":26,"tag":157,"props":5380,"children":5381},{"style":164},[5382],{"type":39,"value":3616},{"type":26,"tag":157,"props":5384,"children":5385},{"class":159,"line":706},[5386,5390],{"type":26,"tag":157,"props":5387,"children":5388},{"style":164},[5389],{"type":39,"value":5033},{"type":26,"tag":157,"props":5391,"children":5392},{"style":1250},[5393],{"type":39,"value":5394},"MYSQL_PASSWORD=${NEXTCLOUD_MARIADB_PASSWORD:?error}\n",{"type":26,"tag":157,"props":5396,"children":5397},{"class":159,"line":147},[5398,5402],{"type":26,"tag":157,"props":5399,"children":5400},{"style":164},[5401],{"type":39,"value":5033},{"type":26,"tag":157,"props":5403,"children":5404},{"style":1250},[5405],{"type":39,"value":5406},"MYSQL_DATABASE=nextcloud\n",{"type":26,"tag":157,"props":5408,"children":5409},{"class":159,"line":148},[5410,5414],{"type":26,"tag":157,"props":5411,"children":5412},{"style":164},[5413],{"type":39,"value":5033},{"type":26,"tag":157,"props":5415,"children":5416},{"style":1250},[5417],{"type":39,"value":5418},"MYSQL_USER=nextcloud\n",{"type":26,"tag":157,"props":5420,"children":5421},{"class":159,"line":149},[5422,5426],{"type":26,"tag":157,"props":5423,"children":5424},{"style":164},[5425],{"type":39,"value":5033},{"type":26,"tag":157,"props":5427,"children":5428},{"style":1250},[5429],{"type":39,"value":5430},"MYSQL_HOST=db\n",{"type":26,"tag":141,"props":5432,"children":5436},{"className":5433,"code":5434,"language":5435,"meta":7,"style":7},"language-dotenv shiki shiki-themes github-dark github-dark monokai","NEXTCLOUD_MARIADB_ROOT_PASSWORD=\nNEXTCLOUD_MARIADB_PASSWORD=\n","dotenv",[5437],{"type":26,"tag":76,"props":5438,"children":5439},{"__ignoreMap":7},[5440,5454],{"type":26,"tag":157,"props":5441,"children":5442},{"class":159,"line":160},[5443,5449],{"type":26,"tag":157,"props":5444,"children":5446},{"style":5445},"--shiki-default:#FFAB70;--shiki-dark:#FFAB70;--shiki-sepia:#F8F8F2",[5447],{"type":39,"value":5448},"NEXTCLOUD_MARIADB_ROOT_PASSWORD",{"type":26,"tag":157,"props":5450,"children":5451},{"style":3157},[5452],{"type":39,"value":5453},"=\n",{"type":26,"tag":157,"props":5455,"children":5456},{"class":159,"line":170},[5457,5462],{"type":26,"tag":157,"props":5458,"children":5459},{"style":5445},[5460],{"type":39,"value":5461},"NEXTCLOUD_MARIADB_PASSWORD",{"type":26,"tag":157,"props":5463,"children":5464},{"style":3157},[5465],{"type":39,"value":5453},{"type":26,"tag":35,"props":5467,"children":5468},{},[5469,5471],{"type":39,"value":5470},"are stored as ",{"type":26,"tag":47,"props":5472,"children":5474},{"href":5473},"https://docs.gitlab.com/ci/variables/",[5475],{"type":39,"value":5476},"CI/CD Variables",{"type":26,"tag":3507,"props":5478,"children":5479},{},[],{"type":26,"tag":35,"props":5481,"children":5482},{},[5483],{"type":39,"value":5484},"To deploy the stack, we have a pipeline:",{"type":26,"tag":141,"props":5486,"children":5488},{"className":3595,"code":5487,"filename":3597,"language":3598,"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",[5489],{"type":26,"tag":76,"props":5490,"children":5491},{"__ignoreMap":7},[5492,5503,5515,5522,5533,5548,5564,5576,5593,5604,5616,5627],{"type":26,"tag":157,"props":5493,"children":5494},{"class":159,"line":160},[5495,5499],{"type":26,"tag":157,"props":5496,"children":5497},{"style":3608},[5498],{"type":39,"value":3611},{"type":26,"tag":157,"props":5500,"children":5501},{"style":164},[5502],{"type":39,"value":3616},{"type":26,"tag":157,"props":5504,"children":5505},{"class":159,"line":170},[5506,5510],{"type":26,"tag":157,"props":5507,"children":5508},{"style":164},[5509],{"type":39,"value":3624},{"type":26,"tag":157,"props":5511,"children":5512},{"style":1250},[5513],{"type":39,"value":5514},"deploy\n",{"type":26,"tag":157,"props":5516,"children":5517},{"class":159,"line":196},[5518],{"type":26,"tag":157,"props":5519,"children":5520},{"emptyLinePlaceholder":1419},[5521],{"type":39,"value":1422},{"type":26,"tag":157,"props":5523,"children":5524},{"class":159,"line":218},[5525,5529],{"type":26,"tag":157,"props":5526,"children":5527},{"style":3608},[5528],{"type":39,"value":3644},{"type":26,"tag":157,"props":5530,"children":5531},{"style":164},[5532],{"type":39,"value":3616},{"type":26,"tag":157,"props":5534,"children":5535},{"class":159,"line":240},[5536,5540,5544],{"type":26,"tag":157,"props":5537,"children":5538},{"style":3608},[5539],{"type":39,"value":3673},{"type":26,"tag":157,"props":5541,"children":5542},{"style":164},[5543],{"type":39,"value":182},{"type":26,"tag":157,"props":5545,"children":5546},{"style":1250},[5547],{"type":39,"value":5514},{"type":26,"tag":157,"props":5549,"children":5550},{"class":159,"line":254},[5551,5555,5559],{"type":26,"tag":157,"props":5552,"children":5553},{"style":3608},[5554],{"type":39,"value":3656},{"type":26,"tag":157,"props":5556,"children":5557},{"style":164},[5558],{"type":39,"value":182},{"type":26,"tag":157,"props":5560,"children":5561},{"style":1250},[5562],{"type":39,"value":5563},"docker:28\n",{"type":26,"tag":157,"props":5565,"children":5566},{"class":159,"line":276},[5567,5572],{"type":26,"tag":157,"props":5568,"children":5569},{"style":3608},[5570],{"type":39,"value":5571},"  variables",{"type":26,"tag":157,"props":5573,"children":5574},{"style":164},[5575],{"type":39,"value":3616},{"type":26,"tag":157,"props":5577,"children":5578},{"class":159,"line":298},[5579,5584,5588],{"type":26,"tag":157,"props":5580,"children":5581},{"style":3608},[5582],{"type":39,"value":5583},"    DOCKER_HOST",{"type":26,"tag":157,"props":5585,"children":5586},{"style":164},[5587],{"type":39,"value":182},{"type":26,"tag":157,"props":5589,"children":5590},{"style":1250},[5591],{"type":39,"value":5592},"ssh://[username@]\u003CIP or host>[:port]\n",{"type":26,"tag":157,"props":5594,"children":5595},{"class":159,"line":320},[5596,5600],{"type":26,"tag":157,"props":5597,"children":5598},{"style":3608},[5599],{"type":39,"value":3689},{"type":26,"tag":157,"props":5601,"children":5602},{"style":164},[5603],{"type":39,"value":3616},{"type":26,"tag":157,"props":5605,"children":5606},{"class":159,"line":342},[5607,5611],{"type":26,"tag":157,"props":5608,"children":5609},{"style":164},[5610],{"type":39,"value":3701},{"type":26,"tag":157,"props":5612,"children":5613},{"style":1250},[5614],{"type":39,"value":5615},"for file in $(find . -type f -name docker-compose.yml); do docker compose -f $file up --remove-orphans --wait; done\n",{"type":26,"tag":157,"props":5617,"children":5618},{"class":159,"line":363},[5619,5623],{"type":26,"tag":157,"props":5620,"children":5621},{"style":3608},[5622],{"type":39,"value":3731},{"type":26,"tag":157,"props":5624,"children":5625},{"style":164},[5626],{"type":39,"value":3616},{"type":26,"tag":157,"props":5628,"children":5629},{"class":159,"line":384},[5630,5634,5638,5642],{"type":26,"tag":157,"props":5631,"children":5632},{"style":164},[5633],{"type":39,"value":3701},{"type":26,"tag":157,"props":5635,"children":5636},{"style":3608},[5637],{"type":39,"value":3964},{"type":26,"tag":157,"props":5639,"children":5640},{"style":164},[5641],{"type":39,"value":182},{"type":26,"tag":157,"props":5643,"children":5644},{"style":1250},[5645],{"type":39,"value":5646},"$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH\n",{"type":26,"tag":35,"props":5648,"children":5649},{},[5650,5652,5658],{"type":39,"value":5651},"The pipeline runs with every commit on the default branch, iterates through all ",{"type":26,"tag":76,"props":5653,"children":5655},{"className":5654},[],[5656],{"type":39,"value":5657},"docker-compose.yml",{"type":39,"value":5659}," files, and deploys them.",{"type":26,"tag":110,"props":5661,"children":5663},{"id":5662},"keep-your-deployments-up-to-date-with-renovate-bot",[5664],{"type":39,"value":5665},"Keep your deployments up-to-date with Renovate Bot",{"type":26,"tag":35,"props":5667,"children":5668},{},[5669],{"type":39,"value":5670},"Here is where Renovate kicks in.",{"type":26,"tag":141,"props":5672,"children":5675},{"className":143,"code":5673,"filename":5674,"language":151,"meta":7,"style":7},"{\n  \"$schema\": \"https://docs.renovatebot.com/renovate-schema.json\",\n  \"extends\": [\n    \"config:best-practices\"\n  ]\n}\n","renovate.json",[5676],{"type":26,"tag":76,"props":5677,"children":5678},{"__ignoreMap":7},[5679,5686,5707,5719,5727,5734],{"type":26,"tag":157,"props":5680,"children":5681},{"class":159,"line":160},[5682],{"type":26,"tag":157,"props":5683,"children":5684},{"style":164},[5685],{"type":39,"value":167},{"type":26,"tag":157,"props":5687,"children":5688},{"class":159,"line":170},[5689,5694,5698,5703],{"type":26,"tag":157,"props":5690,"children":5691},{"style":174},[5692],{"type":39,"value":5693},"  \"$schema\"",{"type":26,"tag":157,"props":5695,"children":5696},{"style":164},[5697],{"type":39,"value":182},{"type":26,"tag":157,"props":5699,"children":5700},{"style":185},[5701],{"type":39,"value":5702},"\"https://docs.renovatebot.com/renovate-schema.json\"",{"type":26,"tag":157,"props":5704,"children":5705},{"style":164},[5706],{"type":39,"value":193},{"type":26,"tag":157,"props":5708,"children":5709},{"class":159,"line":196},[5710,5715],{"type":26,"tag":157,"props":5711,"children":5712},{"style":174},[5713],{"type":39,"value":5714},"  \"extends\"",{"type":26,"tag":157,"props":5716,"children":5717},{"style":164},[5718],{"type":39,"value":422},{"type":26,"tag":157,"props":5720,"children":5721},{"class":159,"line":218},[5722],{"type":26,"tag":157,"props":5723,"children":5724},{"style":185},[5725],{"type":39,"value":5726},"    \"config:best-practices\"\n",{"type":26,"tag":157,"props":5728,"children":5729},{"class":159,"line":240},[5730],{"type":26,"tag":157,"props":5731,"children":5732},{"style":164},[5733],{"type":39,"value":4408},{"type":26,"tag":157,"props":5735,"children":5736},{"class":159,"line":254},[5737],{"type":26,"tag":157,"props":5738,"children":5739},{"style":164},[5740],{"type":39,"value":1225},{"type":26,"tag":35,"props":5742,"children":5743},{},[5744],{"type":39,"value":5745},"Renovate will create Merge Requests for every update. Nice!",{"type":26,"tag":110,"props":5747,"children":5749},{"id":5748},"automated-security-updates-and-opt-in-for-minormajor-version-updates",[5750],{"type":39,"value":5751},"Automated security updates and opt-in for minor/major version updates",{"type":26,"tag":35,"props":5753,"children":5754},{},[5755],{"type":39,"value":5756},"The current configuration creates Merge Requests for every update, but we want security updates to happen without user interaction.",{"type":26,"tag":35,"props":5758,"children":5759},{},[5760,5762],{"type":39,"value":5761},"You need to understand how Docker images are versioned / tagged. It depends on the image, but let's take a look on the official ",{"type":26,"tag":47,"props":5763,"children":5765},{"href":5764},"https://hub.docker.com/_/mariadb",[5766],{"type":39,"value":5767},"MariaDB",{"type":26,"tag":35,"props":5769,"children":5770},{},[5771,5773,5779],{"type":39,"value":5772},"There are ",{"type":26,"tag":76,"props":5774,"children":5776},{"className":5775},[],[5777],{"type":39,"value":5778},"11.8.3-noble, 11.8-noble, 11-noble, lts-noble, 11.8.3, 11.8, 11, lts",{"type":39,"value":5780},", all of which refer to the same image.",{"type":26,"tag":35,"props":5782,"children":5783},{},[5784,5790,5792,5798,5800,5806,5807,5813],{"type":26,"tag":76,"props":5785,"children":5787},{"className":5786},[],[5788],{"type":39,"value":5789},"11.8.3-noble",{"type":39,"value":5791}," means that we get MariaDB in version ",{"type":26,"tag":76,"props":5793,"children":5795},{"className":5794},[],[5796],{"type":39,"value":5797},"11.8.3",{"type":39,"value":5799}," based on Ubuntu Noble.\n",{"type":26,"tag":76,"props":5801,"children":5803},{"className":5802},[],[5804],{"type":39,"value":5805},"11.8-noble",{"type":39,"value":5791},{"type":26,"tag":76,"props":5808,"children":5810},{"className":5809},[],[5811],{"type":39,"value":5812},"11.8.\u003Clatest_path>",{"type":39,"value":5814}," based on Ubuntu Noble.",{"type":26,"tag":35,"props":5816,"children":5817},{},[5818,5820,5826,5828,5833,5835,5840],{"type":39,"value":5819},"When a neu version of MariaDB is released, e.g ",{"type":26,"tag":76,"props":5821,"children":5823},{"className":5822},[],[5824],{"type":39,"value":5825},"11.8.4-noble",{"type":39,"value":5827},", a new ",{"type":26,"tag":76,"props":5829,"children":5831},{"className":5830},[],[5832],{"type":39,"value":5825},{"type":39,"value":5834}," tag will be pushed, but the ",{"type":26,"tag":76,"props":5836,"children":5838},{"className":5837},[],[5839],{"type":39,"value":5805},{"type":39,"value":5841}," will be updated.",{"type":26,"tag":35,"props":5843,"children":5844},{},[5845,5847,5852],{"type":39,"value":5846},"This same is true for the Ubuntu update. The ",{"type":26,"tag":76,"props":5848,"children":5850},{"className":5849},[],[5851],{"type":39,"value":5789},{"type":39,"value":5853}," tag can be updated, if the image is rebuild with the latest Ubuntu image.",{"type":26,"tag":35,"props":5855,"children":5856},{},[5857,5859,5865,5867,5873],{"type":39,"value":5858},"Running ",{"type":26,"tag":76,"props":5860,"children":5862},{"className":5861},[],[5863],{"type":39,"value":5864},"docker compose up",{"type":39,"value":5866}," on ",{"type":26,"tag":76,"props":5868,"children":5870},{"className":5869},[],[5871],{"type":39,"value":5872},"mariadb:11.8-noble",{"type":39,"value":5874}," will do nothing, because Docker is not aware of that change.",{"type":26,"tag":35,"props":5876,"children":5877},{},[5878,5880,5886],{"type":39,"value":5879},"In the example above we reference ",{"type":26,"tag":76,"props":5881,"children":5883},{"className":5882},[],[5884],{"type":39,"value":5885},"mariadb:11.8",{"type":39,"value":5887},", because we want to use the latest patch version based on the most current OS.",{"type":26,"tag":3507,"props":5889,"children":5890},{},[],{"type":26,"tag":35,"props":5892,"children":5893},{},[5894],{"type":39,"value":5895},"How to tell Docker that there is a new version?",{"type":26,"tag":35,"props":5897,"children":5898},{},[5899,5901,5907],{"type":39,"value":5900},"The main idea is to attach a ",{"type":26,"tag":47,"props":5902,"children":5904},{"href":5903},"https://docs.docker.com/dhi/core-concepts/digests/",[5905],{"type":39,"value":5906},"digest",{"type":39,"value":5908}," to the Docker image.",{"type":26,"tag":35,"props":5910,"children":5911},{},[5912,5914,5919,5921],{"type":39,"value":5913},"When running Renovate for the first time, it will find the reference to ",{"type":26,"tag":76,"props":5915,"children":5917},{"className":5916},[],[5918],{"type":39,"value":5885},{"type":39,"value":5920}," and create a merge request to pin the Digest to something like ",{"type":26,"tag":76,"props":5922,"children":5924},{"className":5923},[],[5925],{"type":39,"value":5926},"mariadb:11.8@sha256:ae6119716edac6998ae85508431b3d2e666530ddf4e94c61a10710caec9b0f71",{"type":26,"tag":35,"props":5928,"children":5929},{},[5930],{"type":39,"value":5931},"Renovate will also monitor the upstream changes, so that every time the image get updated, the digest will change and Renovate will create a merge request.",{"type":26,"tag":35,"props":5933,"children":5934},{},[5935],{"type":39,"value":5936},"To merge these updates automatically, we need to do some adjustments.",{"type":26,"tag":141,"props":5938,"children":5941},{"className":143,"code":5939,"filename":5674,"highlights":5940,"language":151,"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",[240,254,276,298],[5942],{"type":26,"tag":76,"props":5943,"children":5944},{"__ignoreMap":7},[5945,5952,5971,5982,5994,6003,6011,6033,6050],{"type":26,"tag":157,"props":5946,"children":5947},{"class":159,"line":160},[5948],{"type":26,"tag":157,"props":5949,"children":5950},{"style":164},[5951],{"type":39,"value":167},{"type":26,"tag":157,"props":5953,"children":5954},{"class":159,"line":170},[5955,5959,5963,5967],{"type":26,"tag":157,"props":5956,"children":5957},{"style":174},[5958],{"type":39,"value":5693},{"type":26,"tag":157,"props":5960,"children":5961},{"style":164},[5962],{"type":39,"value":182},{"type":26,"tag":157,"props":5964,"children":5965},{"style":185},[5966],{"type":39,"value":5702},{"type":26,"tag":157,"props":5968,"children":5969},{"style":164},[5970],{"type":39,"value":193},{"type":26,"tag":157,"props":5972,"children":5973},{"class":159,"line":196},[5974,5978],{"type":26,"tag":157,"props":5975,"children":5976},{"style":174},[5977],{"type":39,"value":5714},{"type":26,"tag":157,"props":5979,"children":5980},{"style":164},[5981],{"type":39,"value":422},{"type":26,"tag":157,"props":5983,"children":5984},{"class":159,"line":218},[5985,5990],{"type":26,"tag":157,"props":5986,"children":5987},{"style":185},[5988],{"type":39,"value":5989},"    \"config:best-practices\"",{"type":26,"tag":157,"props":5991,"children":5992},{"style":164},[5993],{"type":39,"value":193},{"type":26,"tag":157,"props":5995,"children":5997},{"class":5996,"line":240},[159,715],[5998],{"type":26,"tag":157,"props":5999,"children":6000},{"style":185},[6001],{"type":39,"value":6002},"    \"default:automergeDigest\"\n",{"type":26,"tag":157,"props":6004,"children":6006},{"class":6005,"line":254},[159,715],[6007],{"type":26,"tag":157,"props":6008,"children":6009},{"style":164},[6010],{"type":39,"value":776},{"type":26,"tag":157,"props":6012,"children":6014},{"class":6013,"line":276},[159,715],[6015,6020,6024,6029],{"type":26,"tag":157,"props":6016,"children":6017},{"style":174},[6018],{"type":39,"value":6019},"  \"automergeType\"",{"type":26,"tag":157,"props":6021,"children":6022},{"style":164},[6023],{"type":39,"value":182},{"type":26,"tag":157,"props":6025,"children":6026},{"style":185},[6027],{"type":39,"value":6028},"\"branch\"",{"type":26,"tag":157,"props":6030,"children":6031},{"style":164},[6032],{"type":39,"value":193},{"type":26,"tag":157,"props":6034,"children":6036},{"class":6035,"line":298},[159,715],[6037,6042,6046],{"type":26,"tag":157,"props":6038,"children":6039},{"style":174},[6040],{"type":39,"value":6041},"  \"ignoreTests\"",{"type":26,"tag":157,"props":6043,"children":6044},{"style":164},[6045],{"type":39,"value":182},{"type":26,"tag":157,"props":6047,"children":6048},{"style":504},[6049],{"type":39,"value":507},{"type":26,"tag":157,"props":6051,"children":6052},{"class":159,"line":320},[6053],{"type":26,"tag":157,"props":6054,"children":6055},{"style":164},[6056],{"type":39,"value":1225},{"type":26,"tag":35,"props":6058,"children":6059},{},[6060,6062,6068,6069],{"type":39,"value":6061},"This instructs Renovate to auto-merge the Digest updates without creating a merge request prior. This reduces noise since there is no merge request notification.\nYou can read more about ",{"type":26,"tag":47,"props":6063,"children":6065},{"href":6064},"https://docs.renovatebot.com/key-concepts/automerge/#branch-vs-pr-automerging",[6066],{"type":39,"value":6067},"automergeType",{"type":39,"value":4674},{"type":26,"tag":47,"props":6070,"children":6072},{"href":6071},"https://docs.renovatebot.com/key-concepts/automerge/#absence-of-tests",[6073],{"type":39,"value":6074},"ignoreTests",{"type":26,"tag":4462,"props":6076,"children":6077},{},[6078],{"type":39,"value":4466},{"title":7,"searchDepth":170,"depth":170,"links":6080},[6081,6082,6083,6084,6085],{"id":4706,"depth":170,"text":4709},{"id":4743,"depth":170,"text":4746},{"id":4784,"depth":170,"text":4787},{"id":5662,"depth":170,"text":5665},{"id":5748,"depth":170,"text":5751},{"_path":4497,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":4498,"description":4499,"author":10,"image":11,"releaseDate":4500,"blogCategories":6087,"articleTags":6088,"tags":6089,"body":6090,"_type":4479,"_id":4504,"_source":4481,"_file":4505,"_stem":4506,"_extension":4484},[14,15],[15],[21],{"type":23,"children":6091,"toc":7229},[6092,6103,6108,6233,6238,6311,6317,6343,6348,6372,6385,6403,6409,6426,6527,6532,6537,6562,6608,6611,6616,6957,6962,6998,7004,7012,7063,7066,7073,7101,7107,7112,7118,7123,7135,7143,7149,7161,7225],{"type":26,"tag":35,"props":6093,"children":6094},{},[6095,6101],{"type":26,"tag":47,"props":6096,"children":6098},{"href":6097},"https://doc.traefik.io/traefik/",[6099],{"type":39,"value":6100},"Traefik",{"type":39,"value":6102}," is a reverse proxy with excellent docker integration. It uses labeln attached to containers to route traffic to them.",{"type":26,"tag":35,"props":6104,"children":6105},{},[6106],{"type":39,"value":6107},"A common label set looks similar to this:",{"type":26,"tag":141,"props":6109,"children":6113},{"code":6110,"filename":6111,"highlights":6112,"language":3598,"meta":7,"className":3595,"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",[240,254,276,298,320],[6114],{"type":26,"tag":76,"props":6115,"children":6116},{"__ignoreMap":7},[6117,6128,6140,6156,6168,6181,6194,6207,6220],{"type":26,"tag":157,"props":6118,"children":6119},{"class":159,"line":160},[6120,6124],{"type":26,"tag":157,"props":6121,"children":6122},{"style":3608},[6123],{"type":39,"value":4964},{"type":26,"tag":157,"props":6125,"children":6126},{"style":164},[6127],{"type":39,"value":3616},{"type":26,"tag":157,"props":6129,"children":6130},{"class":159,"line":170},[6131,6136],{"type":26,"tag":157,"props":6132,"children":6133},{"style":3608},[6134],{"type":39,"value":6135},"  whoami",{"type":26,"tag":157,"props":6137,"children":6138},{"style":164},[6139],{"type":39,"value":3616},{"type":26,"tag":157,"props":6141,"children":6142},{"class":159,"line":196},[6143,6147,6151],{"type":26,"tag":157,"props":6144,"children":6145},{"style":3608},[6146],{"type":39,"value":4987},{"type":26,"tag":157,"props":6148,"children":6149},{"style":164},[6150],{"type":39,"value":182},{"type":26,"tag":157,"props":6152,"children":6153},{"style":1250},[6154],{"type":39,"value":6155},"traefik/whoami\n",{"type":26,"tag":157,"props":6157,"children":6158},{"class":159,"line":218},[6159,6164],{"type":26,"tag":157,"props":6160,"children":6161},{"style":3608},[6162],{"type":39,"value":6163},"    labels",{"type":26,"tag":157,"props":6165,"children":6166},{"style":164},[6167],{"type":39,"value":3616},{"type":26,"tag":157,"props":6169,"children":6171},{"class":6170,"line":240},[159,715],[6172,6176],{"type":26,"tag":157,"props":6173,"children":6174},{"style":164},[6175],{"type":39,"value":5033},{"type":26,"tag":157,"props":6177,"children":6178},{"style":1250},[6179],{"type":39,"value":6180},"\"traefik.enable=true\"\n",{"type":26,"tag":157,"props":6182,"children":6184},{"class":6183,"line":254},[159,715],[6185,6189],{"type":26,"tag":157,"props":6186,"children":6187},{"style":164},[6188],{"type":39,"value":5033},{"type":26,"tag":157,"props":6190,"children":6191},{"style":1250},[6192],{"type":39,"value":6193},"\"traefik.http.routers.whoami.rule=Host(`whoami.example.com`)\"\n",{"type":26,"tag":157,"props":6195,"children":6197},{"class":6196,"line":276},[159,715],[6198,6202],{"type":26,"tag":157,"props":6199,"children":6200},{"style":164},[6201],{"type":39,"value":5033},{"type":26,"tag":157,"props":6203,"children":6204},{"style":1250},[6205],{"type":39,"value":6206},"\"traefik.http.routers.whoami.entrypoints=websecure\"\n",{"type":26,"tag":157,"props":6208,"children":6210},{"class":6209,"line":298},[159,715],[6211,6215],{"type":26,"tag":157,"props":6212,"children":6213},{"style":164},[6214],{"type":39,"value":5033},{"type":26,"tag":157,"props":6216,"children":6217},{"style":1250},[6218],{"type":39,"value":6219},"\"traefik.http.routers.whoami.tls=true\"\n",{"type":26,"tag":157,"props":6221,"children":6223},{"class":6222,"line":320},[159,715],[6224,6228],{"type":26,"tag":157,"props":6225,"children":6226},{"style":164},[6227],{"type":39,"value":5033},{"type":26,"tag":157,"props":6229,"children":6230},{"style":1250},[6231],{"type":39,"value":6232},"\"traefik.http.routers.whoami.tls.certresolver=letsencrypt\"\n",{"type":26,"tag":35,"props":6234,"children":6235},{},[6236],{"type":39,"value":6237},"In this example:",{"type":26,"tag":4639,"props":6239,"children":6240},{},[6241,6252,6268,6273,6285,6290],{"type":26,"tag":70,"props":6242,"children":6243},{},[6244,6250],{"type":26,"tag":76,"props":6245,"children":6247},{"className":6246},[],[6248],{"type":39,"value":6249},"whoami",{"type":39,"value":6251}," the name of the \"main\" service (2)",{"type":26,"tag":70,"props":6253,"children":6254},{},[6255,6260,6262],{"type":26,"tag":76,"props":6256,"children":6258},{"className":6257},[],[6259],{"type":39,"value":6249},{"type":39,"value":6261}," the also the default ",{"type":26,"tag":47,"props":6263,"children":6265},{"href":6264},"https://docs.docker.com/compose/how-tos/project-name/",[6266],{"type":39,"value":6267},"compose project name",{"type":26,"tag":70,"props":6269,"children":6270},{},[6271],{"type":39,"value":6272},"Traefik is activated (5)",{"type":26,"tag":70,"props":6274,"children":6275},{},[6276,6278,6283],{"type":39,"value":6277},"It is exposed under ",{"type":26,"tag":76,"props":6279,"children":6281},{"className":6280},[],[6282],{"type":39,"value":6249},{"type":39,"value":6284}," subdomain (6)",{"type":26,"tag":70,"props":6286,"children":6287},{},[6288],{"type":39,"value":6289},"It is served over https (7)",{"type":26,"tag":70,"props":6291,"children":6292},{},[6293,6295,6301,6303,6309],{"type":39,"value":6294},"A preconfigured certresolver named ",{"type":26,"tag":76,"props":6296,"children":6298},{"className":6297},[],[6299],{"type":39,"value":6300},"letsencrypt",{"type":39,"value":6302}," is used for ",{"type":26,"tag":76,"props":6304,"children":6306},{"className":6305},[],[6307],{"type":39,"value":6308},"tls",{"type":39,"value":6310}," (8-9)",{"type":26,"tag":110,"props":6312,"children":6314},{"id":6313},"the-problem",[6315],{"type":39,"value":6316},"The problem",{"type":26,"tag":35,"props":6318,"children":6319},{},[6320,6322,6328,6330,6335,6337,6342],{"type":39,"value":6321},"In my ",{"type":26,"tag":47,"props":6323,"children":6325},{"href":6324},"/blog/gitops-docker-renovate",[6326],{"type":39,"value":6327},"other post about gitops with docker",{"type":39,"value":6329}," I introduced a concept of using ",{"type":26,"tag":76,"props":6331,"children":6333},{"className":6332},[],[6334],{"type":39,"value":1456},{"type":39,"value":6336},"\nas the sources of truth for docker deployments using ",{"type":26,"tag":47,"props":6338,"children":6339},{"href":4677},[6340],{"type":39,"value":6341},"docker compose",{"type":39,"value":54},{"type":26,"tag":35,"props":6344,"children":6345},{},[6346],{"type":39,"value":6347},"Now there are some requirements to this approach:",{"type":26,"tag":4639,"props":6349,"children":6350},{},[6351,6362],{"type":26,"tag":70,"props":6352,"children":6353},{},[6354,6356],{"type":39,"value":6355},"every stack is exposer under ",{"type":26,"tag":76,"props":6357,"children":6359},{"className":6358},[],[6360],{"type":39,"value":6361},"\u003Cstack_name>.\u003Cyour_domain>",{"type":26,"tag":70,"props":6363,"children":6364},{},[6365,6367],{"type":39,"value":6366},"every stack is protected with ",{"type":26,"tag":76,"props":6368,"children":6370},{"className":6369},[],[6371],{"type":39,"value":6308},{"type":26,"tag":35,"props":6373,"children":6374},{},[6375,6377,6383],{"type":39,"value":6376},"We could of course edit every ",{"type":26,"tag":76,"props":6378,"children":6380},{"className":6379},[],[6381],{"type":39,"value":6382},"docker-compose.yaml",{"type":39,"value":6384}," file and add the required labels, but it quickly becomes obvious,\nthat all the labels are the same!",{"type":26,"tag":66,"props":6386,"children":6387},{},[6388,6393,6398],{"type":26,"tag":70,"props":6389,"children":6390},{},[6391],{"type":39,"value":6392},"Enable Traefik",{"type":26,"tag":70,"props":6394,"children":6395},{},[6396],{"type":39,"value":6397},"Assign a subdomain",{"type":26,"tag":70,"props":6399,"children":6400},{},[6401],{"type":39,"value":6402},"Enable HTTPS",{"type":26,"tag":110,"props":6404,"children":6406},{"id":6405},"the-solution",[6407],{"type":39,"value":6408},"The solution",{"type":26,"tag":35,"props":6410,"children":6411},{},[6412,6414,6424],{"type":39,"value":6413},"By using ",{"type":26,"tag":47,"props":6415,"children":6417},{"href":6416},"https://docs.docker.com/compose/how-tos/environment-variables/envvars/#compose_project_name",[6418],{"type":26,"tag":76,"props":6419,"children":6421},{"className":6420},[],[6422],{"type":39,"value":6423},"$COMPOSE_PROJECT_NAME",{"type":39,"value":6425},"\nvariable we can create a more generic template.\nThis ensures that the Traefik rules are consistent.",{"type":26,"tag":141,"props":6427,"children":6430},{"code":6428,"filename":6429,"language":3598,"meta":7,"className":3595,"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",[6431],{"type":26,"tag":76,"props":6432,"children":6433},{"__ignoreMap":7},[6434,6445,6457,6468,6479,6491,6503,6515],{"type":26,"tag":157,"props":6435,"children":6436},{"class":159,"line":160},[6437,6441],{"type":26,"tag":157,"props":6438,"children":6439},{"style":3608},[6440],{"type":39,"value":4964},{"type":26,"tag":157,"props":6442,"children":6443},{"style":164},[6444],{"type":39,"value":3616},{"type":26,"tag":157,"props":6446,"children":6447},{"class":159,"line":170},[6448,6453],{"type":26,"tag":157,"props":6449,"children":6450},{"style":3608},[6451],{"type":39,"value":6452},"  \u003Cmain_service>",{"type":26,"tag":157,"props":6454,"children":6455},{"style":164},[6456],{"type":39,"value":3616},{"type":26,"tag":157,"props":6458,"children":6459},{"class":159,"line":196},[6460,6464],{"type":26,"tag":157,"props":6461,"children":6462},{"style":3608},[6463],{"type":39,"value":6163},{"type":26,"tag":157,"props":6465,"children":6466},{"style":164},[6467],{"type":39,"value":3616},{"type":26,"tag":157,"props":6469,"children":6470},{"class":159,"line":218},[6471,6475],{"type":26,"tag":157,"props":6472,"children":6473},{"style":164},[6474],{"type":39,"value":5033},{"type":26,"tag":157,"props":6476,"children":6477},{"style":1250},[6478],{"type":39,"value":6180},{"type":26,"tag":157,"props":6480,"children":6481},{"class":159,"line":240},[6482,6486],{"type":26,"tag":157,"props":6483,"children":6484},{"style":164},[6485],{"type":39,"value":5033},{"type":26,"tag":157,"props":6487,"children":6488},{"style":1250},[6489],{"type":39,"value":6490},"\"traefik.http.routers.$COMPOSE_PROJECT_NAME.rule=Host(`\u003Cstack_name>.example.com`)\"\n",{"type":26,"tag":157,"props":6492,"children":6493},{"class":159,"line":254},[6494,6498],{"type":26,"tag":157,"props":6495,"children":6496},{"style":164},[6497],{"type":39,"value":5033},{"type":26,"tag":157,"props":6499,"children":6500},{"style":1250},[6501],{"type":39,"value":6502},"\"traefik.http.routers.$COMPOSE_PROJECT_NAME.entrypoints=websecure\"\n",{"type":26,"tag":157,"props":6504,"children":6505},{"class":159,"line":276},[6506,6510],{"type":26,"tag":157,"props":6507,"children":6508},{"style":164},[6509],{"type":39,"value":5033},{"type":26,"tag":157,"props":6511,"children":6512},{"style":1250},[6513],{"type":39,"value":6514},"\"traefik.http.routers.$COMPOSE_PROJECT_NAME.tls=true\"\n",{"type":26,"tag":157,"props":6516,"children":6517},{"class":159,"line":298},[6518,6522],{"type":26,"tag":157,"props":6519,"children":6520},{"style":164},[6521],{"type":39,"value":5033},{"type":26,"tag":157,"props":6523,"children":6524},{"style":1250},[6525],{"type":39,"value":6526},"\"traefik.http.routers.$COMPOSE_PROJECT_NAME.tls.certresolver=letsencrypt\"\n",{"type":26,"tag":35,"props":6528,"children":6529},{},[6530],{"type":39,"value":6531},"The good news is that Traefik lets us configure some defaults that will cover the above boilerplate!",{"type":26,"tag":35,"props":6533,"children":6534},{},[6535],{"type":39,"value":6536},"Let's us define two simple conventions:",{"type":26,"tag":66,"props":6538,"children":6539},{},[6540,6551],{"type":26,"tag":70,"props":6541,"children":6542},{},[6543,6549],{"type":26,"tag":76,"props":6544,"children":6546},{"className":6545},[],[6547],{"type":39,"value":6548},"app",{"type":39,"value":6550}," is the main container, where Traefik will route the traffic",{"type":26,"tag":70,"props":6552,"children":6553},{},[6554,6560],{"type":26,"tag":76,"props":6555,"children":6557},{"className":6556},[],[6558],{"type":39,"value":6559},"\u003Cstack_name>",{"type":39,"value":6561}," (the compose project name) is the subdomain",{"type":26,"tag":141,"props":6563,"children":6566},{"code":6564,"filename":6111,"language":3598,"meta":6565,"className":3595,"style":7},"services:\n  app:\n    image: traefik/whoami\n","(1)",[6567],{"type":26,"tag":76,"props":6568,"children":6569},{"__ignoreMap":7},[6570,6581,6593],{"type":26,"tag":157,"props":6571,"children":6572},{"class":159,"line":160},[6573,6577],{"type":26,"tag":157,"props":6574,"children":6575},{"style":3608},[6576],{"type":39,"value":4964},{"type":26,"tag":157,"props":6578,"children":6579},{"style":164},[6580],{"type":39,"value":3616},{"type":26,"tag":157,"props":6582,"children":6583},{"class":159,"line":170},[6584,6589],{"type":26,"tag":157,"props":6585,"children":6586},{"style":3608},[6587],{"type":39,"value":6588},"  app",{"type":26,"tag":157,"props":6590,"children":6591},{"style":164},[6592],{"type":39,"value":3616},{"type":26,"tag":157,"props":6594,"children":6595},{"class":159,"line":196},[6596,6600,6604],{"type":26,"tag":157,"props":6597,"children":6598},{"style":3608},[6599],{"type":39,"value":4987},{"type":26,"tag":157,"props":6601,"children":6602},{"style":164},[6603],{"type":39,"value":182},{"type":26,"tag":157,"props":6605,"children":6606},{"style":1250},[6607],{"type":39,"value":6155},{"type":26,"tag":3507,"props":6609,"children":6610},{},[],{"type":26,"tag":35,"props":6612,"children":6613},{},[6614],{"type":39,"value":6615},"Now let's configure traefik to do \"the magic\"",{"type":26,"tag":141,"props":6617,"children":6621},{"code":6618,"filename":6619,"language":3598,"meta":6620,"className":3595,"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","traefik/docker-compose.yaml","(2)",[6622],{"type":26,"tag":76,"props":6623,"children":6624},{"__ignoreMap":7},[6625,6636,6648,6656,6667,6679,6696,6712,6728,6745,6756,6768,6780,6792,6804,6811,6823,6835,6843,6855,6867,6879,6886,6898,6910,6922,6933,6945],{"type":26,"tag":157,"props":6626,"children":6627},{"class":159,"line":160},[6628,6632],{"type":26,"tag":157,"props":6629,"children":6630},{"style":3608},[6631],{"type":39,"value":4921},{"type":26,"tag":157,"props":6633,"children":6634},{"style":164},[6635],{"type":39,"value":3616},{"type":26,"tag":157,"props":6637,"children":6638},{"class":159,"line":170},[6639,6644],{"type":26,"tag":157,"props":6640,"children":6641},{"style":3608},[6642],{"type":39,"value":6643},"  letsencrypt",{"type":26,"tag":157,"props":6645,"children":6646},{"style":164},[6647],{"type":39,"value":3616},{"type":26,"tag":157,"props":6649,"children":6650},{"class":159,"line":196},[6651],{"type":26,"tag":157,"props":6652,"children":6653},{"style":164},[6654],{"type":39,"value":6655},"    \n",{"type":26,"tag":157,"props":6657,"children":6658},{"class":159,"line":218},[6659,6663],{"type":26,"tag":157,"props":6660,"children":6661},{"style":3608},[6662],{"type":39,"value":4964},{"type":26,"tag":157,"props":6664,"children":6665},{"style":164},[6666],{"type":39,"value":3616},{"type":26,"tag":157,"props":6668,"children":6669},{"class":159,"line":240},[6670,6675],{"type":26,"tag":157,"props":6671,"children":6672},{"style":3608},[6673],{"type":39,"value":6674},"  traefik",{"type":26,"tag":157,"props":6676,"children":6677},{"style":164},[6678],{"type":39,"value":3616},{"type":26,"tag":157,"props":6680,"children":6681},{"class":159,"line":254},[6682,6687,6691],{"type":26,"tag":157,"props":6683,"children":6684},{"style":3608},[6685],{"type":39,"value":6686},"    container_name",{"type":26,"tag":157,"props":6688,"children":6689},{"style":164},[6690],{"type":39,"value":182},{"type":26,"tag":157,"props":6692,"children":6693},{"style":1250},[6694],{"type":39,"value":6695},"traefik\n",{"type":26,"tag":157,"props":6697,"children":6698},{"class":159,"line":276},[6699,6703,6707],{"type":26,"tag":157,"props":6700,"children":6701},{"style":3608},[6702],{"type":39,"value":5004},{"type":26,"tag":157,"props":6704,"children":6705},{"style":164},[6706],{"type":39,"value":182},{"type":26,"tag":157,"props":6708,"children":6709},{"style":1250},[6710],{"type":39,"value":6711},"always\n",{"type":26,"tag":157,"props":6713,"children":6714},{"class":159,"line":298},[6715,6719,6723],{"type":26,"tag":157,"props":6716,"children":6717},{"style":3608},[6718],{"type":39,"value":4987},{"type":26,"tag":157,"props":6720,"children":6721},{"style":164},[6722],{"type":39,"value":182},{"type":26,"tag":157,"props":6724,"children":6725},{"style":1250},[6726],{"type":39,"value":6727},"traefik:3\n",{"type":26,"tag":157,"props":6729,"children":6730},{"class":159,"line":320},[6731,6736,6740],{"type":26,"tag":157,"props":6732,"children":6733},{"style":3608},[6734],{"type":39,"value":6735},"    network_mode",{"type":26,"tag":157,"props":6737,"children":6738},{"style":164},[6739],{"type":39,"value":182},{"type":26,"tag":157,"props":6741,"children":6742},{"style":1250},[6743],{"type":39,"value":6744},"host\n",{"type":26,"tag":157,"props":6746,"children":6747},{"class":159,"line":342},[6748,6752],{"type":26,"tag":157,"props":6749,"children":6750},{"style":3608},[6751],{"type":39,"value":5106},{"type":26,"tag":157,"props":6753,"children":6754},{"style":164},[6755],{"type":39,"value":3616},{"type":26,"tag":157,"props":6757,"children":6758},{"class":159,"line":363},[6759,6763],{"type":26,"tag":157,"props":6760,"children":6761},{"style":164},[6762],{"type":39,"value":5033},{"type":26,"tag":157,"props":6764,"children":6765},{"style":1250},[6766],{"type":39,"value":6767},"--certificatesresolvers.letsencrypt.acme.httpchallenge=true\n",{"type":26,"tag":157,"props":6769,"children":6770},{"class":159,"line":384},[6771,6775],{"type":26,"tag":157,"props":6772,"children":6773},{"style":164},[6774],{"type":39,"value":5033},{"type":26,"tag":157,"props":6776,"children":6777},{"style":1250},[6778],{"type":39,"value":6779},"--certificatesresolvers.letsencrypt.acme.email=\u003Cyour_email_here>\n",{"type":26,"tag":157,"props":6781,"children":6782},{"class":159,"line":402},[6783,6787],{"type":26,"tag":157,"props":6784,"children":6785},{"style":164},[6786],{"type":39,"value":5033},{"type":26,"tag":157,"props":6788,"children":6789},{"style":1250},[6790],{"type":39,"value":6791},"--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json\n",{"type":26,"tag":157,"props":6793,"children":6794},{"class":159,"line":411},[6795,6799],{"type":26,"tag":157,"props":6796,"children":6797},{"style":164},[6798],{"type":39,"value":5033},{"type":26,"tag":157,"props":6800,"children":6801},{"style":1250},[6802],{"type":39,"value":6803},"--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web\n",{"type":26,"tag":157,"props":6805,"children":6806},{"class":159,"line":425},[6807],{"type":26,"tag":157,"props":6808,"children":6809},{"emptyLinePlaceholder":1419},[6810],{"type":39,"value":1422},{"type":26,"tag":157,"props":6812,"children":6813},{"class":159,"line":434},[6814,6818],{"type":26,"tag":157,"props":6815,"children":6816},{"style":164},[6817],{"type":39,"value":5033},{"type":26,"tag":157,"props":6819,"children":6820},{"style":1250},[6821],{"type":39,"value":6822},"--entrypoints.web.address=:80\n",{"type":26,"tag":157,"props":6824,"children":6825},{"class":159,"line":456},[6826,6830],{"type":26,"tag":157,"props":6827,"children":6828},{"style":164},[6829],{"type":39,"value":5033},{"type":26,"tag":157,"props":6831,"children":6832},{"style":1250},[6833],{"type":39,"value":6834},"--entrypoints.websecure.address=:443\n",{"type":26,"tag":157,"props":6836,"children":6837},{"class":159,"line":478},[6838],{"type":26,"tag":157,"props":6839,"children":6840},{"style":164},[6841],{"type":39,"value":6842},"      \n",{"type":26,"tag":157,"props":6844,"children":6845},{"class":159,"line":491},[6846,6850],{"type":26,"tag":157,"props":6847,"children":6848},{"style":164},[6849],{"type":39,"value":5033},{"type":26,"tag":157,"props":6851,"children":6852},{"style":1250},[6853],{"type":39,"value":6854},"--entrypoints.web.http.redirections.entrypoint.to=websecure\n",{"type":26,"tag":157,"props":6856,"children":6857},{"class":159,"line":510},[6858,6862],{"type":26,"tag":157,"props":6859,"children":6860},{"style":164},[6861],{"type":39,"value":5033},{"type":26,"tag":157,"props":6863,"children":6864},{"style":1250},[6865],{"type":39,"value":6866},"--entrypoints.web.http.redirections.entrypoint.scheme=https\n",{"type":26,"tag":157,"props":6868,"children":6869},{"class":159,"line":519},[6870,6874],{"type":26,"tag":157,"props":6871,"children":6872},{"style":164},[6873],{"type":39,"value":5033},{"type":26,"tag":157,"props":6875,"children":6876},{"style":1250},[6877],{"type":39,"value":6878},"--entrypoints.websecure.http.tls.certresolver=letsencrypt\n",{"type":26,"tag":157,"props":6880,"children":6881},{"class":159,"line":528},[6882],{"type":26,"tag":157,"props":6883,"children":6884},{"emptyLinePlaceholder":1419},[6885],{"type":39,"value":1422},{"type":26,"tag":157,"props":6887,"children":6888},{"class":159,"line":536},[6889,6893],{"type":26,"tag":157,"props":6890,"children":6891},{"style":164},[6892],{"type":39,"value":5033},{"type":26,"tag":157,"props":6894,"children":6895},{"style":1250},[6896],{"type":39,"value":6897},"--providers.docker\n",{"type":26,"tag":157,"props":6899,"children":6900},{"class":159,"line":556},[6901,6905],{"type":26,"tag":157,"props":6902,"children":6903},{"style":164},[6904],{"type":39,"value":5033},{"type":26,"tag":157,"props":6906,"children":6907},{"style":1250},[6908],{"type":39,"value":6909},"--providers.docker.defaultrule=Host(`{{ trimPrefix `app-` .Name }}.example.com`)\n",{"type":26,"tag":157,"props":6911,"children":6912},{"class":159,"line":577},[6913,6917],{"type":26,"tag":157,"props":6914,"children":6915},{"style":164},[6916],{"type":39,"value":5033},{"type":26,"tag":157,"props":6918,"children":6919},{"style":1250},[6920],{"type":39,"value":6921},"--providers.docker.constraints=Label(`com.docker.compose.service`,`app`)\n",{"type":26,"tag":157,"props":6923,"children":6924},{"class":159,"line":589},[6925,6929],{"type":26,"tag":157,"props":6926,"children":6927},{"style":3608},[6928],{"type":39,"value":5021},{"type":26,"tag":157,"props":6930,"children":6931},{"style":164},[6932],{"type":39,"value":3616},{"type":26,"tag":157,"props":6934,"children":6935},{"class":159,"line":605},[6936,6940],{"type":26,"tag":157,"props":6937,"children":6938},{"style":164},[6939],{"type":39,"value":5033},{"type":26,"tag":157,"props":6941,"children":6942},{"style":1250},[6943],{"type":39,"value":6944},"/var/run/docker.sock:/var/run/docker.sock:ro\n",{"type":26,"tag":157,"props":6946,"children":6947},{"class":159,"line":613},[6948,6952],{"type":26,"tag":157,"props":6949,"children":6950},{"style":164},[6951],{"type":39,"value":5033},{"type":26,"tag":157,"props":6953,"children":6954},{"style":1250},[6955],{"type":39,"value":6956},"/letsencrypt:/letsencrypt\n",{"type":26,"tag":35,"props":6958,"children":6959},{},[6960],{"type":39,"value":6961},"Let's explain this a little",{"type":26,"tag":66,"props":6963,"children":6964},{},[6965,6978,6983,6988,6993],{"type":26,"tag":70,"props":6966,"children":6967},{},[6968,6970,6976],{"type":39,"value":6969},"We configure a ",{"type":26,"tag":47,"props":6971,"children":6973},{"href":6972},"https://letsencrypt.org/",[6974],{"type":39,"value":6975},"Let's Encrypt",{"type":39,"value":6977}," certificates resolvers (11-14)",{"type":26,"tag":70,"props":6979,"children":6980},{},[6981],{"type":39,"value":6982},"We listen on port 80 and 443 (16-17)",{"type":26,"tag":70,"props":6984,"children":6985},{},[6986],{"type":39,"value":6987},"We redirect all http traffic to https (19-20)",{"type":26,"tag":70,"props":6989,"children":6990},{},[6991],{"type":39,"value":6992},"and attach the configured certificates resolvers to it (21)",{"type":26,"tag":70,"props":6994,"children":6995},{},[6996],{"type":39,"value":6997},"We setup the docker provider (23-25)",{"type":26,"tag":122,"props":6999,"children":7001},{"id":7000},"explanation-for-lines-24-25",[7002],{"type":39,"value":7003},"Explanation for lines 24-25",{"type":26,"tag":141,"props":7005,"children":7007},{"code":7006},"--providers.docker.defaultrule=Host(`{{ trimPrefix 'app-'.Name }}.example.com`)\n",[7008],{"type":26,"tag":76,"props":7009,"children":7010},{"__ignoreMap":7},[7011],{"type":39,"value":7006},{"type":26,"tag":4639,"props":7013,"children":7014},{},[7015,7047],{"type":26,"tag":70,"props":7016,"children":7017},{},[7018,7024,7026,7032,7034,7039,7041],{"type":26,"tag":76,"props":7019,"children":7021},{"className":7020},[],[7022],{"type":39,"value":7023},".Name",{"type":39,"value":7025}," is autogenerated as ",{"type":26,"tag":76,"props":7027,"children":7029},{"className":7028},[],[7030],{"type":39,"value":7031},"\u003Cservice-name>-\u003Cstack_name>",{"type":39,"value":7033}," so for your ",{"type":26,"tag":76,"props":7035,"children":7037},{"className":7036},[],[7038],{"type":39,"value":6249},{"type":39,"value":7040}," example it would be ",{"type":26,"tag":76,"props":7042,"children":7044},{"className":7043},[],[7045],{"type":39,"value":7046},"app-whoami",{"type":26,"tag":70,"props":7048,"children":7049},{},[7050,7056,7058],{"type":26,"tag":76,"props":7051,"children":7053},{"className":7052},[],[7054],{"type":39,"value":7055},"trimPrefix 'app-'.Name",{"type":39,"value":7057}," resolves in ",{"type":26,"tag":76,"props":7059,"children":7061},{"className":7060},[],[7062],{"type":39,"value":6249},{"type":26,"tag":1270,"props":7064,"children":7065},{},[],{"type":26,"tag":141,"props":7067,"children":7068},{"code":6921},[7069],{"type":26,"tag":76,"props":7070,"children":7071},{"__ignoreMap":7},[7072],{"type":39,"value":6921},{"type":26,"tag":35,"props":7074,"children":7075},{},[7076,7078,7083,7085,7091,7093,7099],{"type":39,"value":7077},"All services should be exposed by default but should be filtered down, only to ",{"type":26,"tag":76,"props":7079,"children":7081},{"className":7080},[],[7082],{"type":39,"value":6548},{"type":39,"value":7084}," services. The label ",{"type":26,"tag":76,"props":7086,"children":7088},{"className":7087},[],[7089],{"type":39,"value":7090},"com.docker.compose.service",{"type":39,"value":7092}," is added by ",{"type":26,"tag":76,"props":7094,"children":7096},{"className":7095},[],[7097],{"type":39,"value":7098},"docker-compose",{"type":39,"value":7100}," to all containers .",{"type":26,"tag":110,"props":7102,"children":7104},{"id":7103},"bonus-configuration",[7105],{"type":39,"value":7106},"Bonus configuration",{"type":26,"tag":35,"props":7108,"children":7109},{},[7110],{"type":39,"value":7111},"We can tweak this configuration even more.",{"type":26,"tag":122,"props":7113,"children":7115},{"id":7114},"exposing-other-services-in-the-stack",[7116],{"type":39,"value":7117},"Exposing other services in the stack",{"type":26,"tag":35,"props":7119,"children":7120},{},[7121],{"type":39,"value":7122},"Sometimes you want to expose more than just the app container.",{"type":26,"tag":35,"props":7124,"children":7125},{},[7126,7128,7133],{"type":39,"value":7127},"The current configuration won't route traffic to any other services other than ",{"type":26,"tag":76,"props":7129,"children":7131},{"className":7130},[],[7132],{"type":39,"value":6548},{"type":39,"value":7134},".\nTo still be able to use the default configuration method, we need to re-enable it.",{"type":26,"tag":141,"props":7136,"children":7138},{"code":7137},"--providers.docker.constraints=Label(`com.docker.compose.service`,`app`) || Label(`traefik.enable`, `true`)\n",[7139],{"type":26,"tag":76,"props":7140,"children":7141},{"__ignoreMap":7},[7142],{"type":39,"value":7137},{"type":26,"tag":122,"props":7144,"children":7146},{"id":7145},"stack-name-other-than-directory-name",[7147],{"type":39,"value":7148},"Stack name other than directory name",{"type":26,"tag":35,"props":7150,"children":7151},{},[7152,7154,7159],{"type":39,"value":7153},"When deploying the stacks, the name is generated based on directory name where the ",{"type":26,"tag":76,"props":7155,"children":7157},{"className":7156},[],[7158],{"type":39,"value":6382},{"type":39,"value":7160}," file is located.\nWe can change the make in several ways, but here is the easiest one:",{"type":26,"tag":141,"props":7162,"children":7166},{"code":7163,"filename":7164,"highlights":7165,"language":3598,"meta":7,"className":3595,"style":7},"name: whoami\nservices:\n  app:\n    image: traefik/whoami\n","whoami-example/docker-compose.yaml",[160],[7167],{"type":26,"tag":76,"props":7168,"children":7169},{"__ignoreMap":7},[7170,7188,7199,7210],{"type":26,"tag":157,"props":7171,"children":7173},{"class":7172,"line":160},[159,715],[7174,7179,7183],{"type":26,"tag":157,"props":7175,"children":7176},{"style":3608},[7177],{"type":39,"value":7178},"name",{"type":26,"tag":157,"props":7180,"children":7181},{"style":164},[7182],{"type":39,"value":182},{"type":26,"tag":157,"props":7184,"children":7185},{"style":1250},[7186],{"type":39,"value":7187},"whoami\n",{"type":26,"tag":157,"props":7189,"children":7190},{"class":159,"line":170},[7191,7195],{"type":26,"tag":157,"props":7192,"children":7193},{"style":3608},[7194],{"type":39,"value":4964},{"type":26,"tag":157,"props":7196,"children":7197},{"style":164},[7198],{"type":39,"value":3616},{"type":26,"tag":157,"props":7200,"children":7201},{"class":159,"line":196},[7202,7206],{"type":26,"tag":157,"props":7203,"children":7204},{"style":3608},[7205],{"type":39,"value":6588},{"type":26,"tag":157,"props":7207,"children":7208},{"style":164},[7209],{"type":39,"value":3616},{"type":26,"tag":157,"props":7211,"children":7212},{"class":159,"line":218},[7213,7217,7221],{"type":26,"tag":157,"props":7214,"children":7215},{"style":3608},[7216],{"type":39,"value":4987},{"type":26,"tag":157,"props":7218,"children":7219},{"style":164},[7220],{"type":39,"value":182},{"type":26,"tag":157,"props":7222,"children":7223},{"style":1250},[7224],{"type":39,"value":6155},{"type":26,"tag":4462,"props":7226,"children":7227},{},[7228],{"type":39,"value":4466},{"title":7,"searchDepth":170,"depth":170,"links":7230},[7231,7232,7235],{"id":6313,"depth":170,"text":6316},{"id":6405,"depth":170,"text":6408,"children":7233},[7234],{"id":7000,"depth":196,"text":7003},{"id":7103,"depth":170,"text":7106,"children":7236},[7237,7238],{"id":7114,"depth":196,"text":7117},{"id":7145,"depth":196,"text":7148},{"_path":4511,"_dir":4512,"_draft":6,"_partial":6,"_locale":7,"slug":10,"teams":7240,"primaryTeam":4515,"firstName":4516,"lastName":4517,"prefixTitle":7,"suffixTitle":4518,"education":7241,"role":7243,"workingSince":4529,"inTheCompanySince":4530,"techSkills":7244,"skills":7258,"projects":7268,"contactDetails":7273,"_image":4601,"image":4602,"_id":4603,"_type":151,"title":4604,"_source":4512,"_file":4605,"_stem":4606,"_extension":151},[4514,4515],[7242],[4521,4522,4523],[4525,4526,4527,4528],[7245,7246,7247,7248,7249,7250,7251,7252,7253,7254,7255,7256,7257],{"name":4533,"level":4534,"icon":4535},{"name":4537,"level":4534},{"name":4539,"level":4534,"icon":4540},{"name":4542,"level":4534,"icon":4543},{"name":4545,"level":4534,"icon":4546},{"name":4548,"level":4534},{"name":4550,"level":4534,"icon":4551},{"name":4553,"level":4534,"icon":4554},{"name":4556,"level":4557,"icon":4558},{"name":4560,"level":4557,"icon":4561},{"name":4563,"level":4557},{"name":4565,"level":4557,"icon":4566},{"name":4568,"level":4557,"icon":4569},[7259,7260,7261,7262,7263,7264,7265,7266,7267],{"name":3492,"level":4534},{"name":4573,"level":4534},{"name":4515,"level":4534},{"name":4576,"level":4534},{"name":4578,"level":4534},{"name":4580,"level":4557},{"name":4582,"level":4557},{"name":4584,"level":4557},{"name":4586,"level":4557},[7269,7271,7272],{"project":4589,"position":7270},[4591,4592],{"project":4594,"position":4592},{"project":4596,"position":4592},{"eMail":4598,"phone":4599,"visibility":4600},[7275,7289,7301,7313],{"_path":7276,"_dir":7277,"_draft":6,"_partial":1419,"_locale":7,"name":7278,"slug":7277,"text":7279,"hoverText":7280,"image":7281,"customer":7282,"tags":7283,"_id":7285,"_type":3598,"title":7286,"_source":4481,"_file":7287,"_stem":7288,"_extension":3598},"/en/portfolio/bitburger/_teaser","bitburger","Bitburger B2B and Brand Shops","Relaunch of Bitburger Brewery Group online shops with new platform","Migration of all brand shops and B2B shop of Bitburger Brewery Group to a unified platform. Ongoing support for redesign initiatives and integration of additional subsystems.","/images/portfolio/bitburger/Bitburger_HuW_Glaeser.jpg","Bitburger",[20,7284],"e-commerce","common:en:portfolio:900.bitburger:_teaser.yaml","Teaser","en/portfolio/900.bitburger/_teaser.yaml","en/portfolio/900.bitburger/_teaser",{"_path":7290,"_dir":7291,"_draft":6,"_partial":1419,"_locale":7,"name":7292,"slug":7291,"text":7293,"hoverText":7294,"image":7295,"customer":7296,"tags":7297,"_id":7298,"_type":3598,"title":7286,"_source":4481,"_file":7299,"_stem":7300,"_extension":3598},"/en/portfolio/purize/_teaser","purize","Purize Filters","E-Commerce for high-quality activated carbon filters","We support PURIZE® Filters with a complete e-commerce service including fulfillment solution and connection to shipping service providers. Our expertise in online retail enables the manufacturer of high-quality activated carbon filters \"Made in Germany\" to process their orders smoothly.","/images/portfolio/barcode-machine-verdandijpg.jpg","PURIZE® Filters",[20,7284],"common:en:portfolio:9000.purize:_teaser.yaml","en/portfolio/9000.purize/_teaser.yaml","en/portfolio/9000.purize/_teaser",{"_path":7302,"_dir":7303,"_draft":6,"_partial":1419,"_locale":7,"name":7304,"slug":7303,"text":7305,"hoverText":7306,"image":7307,"customer":7304,"tags":7308,"_id":7310,"_type":3598,"title":7286,"_source":4481,"_file":7311,"_stem":7312,"_extension":3598},"/en/portfolio/pixelx/_teaser","pixelx","PixelX","IT Security with Precision and Expertise","For PixelX, we conducted a targeted security analysis where, thanks to our deep technical understanding, we were able to identify a critical SQL injection vulnerability. With minimal time investment, we achieved maximum security gain.","/images/portfolio/pixelx/pixelx_secured.png",[7309,21],"security","common:en:portfolio:9010.pixelx:_teaser.yaml","en/portfolio/9010.pixelx/_teaser.yaml","en/portfolio/9010.pixelx/_teaser",{"_path":7314,"_dir":7315,"_draft":6,"_partial":1419,"_locale":7,"name":7316,"slug":7315,"text":7317,"hoverText":7318,"image":7319,"customer":7316,"tags":7320,"_id":7321,"_type":3598,"title":7286,"_source":4481,"_file":7322,"_stem":7323,"_extension":3598},"/en/portfolio/slimspots/_teaser","slimspots","SlimSpots","Processing large amounts of data in real-time","For SlimSpots, a global provider of ad marketing solutions, we developed a highly scalable infrastructure that enables the processing of trillions of data records in real-time.","/images/portfolio/slimspots/slim_spots_prtfolio.png",[4582,21],"common:en:portfolio:9020.slimspots:_teaser.yaml","en/portfolio/9020.slimspots/_teaser.yaml","en/portfolio/9020.slimspots/_teaser",1782284057241]