[{"data":1,"prerenderedAt":2226},["ShallowReactive",2],{"blog-current-amazon-mws-sp-api-wrapper-en":3,"blog-previous-amazon-mws-sp-api-wrapper-en":102,"blog-next-amazon-mws-sp-api-wrapper-en":116,"blog-alt-de-amazon-mws-sp-api-wrapper-en":130,"blog-alt-en-amazon-mws-sp-api-wrapper-en":132,"employee-bernd-helm":133,"content-query-t20WiKE4uI":240,"content-query-yliWk2uBx7":813,"content-query-1PFeYVQSzn":2069,"content-query-vhr2h3d1hs":2105,"related-refs-e-commerce_backend--en":2173},{"_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":96,"_id":97,"_source":98,"_file":99,"_stem":100,"_extension":101},"/en/blog/amazon-mws-sp-api-wrapper","blog",false,"","Amazon MWS to SP API Wrapper","We have released a wrapper that converts Amazon MWS to SP API, offering developers with outdated systems a simple solution. This open-source project provides a practical alternative to redevelopment and supports the continuation of existing applications.","bernd-helm","/blog/thumbnails/AWS.svg","2024-02-21",[14,15],"What moves us","DevOps",[17,18],"Amazon","Open Source",[20,21],"e-commerce","backend",{"type":23,"children":24,"toc":91},"root",[25,34,57,62,67,73,86],{"type":26,"tag":27,"props":28,"children":30},"element","h2",{"id":29},"what-is-this",[31],{"type":32,"value":33},"text","What is this?",{"type":26,"tag":35,"props":36,"children":37},"p",{},[38,40,47,49,55],{"type":32,"value":39},"This wrapper serves as a simple and cost-effective bridge that translates calls from the\n",{"type":26,"tag":41,"props":42,"children":44},"a",{"href":43},"https://docs.developer.amazonservices.com/en_US/dev_guide/index.html",[45],{"type":32,"value":46},"Amazon Marketplace Web Service (MWS)",{"type":32,"value":48},"\nAPI to ",{"type":26,"tag":41,"props":50,"children":52},{"href":51},"https://developer-docs.amazon.com/sp-api",[53],{"type":32,"value":54},"Selling Partner (SP) API",{"type":32,"value":56}," calls. It was specifically developed for customers with outdated systems and limited\nbudgets, for whom a complete redevelopment of the Amazon interface would be economically unfeasible.\nThe wrapper allows these customers to continue their business even after the MWS interface is discontinued.",{"type":26,"tag":35,"props":58,"children":59},{},[60],{"type":32,"value":61},"Technically, the project is based on a Docker container that functions as a web server. This server receives MWS API calls,\ntranslates them into SP API calls, and converts the responses from the SP API back into the format of the MWS API.",{"type":26,"tag":35,"props":63,"children":64},{},[65],{"type":32,"value":66},"The idea for this wrapper originated from a proof of concept, with the aim to verify whether the interfaces are\nsufficiently similar to enable a direct translation. Despite concerns that the devil might be in the details,\nthe calls proved to be relatively simple to translate. It was only necessary to adjust some feed names\nand occasionally make two API calls to gather all the necessary information.\nOverall, the project has been surprisingly trouble-free.",{"type":26,"tag":27,"props":68,"children":70},{"id":69},"download",[71],{"type":32,"value":72},"Download",{"type":26,"tag":35,"props":74,"children":75},{},[76,78,84],{"type":32,"value":77},"Interested? The project has been published as open-source on GitHub:\n",{"type":26,"tag":41,"props":79,"children":81},{"href":80},"https://github.com/bhelm/Amazon-MWS-SP-Wrapper",[82],{"type":32,"value":83},"Amazon-MWS-SP-API-Wrapper",{"type":32,"value":85},". This offer is aimed at developers\nwho also see the wrapper approach as the most efficient solution and want to contribute to the open-source community.",{"type":26,"tag":35,"props":87,"children":88},{},[89],{"type":32,"value":90},"If you need support integrating it into your application or if adjustments or extensions to the wrapper\nare necessary, we are happy to help. Since the wrapper is currently used by only a limited number of customers,\nit covers only part of the possible API calls and parameters and is by no means a \"complete solution\".",{"title":7,"searchDepth":92,"depth":92,"links":93},2,[94,95],{"id":29,"depth":92,"text":33},{"id":69,"depth":92,"text":72},"markdown","common:en:blog:11.amazon-mws-sp-api-wrapper.md","common","en/blog/11.amazon-mws-sp-api-wrapper.md","en/blog/11.amazon-mws-sp-api-wrapper","md",{"_path":103,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":104,"description":105,"author":10,"image":106,"releaseDate":107,"blogCategories":108,"articleTags":109,"tags":111,"_type":96,"_id":113,"_source":98,"_file":114,"_stem":115,"_extension":101},"/en/blog/how-to-use-different-dns-servers-on-specific-domains","How to use different DNS servers for specific domains name resolution – VPN Use-Case","How to resolve selected domains over VPN on linux. In today's world, more people than ever use VPN services to work from remote. However, in some cases it's not desirable to route all traffic and all domain name resolutions over the VPN connection.","/blog/thumbnails/VPN.png","2022-04-21",[14,15],[110],"VPN",[112],"devops","common:en:blog:10.how-to-use-different-dns-servers-on-specific-domains.md","en/blog/10.how-to-use-different-dns-servers-on-specific-domains.md","en/blog/10.how-to-use-different-dns-servers-on-specific-domains",{"_path":117,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":118,"description":119,"author":120,"image":121,"releaseDate":122,"blogCategories":123,"articleTags":125,"tags":126,"_type":96,"_id":127,"_source":98,"_file":128,"_stem":129,"_extension":101},"/en/blog/a-tribute-to-our-dev-ops","A Tribute to Our Dev Ops","Web applications are mostly developed and tested in a dev environment - however the true endurance test comes from practical scenarios on the prod systems.","jens-bornschein","/images/dev-ops-dark.svg","2025-03-31",[124],"What Moves Us",[15],[112],"common:en:blog:12.a-tribute-to-our-dev-ops.md","en/blog/12.a-tribute-to-our-dev-ops.md","en/blog/12.a-tribute-to-our-dev-ops",{"_path":131},"/blog/amazon-mws-sp-api-wrapper-de",{"_path":4},{"_path":134,"_dir":135,"_draft":6,"_partial":6,"_locale":7,"slug":10,"teams":136,"primaryTeam":138,"firstName":139,"lastName":140,"prefixTitle":7,"suffixTitle":7,"education":141,"executiveRole":146,"role":147,"workingSince":155,"inTheCompanySince":156,"techSkills":157,"skills":203,"projects":216,"contactDetails":229,"_image":233,"image":234,"_id":235,"_type":236,"title":237,"_source":135,"_file":238,"_stem":239,"_extension":236},"/employees/bernd-helm","employees",[137,138],"ai","devOps","Bernd","Helm",[142],[143,144,145],"B. Sc. Angewandte Informatik","FHDW Dresden","2010","CTO",[148,149,138,150,151,152,153,154],"founder","chiefTechnologyOfficer","databaseSpecialist","admin","softwareDeveloper","backendDeveloper","consultant","2005","2008",[158,162,165,167,170,172,175,177,179,181,184,188,191,194,197,200],{"name":159,"level":160,"icon":161},"Docker","expert","/images/Docker.svg",{"name":163,"level":160,"icon":164},"Linux","/images/linux_os-mono.svg",{"name":166,"level":160},"Zabbix",{"name":168,"level":160,"icon":169},"MariaDB ColumnStore","/images/maria-db-logo.svg",{"name":171,"level":160},"OpenAI",{"name":173,"level":160,"icon":174},"Pytorch","/images/PyTorch.svg",{"name":176,"level":160},"PHP",{"name":178,"level":160},"Java",{"name":180,"level":160},"Python",{"name":182,"level":160,"icon":183},"SQL","/images/SQL.svg",{"name":185,"level":186,"icon":187},"C++","advanced","/images/cpp-logo.svg",{"name":189,"level":186,"icon":190},"C#","/images/csharp.svg",{"name":192,"level":186,"icon":193},"CSS","/images/css.svg",{"name":195,"level":186,"icon":196},"HTML","/images/html.svg",{"name":198,"level":186,"icon":199},"OpenCV","/images/OpenCV.svg",{"name":201,"level":186,"icon":202},"Vue.js","/images/vuejs.svg",[204,206,208,210,212,214],{"name":205,"level":160},"artificialIntelligence",{"name":207,"level":160},"codingGuidelines",{"name":209,"level":160},"databases",{"name":211,"level":160},"linuxServerAdministration",{"name":213,"level":160},"softwareArchitect",{"name":215,"level":186},"qualityAssurance",[217,220,222,224,227],{"project":218,"position":219},"Gridside","Technical Consultant",{"project":221,"position":219},"Herole",{"project":223,"position":219},"Montagespezis",{"project":225,"position":226},"Orsee","Technical Manager",{"project":228,"position":219},"Vipr",{"eMail":230,"phone":231,"visibility":232},"bernd.helm@helmundwalter.de","+49 351 799 035 20","1","images/employees/Portraits/bernd_helm.webp","images/employees/Portraits/BerndHelm_MS.webp","employees:employees:1.bernd-helm.json","json","Bernd Helm","employees/1.bernd-helm.json","employees/1.bernd-helm",{"_path":103,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":104,"description":105,"author":10,"image":106,"releaseDate":107,"blogCategories":241,"articleTags":242,"tags":243,"body":244,"_type":96,"_id":113,"_source":98,"_file":114,"_stem":115,"_extension":101},[14,15],[110],[112],{"type":23,"children":245,"toc":808},[246,252,257,262,284,297,303,332,349,355,360,373,386,419,454,475,530,547,574,617,646,696,715,728,770,782,802],{"type":26,"tag":27,"props":247,"children":249},{"id":248},"how-to-resolve-selected-domains-over-vpn-on-linux",[250],{"type":32,"value":251},"How to resolve selected domains over VPN on Linux",{"type":26,"tag":35,"props":253,"children":254},{},[255],{"type":32,"value":256},"In today's world, more people than ever use VPN services to work from remote. However, in some cases it's not desirable\nto route all traffic and all domain name resolutions over the VPN connection. Even if the VPN-Server wants the client to\nconfigure itself to work like this, the client can be configured to ignore the request to route all traffic over the VPN\nconnection.",{"type":26,"tag":35,"props":258,"children":259},{},[260],{"type":32,"value":261},"For example, with Openvpn the option",{"type":26,"tag":263,"props":264,"children":268},"pre",{"className":265,"code":266,"language":267,"meta":7,"style":7},"language-apache shiki shiki-themes github-dark github-dark monokai","pull-filter ignore redirect-gateway\n","apache",[269],{"type":26,"tag":270,"props":271,"children":272},"code",{"__ignoreMap":7},[273],{"type":26,"tag":274,"props":275,"children":278},"span",{"class":276,"line":277},"line",1,[279],{"type":26,"tag":274,"props":280,"children":282},{"style":281},"--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2",[283],{"type":32,"value":266},{"type":26,"tag":35,"props":285,"children":286},{},[287,289,295],{"type":32,"value":288},"can be used to tell the ",{"type":26,"tag":270,"props":290,"children":292},{"className":291},[],[293],{"type":32,"value":294},"openvpn-client",{"type":32,"value":296}," to ignore all \"route all\" requests from the server.",{"type":26,"tag":27,"props":298,"children":300},{"id":299},"fritzbox-example",[301],{"type":32,"value":302},"FRITZ!Box example",{"type":26,"tag":35,"props":304,"children":305},{},[306,308,314,316,322,324,330],{"type":32,"value":307},"Recently I had to use a VPN-Connection to a ",{"type":26,"tag":309,"props":310,"children":311},"strong",{},[312],{"type":32,"value":313},"FRITZ!Box",{"type":32,"value":315},". It's a very popular router in Germany that not only offers\neasy\nVPN-Connections but also adds all hosts on its network to its own dns. If you want to talk to a machine with the name ",{"type":26,"tag":270,"props":317,"children":319},{"className":318},[],[320],{"type":32,"value":321}," workstation",{"type":32,"value":323}," you can reach it using the \"workstation.fritz.box\" dns name. The fritz-box itself is also available on the\ndns name ",{"type":26,"tag":270,"props":325,"children":327},{"className":326},[],[328],{"type":32,"value":329},"fritz.box",{"type":32,"value":331},".",{"type":26,"tag":35,"props":333,"children":334},{},[335,337,342,344,348],{"type":32,"value":336},"In my case, I prefer to use my own DNS server for all queries because of speed and privacy reasons - that means, I only\nwant the\ndomains with the ",{"type":26,"tag":270,"props":338,"children":340},{"className":339},[],[341],{"type":32,"value":329},{"type":32,"value":343}," suffix to resolve over the ",{"type":26,"tag":309,"props":345,"children":346},{},[347],{"type":32,"value":313},{"type":32,"value":331},{"type":26,"tag":27,"props":350,"children":352},{"id":351},"solution-using-a-local-dns-server-dnsmasq",[353],{"type":32,"value":354},"Solution using a local DNS server - dnsmasq",{"type":26,"tag":35,"props":356,"children":357},{},[358],{"type":32,"value":359},"Dnsmasq is a lightweight DNS-Server that you can run on your machine to get control on how the name resolution works. A\nnice side effect is that it has its own dns cache, making recurring dns queries faster. Here is how I have set it up:",{"type":26,"tag":35,"props":361,"children":362},{},[363,365,371],{"type":32,"value":364},"Before you start you need to find out which DNS server is used on the VPN. It's usually the default gateway that usually\nhas a ",{"type":26,"tag":270,"props":366,"children":368},{"className":367},[],[369],{"type":32,"value":370},".1",{"type":32,"value":372}," at the end. You can watch the VPN logs closely to learn which DNS server gets pushed on connect.",{"type":26,"tag":35,"props":374,"children":375},{},[376,378,384],{"type":32,"value":377},"There is a tool called ",{"type":26,"tag":270,"props":379,"children":381},{"className":380},[],[382],{"type":32,"value":383},"dig",{"type":32,"value":385}," which can do dns queries over specified dns servers, for example",{"type":26,"tag":263,"props":387,"children":391},{"className":388,"code":389,"language":390,"meta":7,"style":7},"language-bash shiki shiki-themes github-dark github-dark monokai","dig @192.168.1.1 a fritz.box\n","bash",[392],{"type":26,"tag":270,"props":393,"children":394},{"__ignoreMap":7},[395],{"type":26,"tag":274,"props":396,"children":397},{"class":276,"line":277},[398,403,409,414],{"type":26,"tag":274,"props":399,"children":401},{"style":400},"--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E",[402],{"type":32,"value":383},{"type":26,"tag":274,"props":404,"children":406},{"style":405},"--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74",[407],{"type":32,"value":408}," @192.168.1.1",{"type":26,"tag":274,"props":410,"children":411},{"style":405},[412],{"type":32,"value":413}," a",{"type":26,"tag":274,"props":415,"children":416},{"style":405},[417],{"type":32,"value":418}," fritz.box\n",{"type":26,"tag":35,"props":420,"children":421},{},[422,424,430,432,437,439,445,447,453],{"type":32,"value":423},"will ask the dns server ",{"type":26,"tag":270,"props":425,"children":427},{"className":426},[],[428],{"type":32,"value":429},"192.168.1.1",{"type":32,"value":431}," for the ip of ",{"type":26,"tag":270,"props":433,"children":435},{"className":434},[],[436],{"type":32,"value":329},{"type":32,"value":438},". ",{"type":26,"tag":270,"props":440,"children":442},{"className":441},[],[443],{"type":32,"value":444},"Dig",{"type":32,"value":446}," is very handy when debugging dns problems and to\ntest\nyour setup. You may have to install it on your System. On debian, it lives in a package called ",{"type":26,"tag":270,"props":448,"children":450},{"className":449},[],[451],{"type":32,"value":452},"dnsutils",{"type":32,"value":331},{"type":26,"tag":35,"props":455,"children":456},{},[457,459,465,467,473],{"type":32,"value":458},"First install ",{"type":26,"tag":270,"props":460,"children":462},{"className":461},[],[463],{"type":32,"value":464},"dnsmasq",{"type":32,"value":466}," on your Linux and edit its configuration (usually lives in ",{"type":26,"tag":270,"props":468,"children":470},{"className":469},[],[471],{"type":32,"value":472},"/etc/dnsmasq.conf",{"type":32,"value":474},"). Add these lines\nhere:",{"type":26,"tag":263,"props":476,"children":478},{"className":265,"code":477,"language":267,"meta":7,"style":7},"resolv-file=/etc/resolv.dnsmasq.conf\nserver=/fritz.box/192.168.1.1\n",[479],{"type":26,"tag":270,"props":480,"children":481},{"__ignoreMap":7},[482,490],{"type":26,"tag":274,"props":483,"children":484},{"class":276,"line":277},[485],{"type":26,"tag":274,"props":486,"children":487},{"style":281},[488],{"type":32,"value":489},"resolv-file=/etc/resolv.dnsmasq.conf\n",{"type":26,"tag":274,"props":491,"children":492},{"class":276,"line":92},[493,498,504,508,513,517,521,525],{"type":26,"tag":274,"props":494,"children":495},{"style":281},[496],{"type":32,"value":497},"server=/fritz.box/",{"type":26,"tag":274,"props":499,"children":501},{"style":500},"--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF",[502],{"type":32,"value":503},"192",{"type":26,"tag":274,"props":505,"children":506},{"style":281},[507],{"type":32,"value":331},{"type":26,"tag":274,"props":509,"children":510},{"style":500},[511],{"type":32,"value":512},"168",{"type":26,"tag":274,"props":514,"children":515},{"style":281},[516],{"type":32,"value":331},{"type":26,"tag":274,"props":518,"children":519},{"style":500},[520],{"type":32,"value":232},{"type":26,"tag":274,"props":522,"children":523},{"style":281},[524],{"type":32,"value":331},{"type":26,"tag":274,"props":526,"children":527},{"style":500},[528],{"type":32,"value":529},"1\n",{"type":26,"tag":35,"props":531,"children":532},{},[533,538,540,545],{"type":26,"tag":270,"props":534,"children":536},{"className":535},[],[537],{"type":32,"value":329},{"type":32,"value":539}," is the domain you want to resolve over the VPN-Dns-server, ",{"type":26,"tag":270,"props":541,"children":543},{"className":542},[],[544],{"type":32,"value":429},{"type":32,"value":546}," in this example.",{"type":26,"tag":35,"props":548,"children":549},{},[550,552,557,559,564,566,572],{"type":32,"value":551},"The ",{"type":26,"tag":309,"props":553,"children":554},{},[555],{"type":32,"value":556},"Resolv-File",{"type":32,"value":558}," will tell ",{"type":26,"tag":270,"props":560,"children":562},{"className":561},[],[563],{"type":32,"value":464},{"type":32,"value":565}," how it should resolve its dns queries in case there are no other rules, so let's\ncreate\na ",{"type":26,"tag":270,"props":567,"children":569},{"className":568},[],[570],{"type":32,"value":571},"/etc/resolv.dnsmasq.conf",{"type":32,"value":573},"\nwith content",{"type":26,"tag":263,"props":575,"children":577},{"className":265,"code":576,"language":267,"meta":7,"style":7},"nameserver 1.1.1.1\n",[578],{"type":26,"tag":270,"props":579,"children":580},{"__ignoreMap":7},[581],{"type":26,"tag":274,"props":582,"children":583},{"class":276,"line":277},[584,589,593,597,601,605,609,613],{"type":26,"tag":274,"props":585,"children":586},{"style":281},[587],{"type":32,"value":588},"nameserver ",{"type":26,"tag":274,"props":590,"children":591},{"style":500},[592],{"type":32,"value":232},{"type":26,"tag":274,"props":594,"children":595},{"style":281},[596],{"type":32,"value":331},{"type":26,"tag":274,"props":598,"children":599},{"style":500},[600],{"type":32,"value":232},{"type":26,"tag":274,"props":602,"children":603},{"style":281},[604],{"type":32,"value":331},{"type":26,"tag":274,"props":606,"children":607},{"style":500},[608],{"type":32,"value":232},{"type":26,"tag":274,"props":610,"children":611},{"style":281},[612],{"type":32,"value":331},{"type":26,"tag":274,"props":614,"children":615},{"style":500},[616],{"type":32,"value":529},{"type":26,"tag":35,"props":618,"children":619},{},[620,622,628,630,636,638,644],{"type":32,"value":621},"If you use a static network configuration, you now can just edit it to use ",{"type":26,"tag":270,"props":623,"children":625},{"className":624},[],[626],{"type":32,"value":627},"127.0.0.1",{"type":32,"value":629}," as its nameserver. If you use\nautomatic ip configuration using dhcp, you need to configure your dhcp client use the new local dns server. On debian,\nthe default is ",{"type":26,"tag":270,"props":631,"children":633},{"className":632},[],[634],{"type":32,"value":635},"dhclient",{"type":32,"value":637},". In that case edit ",{"type":26,"tag":270,"props":639,"children":641},{"className":640},[],[642],{"type":32,"value":643},"/etc/dhcp/dhclient.conf",{"type":32,"value":645}," and add:",{"type":26,"tag":263,"props":647,"children":649},{"className":265,"code":648,"language":267,"meta":7,"style":7},"prepend domain-name-servers 127.0.0.1;\n",[650],{"type":26,"tag":270,"props":651,"children":652},{"__ignoreMap":7},[653],{"type":26,"tag":274,"props":654,"children":655},{"class":276,"line":277},[656,661,666,670,675,679,683,687,691],{"type":26,"tag":274,"props":657,"children":658},{"style":281},[659],{"type":32,"value":660},"prepend domain-name-servers ",{"type":26,"tag":274,"props":662,"children":663},{"style":500},[664],{"type":32,"value":665},"127",{"type":26,"tag":274,"props":667,"children":668},{"style":281},[669],{"type":32,"value":331},{"type":26,"tag":274,"props":671,"children":672},{"style":500},[673],{"type":32,"value":674},"0",{"type":26,"tag":274,"props":676,"children":677},{"style":281},[678],{"type":32,"value":331},{"type":26,"tag":274,"props":680,"children":681},{"style":500},[682],{"type":32,"value":674},{"type":26,"tag":274,"props":684,"children":685},{"style":281},[686],{"type":32,"value":331},{"type":26,"tag":274,"props":688,"children":689},{"style":500},[690],{"type":32,"value":232},{"type":26,"tag":274,"props":692,"children":693},{"style":281},[694],{"type":32,"value":695},";\n",{"type":26,"tag":35,"props":697,"children":698},{},[699,701,706,708,713],{"type":32,"value":700},"That's it. All you have to do now is to restart ",{"type":26,"tag":270,"props":702,"children":704},{"className":703},[],[705],{"type":32,"value":464},{"type":32,"value":707}," so it reloads its config and reconnect/restart ",{"type":26,"tag":270,"props":709,"children":711},{"className":710},[],[712],{"type":32,"value":635},{"type":32,"value":714},"\n(disconnecting and reconnecting the network may work, reboot the machine when in doubt).",{"type":26,"tag":35,"props":716,"children":717},{},[718,720,726],{"type":32,"value":719},"Now you can check if the file ",{"type":26,"tag":270,"props":721,"children":723},{"className":722},[],[724],{"type":32,"value":725},"/etc/resolv.conf",{"type":32,"value":727}," has",{"type":26,"tag":263,"props":729,"children":731},{"className":265,"code":730,"language":267,"meta":7,"style":7},"nameserver 127.0.0.1\n",[732],{"type":26,"tag":270,"props":733,"children":734},{"__ignoreMap":7},[735],{"type":26,"tag":274,"props":736,"children":737},{"class":276,"line":277},[738,742,746,750,754,758,762,766],{"type":26,"tag":274,"props":739,"children":740},{"style":281},[741],{"type":32,"value":588},{"type":26,"tag":274,"props":743,"children":744},{"style":500},[745],{"type":32,"value":665},{"type":26,"tag":274,"props":747,"children":748},{"style":281},[749],{"type":32,"value":331},{"type":26,"tag":274,"props":751,"children":752},{"style":500},[753],{"type":32,"value":674},{"type":26,"tag":274,"props":755,"children":756},{"style":281},[757],{"type":32,"value":331},{"type":26,"tag":274,"props":759,"children":760},{"style":500},[761],{"type":32,"value":674},{"type":26,"tag":274,"props":763,"children":764},{"style":281},[765],{"type":32,"value":331},{"type":26,"tag":274,"props":767,"children":768},{"style":500},[769],{"type":32,"value":529},{"type":26,"tag":35,"props":771,"children":772},{},[773,775,780],{"type":32,"value":774},"as first nameserver. If it has, the selected domain (",{"type":26,"tag":270,"props":776,"children":778},{"className":777},[],[779],{"type":32,"value":329},{"type":32,"value":781}," in my example) should now resolve.",{"type":26,"tag":35,"props":783,"children":784},{},[785,787,792,794,800],{"type":32,"value":786},"On ",{"type":26,"tag":270,"props":788,"children":790},{"className":789},[],[791],{"type":32,"value":464},{"type":32,"value":793},", you can add multiple ",{"type":26,"tag":270,"props":795,"children":797},{"className":796},[],[798],{"type":32,"value":799},"server=",{"type":32,"value":801}," lines, which comes in handy if you have multiple domains that need to be\nresolved over different DNS servers.",{"type":26,"tag":803,"props":804,"children":805},"style",{},[806],{"type":32,"value":807},"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":92,"depth":92,"links":809},[810,811,812],{"id":248,"depth":92,"text":251},{"id":299,"depth":92,"text":302},{"id":351,"depth":92,"text":354},{"_path":117,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":118,"description":119,"author":120,"image":121,"releaseDate":122,"blogCategories":814,"articleTags":815,"tags":816,"body":817,"_type":96,"_id":127,"_source":98,"_file":128,"_stem":129,"_extension":101},[124],[15],[112],{"type":23,"children":818,"toc":2059},[819,828,847,853,899,964,976,982,992,1033,1042,1074,1114,1123,1156,1175,1218,1224,1233,1265,1310,1335,1345,1362,1368,1377,1406,1528,1532,1576,1582,1591,1643,1674,1698,1729,1747,1753,1762,1794,1813,1849,1868,1894,1906,1912,1921,1947,2003,2009,2037,2049],{"type":26,"tag":820,"props":821,"children":827},"img",{"alt":822,"aspect-ratio":823,"height":824,"object-fit":825,"src":826},"A person holding a sticker with the word \"Dev-ops\" wright in front of the camera","2.07",300,"fill","/blog/person_holding_devops_sticker.jpg",[],{"type":26,"tag":274,"props":829,"children":833},{"className":830},[831,832],"text-right","text-caption",[834],{"type":26,"tag":35,"props":835,"children":836},{},[837],{"type":26,"tag":838,"props":839,"children":840},"em",{},[841],{"type":26,"tag":41,"props":842,"children":844},{"href":843},"https://www.pexels.com/photo/person-holding-a-sticker-11035393/",[845],{"type":32,"value":846},"Photo by RealToughCandy.com",{"type":26,"tag":27,"props":848,"children":850},{"id":849},"why-developing-a-web-application-is-only-the-beginning",[851],{"type":32,"value":852},"Why developing a (web) application is only the beginning",{"type":26,"tag":35,"props":854,"children":855},{},[856,858,863,865,870,872,876,878,883,885,890,892,897],{"type":32,"value":857},"Web applications are mostly developed and tested in a ",{"type":26,"tag":838,"props":859,"children":860},{},[861],{"type":32,"value":862},"Dev",{"type":32,"value":864}," environment (Development environment) - however the\nactual endurance test takes place on the ",{"type":26,"tag":838,"props":866,"children":867},{},[868],{"type":32,"value":869},"Prod",{"type":32,"value":871}," systems (Production environment). Here, ",{"type":26,"tag":309,"props":873,"children":874},{},[875],{"type":32,"value":15},{"type":32,"value":877}," (short for\n",{"type":26,"tag":838,"props":879,"children":880},{},[881],{"type":32,"value":882},"Development Operations",{"type":32,"value":884},", representing the close integration between development and IT operations) plays a key role.\nEspecially with web applications on ",{"type":26,"tag":309,"props":886,"children":887},{},[888],{"type":32,"value":889},"Linux servers",{"type":32,"value":891}," with complex ",{"type":26,"tag":309,"props":893,"children":894},{},[895],{"type":32,"value":896},"network infrastructures",{"type":32,"value":898},", it often only becomes\nclear on the live system how stable and efficient an application is running. In this article, we take a look at some\npopular theories surrounding DevOps in the web environment and examine their validity. In particular, we will focus on\naspects that are relevant to mid-market customers and partners of a software agency.",{"type":26,"tag":35,"props":900,"children":901},{},[902,904,909,911,916,918,923,925,934,936,945,947,955,957,962],{"type":32,"value":903},"We will shed light on why development environments reach their limits, why genuine load tests and ",{"type":26,"tag":838,"props":905,"children":906},{},[907],{"type":32,"value":908},"Edge Cases",{"type":32,"value":910}," are\ndifficult to simulate, and why work begins properly only after the launch (namely under ",{"type":26,"tag":838,"props":912,"children":913},{},[914],{"type":32,"value":915},"monitoring",{"type":32,"value":917}," and ",{"type":26,"tag":838,"props":919,"children":920},{},[921],{"type":32,"value":922},"continuous\nimprovement",{"type":32,"value":924},"). We will also explore the tools that are indispensable in our daily work, from\n",{"type":26,"tag":41,"props":926,"children":928},{"href":927},"https://sentry.io/",[929],{"type":26,"tag":309,"props":930,"children":931},{},[932],{"type":32,"value":933},"Sentry",{"type":32,"value":935},", ",{"type":26,"tag":41,"props":937,"children":939},{"href":938},"https://grafana.com/",[940],{"type":26,"tag":309,"props":941,"children":942},{},[943],{"type":32,"value":944},"Grafana",{"type":32,"value":946},", to\n",{"type":26,"tag":41,"props":948,"children":950},{"href":949},"https://www.zabbix.com/",[951],{"type":26,"tag":309,"props":952,"children":953},{},[954],{"type":32,"value":166},{"type":32,"value":956},", and how ",{"type":26,"tag":309,"props":958,"children":959},{},[960],{"type":32,"value":961},"CI/CD pipelines",{"type":32,"value":963}," help even less experienced developers to deploy\nsafely.",{"type":26,"tag":274,"props":965,"children":967},{"className":966},[831],[968],{"type":26,"tag":35,"props":969,"children":970},{},[971],{"type":26,"tag":838,"props":972,"children":973},{},[974],{"type":32,"value":975},"Reading duration: approx. 20 minutes",{"type":26,"tag":27,"props":977,"children":979},{"id":978},"development-environment-vs-reality-limited-performance-and-unknown-edge-cases",[980],{"type":32,"value":981},"Development environment vs. reality: Limited performance and unknown edge cases",{"type":26,"tag":35,"props":983,"children":984},{},[985,990],{"type":26,"tag":309,"props":986,"children":987},{},[988],{"type":32,"value":989},"Thesis:",{"type":32,"value":991}," Software projects and web applications are built in development environments that are limited in performance\nand test data.",{"type":26,"tag":35,"props":993,"children":994},{},[995,997,1002,1004,1009,1011,1016,1018,1023,1025,1031],{"type":32,"value":996},"During the development phase, a web application often runs on a laptop, a desktop PC, or in an isolated\ntest environment of the developers. This ",{"type":26,"tag":309,"props":998,"children":999},{},[1000],{"type":32,"value":1001},"Dev environment",{"type":32,"value":1003}," is typically ",{"type":26,"tag":309,"props":1005,"children":1006},{},[1007],{"type":32,"value":1008},"less powerful",{"type":32,"value":1010}," than the later\nproduction servers and contains only a fraction of real data. This is normal at first - nobody has a complete\ncopy of the production database on their laptop, and local quick work is also a goal. However,\nthis discrepancy often leads to some problems not becoming visible in the dev environment at all. Also, with\nperformance issues, there's a tendency to quickly assume that the productive system, with its superior performance, will\nnot struggle as much. A ",{"type":26,"tag":309,"props":1012,"children":1013},{},[1014],{"type":32,"value":1015},"staging",{"type":32,"value":1017}," environment can try to mimic the production environment\nbut it has its ",{"type":26,"tag":309,"props":1019,"children":1020},{},[1021],{"type":32,"value":1022},"limits",{"type":32,"value":1024},": Production environments have nuances that are difficult to simulate in staging - such as real\nuser behavior, large amounts of data, or complex system interactions\n",{"type":26,"tag":41,"props":1026,"children":1028},{"href":1027},"https://www.browserstack.com/guide/testing-in-production#:~:text=1.%20Real,only%20surface%20under%20specific%20conditions",[1029],{"type":32,"value":1030},"browserstack.com",{"type":32,"value":1032},"\n. In other words: Everything runs \"smoothly\" in the test environment, but reality introduces completely different\nfactors.",{"type":26,"tag":35,"props":1034,"children":1035},{},[1036,1040],{"type":26,"tag":309,"props":1037,"children":1038},{},[1039],{"type":32,"value":989},{"type":32,"value":1041}," Developers and clients often lack a complete overview of realistic use cases, edge cases, and peak loads.",{"type":26,"tag":35,"props":1043,"children":1044},{},[1045,1047,1052,1054,1059,1061,1065,1067,1072],{"type":32,"value":1046},"Development teams and even clients know the ",{"type":26,"tag":838,"props":1048,"children":1049},{},[1050],{"type":32,"value":1051},"major use cases",{"type":32,"value":1053}," of their software, but ",{"type":26,"tag":309,"props":1055,"children":1056},{},[1057],{"type":32,"value":1058},"real users",{"type":32,"value":1060},"\noften push applications to their limits. Suddenly they use features in combinations that nobody had thought of,\nor input unexpected data. Such ",{"type":26,"tag":309,"props":1062,"children":1063},{},[1064],{"type":32,"value":908},{"type":32,"value":1066}," (special or boundary cases) often remain undetected in the specification.\nOnly in an actual operation do errors occur, which no one had foreseen before. One reason for this is\nthat some bugs only appear under specific conditions that are not anticipated in pre-production tests.\nFor example, a user profile with an ",{"type":26,"tag":838,"props":1068,"children":1069},{},[1070],{"type":32,"value":1071},"emoji",{"type":32,"value":1073}," in the name might trigger an error somewhere in the process –\nsomething that did not appear in the test dataset. Or a client uses the web app on an older browser and faces\ndisplay issues. Cases like these often only show up when the application is being used \"in the wild\".",{"type":26,"tag":35,"props":1075,"children":1076},{},[1077,1079,1084,1086,1091,1093,1098,1100,1105,1107,1112],{"type":32,"value":1078},"In addition, clients might be familiar with their business processes, but ",{"type":26,"tag":309,"props":1080,"children":1081},{},[1082],{"type":32,"value":1083},"peak loads",{"type":32,"value":1085}," due to marketing actions or\ncompletely atypical\nusage times (e.g., at 3 a.m. on weekends) are easily underestimated. The ",{"type":26,"tag":309,"props":1087,"children":1088},{},[1089],{"type":32,"value":1090},"critical view",{"type":32,"value":1092}," here:\nModern approaches aim to close this gap by advocating that development and production environments should be as\nsimilar as possible (",{"type":26,"tag":838,"props":1094,"children":1095},{},[1096],{"type":32,"value":1097},"dev/prod parity",{"type":32,"value":1099},") in order to minimize later surprises.\n",{"type":26,"tag":309,"props":1101,"children":1102},{},[1103],{"type":32,"value":1104},"Containerization",{"type":32,"value":1106}," (e.g. with Docker) allows to locally create an environment that at least in terms of\ndependencies and requirements of the software factors comes very close to the production environment. However, it\nremains unrealistic to anticipate ",{"type":26,"tag":309,"props":1108,"children":1109},{},[1110],{"type":32,"value":1111},"all",{"type":32,"value":1113}," real conditions.",{"type":26,"tag":35,"props":1115,"children":1116},{},[1117,1121],{"type":26,"tag":309,"props":1118,"children":1119},{},[1120],{"type":32,"value":989},{"type":32,"value":1122}," Behavior under prolonged load, external crawlers, penetration tests, or spam-bots are difficult to simulate.",{"type":26,"tag":35,"props":1124,"children":1125},{},[1126,1128,1133,1135,1140,1142,1147,1149,1154],{"type":32,"value":1127},"Performance tests are good practice, but ",{"type":26,"tag":309,"props":1129,"children":1130},{},[1131],{"type":32,"value":1132},"constant load 24/7",{"type":32,"value":1134}," over weeks cannot be fully replicated “in lab”.\nMost companies conduct stress tests before a launch – yet these often only last a few hours or days. How the application\nbehaves over months (memory leaks? Database grows unexpectedly? Logs fill up the hard disk?) remains open. Also,\n",{"type":26,"tag":309,"props":1136,"children":1137},{},[1138],{"type":32,"value":1139},"malicious attacks",{"type":32,"value":1141}," are a topic. External ",{"type":26,"tag":309,"props":1143,"children":1144},{},[1145],{"type":32,"value":1146},"crawlers",{"type":32,"value":1148}," (e.g. by Google, Bing, or others) might massively call up pages\nor ",{"type":26,"tag":309,"props":1150,"children":1151},{},[1152],{"type":32,"value":1153},"spam bots",{"type":32,"value":1155}," cause atypical entries and calls. A constant barrage by a penetration testing tool or even a real\nattack simulation (DDoS) is only somewhat feasible, without possibly endangering the real systems or rendering them\nunusable for daily operations.",{"type":26,"tag":35,"props":1157,"children":1158},{},[1159,1161,1166,1168,1173],{"type":32,"value":1160},"The developer and DevOps community are consistent on this: it is ",{"type":26,"tag":309,"props":1162,"children":1163},{},[1164],{"type":32,"value":1165},"incredibly difficult to truly simulate the production\nload",{"type":32,"value":1167},". Even with test environments that resemble the prod environment, unforeseen effects can occur. An interesting\napproach is therefore almost counterintuitive: sometimes, purposefully ",{"type":26,"tag":309,"props":1169,"children":1170},{},[1171],{"type":32,"value":1172},"undersized test environments are used",{"type":32,"value":1174}," to\nuncover weaknesses. In the mentioned report, a small test database led to a growing log filling up the disk faster – a\nproblem that would have only been noticed much later in a larger environment.",{"type":26,"tag":35,"props":1176,"children":1177},{},[1178,1179,1184,1186,1191,1193,1198,1200,1208,1210,1216],{"type":32,"value":551},{"type":26,"tag":309,"props":1180,"children":1181},{},[1182],{"type":32,"value":1183},"overriding opinion",{"type":32,"value":1185}," in the tech community, however, is that ",{"type":26,"tag":309,"props":1187,"children":1188},{},[1189],{"type":32,"value":1190},"nothing measures up to real production tests",{"type":32,"value":1192},".\nBig players like Netflix even propagate ",{"type":26,"tag":838,"props":1194,"children":1195},{},[1196],{"type":32,"value":1197},"chaos engineering",{"type":32,"value":1199},", where disruptions are specifically generated in the running\nproduction to test the system robustness. An expert sums it up like this: “To test effectively, the system must be\nrunning in production. Because only ",{"type":26,"tag":838,"props":1201,"children":1202},{},[1203],{"type":26,"tag":309,"props":1204,"children":1205},{},[1206],{"type":32,"value":1207},"in production",{"type":32,"value":1209}," can one work with factors such as state data, real inputs, and\nthe behavior of external systems“\n",{"type":26,"tag":41,"props":1211,"children":1213},{"href":1212},"https://www.techtarget.com/searchsoftwarequality/tip/9-techniques-for-fixing-bugs-in-production#:~:text=want%20it%20to%2C%20and%20code,and%20how%20external%20systems%20behave",[1214],{"type":32,"value":1215},"techtarget.com",{"type":32,"value":1217},"\n. This means, we will only see some errors once we go live. Then it's important to be able to react quickly –\nand this is exactly where DevOps comes in.",{"type":26,"tag":27,"props":1219,"children":1221},{"id":1220},"after-the-launch-is-before-the-launch-analysis-and-optimization-during-operation",[1222],{"type":32,"value":1223},"After the launch is before the launch: Analysis and optimization during operation",{"type":26,"tag":35,"props":1225,"children":1226},{},[1227,1231],{"type":26,"tag":309,"props":1228,"children":1229},{},[1230],{"type":32,"value":989},{"type":32,"value":1232}," Further analysis and optimization after the launch is essential.",{"type":26,"tag":35,"props":1234,"children":1235},{},[1236,1238,1243,1245,1250,1252,1257,1263],{"type":32,"value":1237},"In the past, a software project was considered finished after the go-live - today we know that ",{"type":26,"tag":309,"props":1239,"children":1240},{},[1241],{"type":32,"value":1242},"Continuous Improvement",{"type":32,"value":1244},"\nis a critical part of successful software. It's precisely ",{"type":26,"tag":309,"props":1246,"children":1247},{},[1248],{"type":32,"value":1249},"after the launch",{"type":32,"value":1251}," that the phase begins in which real use\ndata is evaluated, bottlenecks are identified, and optimizations are made. As one expert article emphasizes: ",{"type":26,"tag":838,"props":1253,"children":1254},{},[1255],{"type":32,"value":1256},"\"Even with\nrigorous pre-launch testing, actual users can uncover performance problems in practice that were not obvious during\ndevelopment. Post-launch monitoring helps identify these problems before they affect a large number of users.\"",{"type":26,"tag":41,"props":1258,"children":1260},{"href":1259},"https://www.topdevelopers.co/blog/post-launch-support-in-software-development/#:~:text=Even%20with%20rigorous%20pre,a%20large%20number%20of%20users",[1261],{"type":32,"value":1262},"topdevelopers.co",{"type":32,"value":1264},"\n. In other words: A launch without subsequent monitoring is like a maiden voyage without someone at the helm.\nIn practice, especially small and medium-sized companies often underestimate this effort.",{"type":26,"tag":35,"props":1266,"children":1267},{},[1268,1273,1275,1280,1282,1287,1289,1294,1296,1301,1303,1308],{"type":26,"tag":309,"props":1269,"children":1270},{},[1271],{"type":32,"value":1272},"Critical Perspective:",{"type":32,"value":1274}," Some people think good software would run “out of the box” - but based on our experience, this\nis extremely rarely the case. It takes time and iterative improvements to ",{"type":26,"tag":309,"props":1276,"children":1277},{},[1278],{"type":32,"value":1279},"stabilize and speed up",{"type":32,"value":1281}," a (web)\napplication. Studies show that ",{"type":26,"tag":838,"props":1283,"children":1284},{},[1285],{"type":32,"value":1286},"continuous maintenance",{"type":32,"value":1288}," can significantly increase ",{"type":26,"tag":309,"props":1290,"children":1291},{},[1292],{"type":32,"value":1293},"user satisfaction and retention",{"type":32,"value":1295},".\nThis includes regular ",{"type":26,"tag":309,"props":1297,"children":1298},{},[1299],{"type":32,"value":1300},"bug fixes",{"type":32,"value":1302},", performance tuning (e.g., adjusting caching strategies, optimizing database\nindexes), and ",{"type":26,"tag":309,"props":1304,"children":1305},{},[1306],{"type":32,"value":1307},"security patches",{"type":32,"value":1309},". Security vulnerabilities that only emerge gradually must be immediately sealed off\nto prevent damage.",{"type":26,"tag":35,"props":1311,"children":1312},{},[1313,1315,1320,1322,1327,1329,1334],{"type":32,"value":1314},"Another aspect is the ",{"type":26,"tag":309,"props":1316,"children":1317},{},[1318],{"type":32,"value":1319},"feedback loop",{"type":32,"value":1321},": Through real user feedback, you learn which features are well-received and\nwhere usability problems exist, if any. Ideally, this feedback flows directly into the backlog of the development team.\nA culture of ",{"type":26,"tag":838,"props":1323,"children":1324},{},[1325],{"type":32,"value":1326},"continuous deployment",{"type":32,"value":1328}," ensures that improvements reach customers promptly and are not postponed until the\nnext major “release”. Modern DevOps teams consider their software as a living product: ",{"type":26,"tag":838,"props":1330,"children":1331},{},[1332],{"type":32,"value":1333},"\"Software does not end with the\nlaunch - it should be seen as a living product. Post-launch support enables continuous improvement based on user\nfeedback and performance data.\"",{"type":32,"value":331},{"type":26,"tag":35,"props":1336,"children":1337},{},[1338,1340],{"type":32,"value":1339},"Current practice in successful companies clearly shows: after the launch is before the launch. ",{"type":26,"tag":309,"props":1341,"children":1342},{},[1343],{"type":32,"value":1344},"Stagnation is dangerous",{"type":26,"tag":1346,"props":1347,"children":1348},"ul",{},[1349],{"type":26,"tag":1350,"props":1351,"children":1352},"li",{},[1353,1355,1360],{"type":32,"value":1354},"anyone who does not invest in ",{"type":26,"tag":309,"props":1356,"children":1357},{},[1358],{"type":32,"value":1359},"monitoring, troubleshooting, and optimization",{"type":32,"value":1361}," after the go-live risks failures,\ndissatisfied users, and outdated software. For medium-sized companies, this specifically means allocating sufficient\nresources for the operational phase or having a competent partner who takes over the monitoring and maintenance.",{"type":26,"tag":27,"props":1363,"children":1365},{"id":1364},"monitoring-and-logging-observation-is-essential",[1366],{"type":32,"value":1367},"Monitoring and Logging: Observation is essential",{"type":26,"tag":35,"props":1369,"children":1370},{},[1371,1375],{"type":26,"tag":309,"props":1372,"children":1373},{},[1374],{"type":32,"value":989},{"type":32,"value":1376}," Monitoring tools like Sentry or Grafana are essential for logging and error analysis.",{"type":26,"tag":35,"props":1378,"children":1379},{},[1380,1382,1387,1389,1396,1397,1404],{"type":32,"value":1381},"To quickly identify problems in operation, ",{"type":26,"tag":309,"props":1383,"children":1384},{},[1385],{"type":32,"value":1386},"monitoring and logging tools",{"type":32,"value":1388}," are absolutely crucial. Two prominent\nexamples are ",{"type":26,"tag":41,"props":1390,"children":1391},{"href":927},[1392],{"type":26,"tag":309,"props":1393,"children":1394},{},[1395],{"type":32,"value":933},{"type":32,"value":917},{"type":26,"tag":41,"props":1398,"children":1399},{"href":938},[1400],{"type":26,"tag":309,"props":1401,"children":1402},{},[1403],{"type":32,"value":944},{"type":32,"value":1405}," (often in combination with\ntime-series databases like Prometheus or log databases like ElasticSearch/Loki).",{"type":26,"tag":1346,"props":1407,"children":1408},{},[1409,1461],{"type":26,"tag":1350,"props":1410,"children":1411},{},[1412,1419,1421,1426,1428,1433,1435,1445,1447,1452,1454,1459],{"type":26,"tag":41,"props":1413,"children":1414},{"href":927},[1415],{"type":26,"tag":309,"props":1416,"children":1417},{},[1418],{"type":32,"value":933},{"type":32,"value":1420}," is a specialized tool for ",{"type":26,"tag":309,"props":1422,"children":1423},{},[1424],{"type":32,"value":1425},"error tracking",{"type":32,"value":1427},". It captures errors and exceptions in\nthe application and collects them centrally. Why is this important? In production, a developer cannot just hang out\nwith the debugger on the code. Sentry closes this gap: It delivers detailed error reports (with stack trace, user\ninformation, context variables, etc.) as soon as any exception occurs in the code. In the dev community, Sentry is now\nconsidered an ",{"type":26,"tag":309,"props":1429,"children":1430},{},[1431],{"type":32,"value":1432},"industrial standard",{"type":32,"value":1434}," when it comes to crash reporting\n",{"type":26,"tag":41,"props":1436,"children":1438},{"href":1437},"https://medium.com/@AndrzejSala/efficient-error-tracking-with-sentry-e975c186947c#:~:text=Sentry%20is%20a%20crash,an%20industry%20standard%20by%20TechRadar",[1439,1441],{"type":32,"value":1440},"medium.com",{"type":26,"tag":1442,"props":1443,"children":1444},"br",{},[],{"type":32,"value":1446},".\nEven less experienced developers find errors faster with Sentry because the tool eliminates much of the manual\ndetective work. Without a tool like Sentry, many errors in a complex web application would not be noticed until users\ncomplain. With Sentry, however, the team often finds out ",{"type":26,"tag":309,"props":1448,"children":1449},{},[1450],{"type":32,"value":1451},"immediately",{"type":32,"value":1453}," when an error happens – and can proactively\nrespond, ",{"type":26,"tag":309,"props":1455,"children":1456},{},[1457],{"type":32,"value":1458},"before",{"type":32,"value":1460}," all users are affected.",{"type":26,"tag":1350,"props":1462,"children":1463},{},[1464,1471,1473,1478,1480,1485,1487,1492,1494,1499,1501,1506,1508,1513,1515,1520,1522,1527],{"type":26,"tag":41,"props":1465,"children":1466},{"href":938},[1467],{"type":26,"tag":309,"props":1468,"children":1469},{},[1470],{"type":32,"value":944},{"type":32,"value":1472},", on the other hand, addresses ",{"type":26,"tag":309,"props":1474,"children":1475},{},[1476],{"type":32,"value":1477},"performance monitoring and visualization",{"type":32,"value":1479}," of\nsystem metrics. Grafana\nitself is actually a dashboard tool that can integrate various data sources – from server CPU load\nto database performance to application-specific KPIs. In combination with e.g. ",{"type":26,"tag":309,"props":1481,"children":1482},{},[1483],{"type":32,"value":1484},"Prometheus",{"type":32,"value":1486}," (for\nmetric collection) or ",{"type":26,"tag":309,"props":1488,"children":1489},{},[1490],{"type":32,"value":1491},"Loki",{"type":32,"value":1493}," (for log collection), a powerful ",{"type":26,"tag":309,"props":1495,"children":1496},{},[1497],{"type":32,"value":1498},"monitoring cockpit",{"type":32,"value":1500}," is created. You want to be able\nto see ",{"type":26,"tag":838,"props":1502,"children":1503},{},[1504],{"type":32,"value":1505},"at a glance",{"type":32,"value":1507}," whether all systems are green, where potential bottlenecks may be, or if unusual spikes occur.\nSpecifically, this means: Grafana & Co. help to recognize ",{"type":26,"tag":309,"props":1509,"children":1510},{},[1511],{"type":32,"value":1512},"trends",{"type":32,"value":1514}," (e.g., steadily increasing memory load), track\n",{"type":26,"tag":309,"props":1516,"children":1517},{},[1518],{"type":32,"value":1519},"anomalies",{"type":32,"value":1521}," (e.g., sudden traffic increase at midnight), and in the event of an error, quickly identify the ",{"type":26,"tag":309,"props":1523,"children":1524},{},[1525],{"type":32,"value":1526},"cause",{"type":32,"value":331},{"type":26,"tag":1529,"props":1530,"children":1531},"icons-dev-ops",{},[],{"type":26,"tag":35,"props":1533,"children":1534},{},[1535,1539,1541,1546,1548,1553,1555,1560,1562,1567,1569,1574],{"type":26,"tag":309,"props":1536,"children":1537},{},[1538],{"type":32,"value":1272},{"type":32,"value":1540}," Does every small web application need such an array of tools? Some smaller companies initially\ntry to get by without dedicated monitoring, relying on simple logs or manual checking. However, our personal experience\nshows: ",{"type":26,"tag":309,"props":1542,"children":1543},{},[1544],{"type":32,"value":1545},"As soon as the first major problem arises, it becomes clear that monitoring is not a \"nice-to-have\", but a real\nadded value",{"type":32,"value":1547},". Without these tools, you can easily be left in the dark for a long time, sifting through log files.\nHowever, it's crucial to properly channel and interpret the ",{"type":26,"tag":309,"props":1549,"children":1550},{},[1551],{"type":32,"value":1552},"flood of data",{"type":32,"value":1554},". Setting up monitoring correctly takes\ntime initially (and requires some expertise), but it pays off many times over with the first incident. Well-configured\nmonitoring also avoids ",{"type":26,"tag":838,"props":1556,"children":1557},{},[1558],{"type":32,"value":1559},"alert fatigue",{"type":32,"value":1561}," – too many false alarms. Here, ",{"type":26,"tag":309,"props":1563,"children":1564},{},[1565],{"type":32,"value":1566},"quality over quantity",{"type":32,"value":1568}," is key. Better a few,\nbut meaningful metrics and alerts. We strongly advise all our customers: ",{"type":26,"tag":838,"props":1570,"children":1571},{},[1572],{"type":32,"value":1573},"the investment in monitoring and logging tools\nis essential",{"type":32,"value":1575}," in order to remain capable of action in the event of an error!",{"type":26,"tag":27,"props":1577,"children":1579},{"id":1578},"automatic-alerts-zabbix-and-co-as-the-guardians-of-the-systems",[1580],{"type":32,"value":1581},"Automatic Alerts: Zabbix and Co. as the Guardians of the Systems",{"type":26,"tag":35,"props":1583,"children":1584},{},[1585,1589],{"type":26,"tag":309,"props":1586,"children":1587},{},[1588],{"type":32,"value":989},{"type":32,"value":1590}," Monitoring tools like Zabbix are necessary for alerts during critical system conditions.",{"type":26,"tag":35,"props":1592,"children":1593},{},[1594,1596,1601,1603,1607,1608,1613,1614,1619,1621,1628,1630,1635,1636,1641],{"type":32,"value":1595},"In addition to just observing metrics, of course, we want to be ",{"type":26,"tag":309,"props":1597,"children":1598},{},[1599],{"type":32,"value":1600},"automatically alerted",{"type":32,"value":1602}," when something goes awry. This\nis where system monitoring tools like ",{"type":26,"tag":309,"props":1604,"children":1605},{},[1606],{"type":32,"value":166},{"type":32,"value":935},{"type":26,"tag":309,"props":1609,"children":1610},{},[1611],{"type":32,"value":1612},"Nagios",{"type":32,"value":935},{"type":26,"tag":309,"props":1615,"children":1616},{},[1617],{"type":32,"value":1618},"Icinga",{"type":32,"value":1620},", etc., come into play. Let's stick with\n",{"type":26,"tag":41,"props":1622,"children":1623},{"href":949},[1624],{"type":26,"tag":309,"props":1625,"children":1626},{},[1627],{"type":32,"value":166},{"type":32,"value":1629}," as an example: Zabbix is an open-source monitoring system that offers predefined\n",{"type":26,"tag":309,"props":1631,"children":1632},{},[1633],{"type":32,"value":1634},"triggers",{"type":32,"value":917},{"type":26,"tag":309,"props":1637,"children":1638},{},[1639],{"type":32,"value":1640},"notifications",{"type":32,"value":1642},". You can set thresholds - e.g., \"CPU load > 90% over 5 minutes\" or \"less than 10% free\ndisk space\" - and as soon as these are reached, Zabbix sends an alarm (via email, SMS, Slack, etc.).",{"type":26,"tag":35,"props":1644,"children":1645},{},[1646,1648,1652,1654,1659,1661,1665,1667,1672],{"type":32,"value":1647},"Why do we need this, didn't we just praise Grafana & Co.? The difference: ",{"type":26,"tag":309,"props":1649,"children":1650},{},[1651],{"type":32,"value":944},{"type":32,"value":1653}," is great for visualization and\nanalysis, but ",{"type":26,"tag":309,"props":1655,"children":1656},{},[1657],{"type":32,"value":1658},"active alerting",{"type":32,"value":1660}," is often taken over by a dedicated tool like Zabbix (or Grafana is combined with an\nalert manager). ",{"type":26,"tag":309,"props":1662,"children":1663},{},[1664],{"type":32,"value":166},{"type":32,"value":1666}," and similar tools are essentially the ",{"type":26,"tag":309,"props":1668,"children":1669},{},[1670],{"type":32,"value":1671},"night watchmen",{"type":32,"value":1673}," who tirelessly monitor for defined\nconditions.",{"type":26,"tag":35,"props":1675,"children":1676},{},[1677,1679,1684,1690,1692,1696],{"type":32,"value":1678},"The importance of such alerts cannot be overstated. A fitting quote from a Linux Journal article: ",{"type":26,"tag":838,"props":1680,"children":1681},{},[1682],{"type":32,"value":1683},"\"Alerts and triggers\nare the heartbeat of monitoring. Zabbix lets you define specific conditions, upon the occurrence of which notifications\nare sent over various channels, so that you are immediately informed about critical events that could impact system\nperformance\"",{"type":26,"tag":41,"props":1685,"children":1687},{"href":1686},"https://www.linuxjournal.com/content/how-monitor-your-system-zabbix#:~:text=Alerts%20and%20triggers%20are%20the,that%20could%20impact%20system%20performance",[1688],{"type":32,"value":1689},"linuxjournal.com",{"type":32,"value":1691},"\n. Without an alerting system, a problem can go unnoticed for hours - in the worst case, you hear about it first from the\nirritated customer on the phone. With properly configured alerts, however, the team ",{"type":26,"tag":309,"props":1693,"children":1694},{},[1695],{"type":32,"value":1451},{"type":32,"value":1697}," knows, for example,\nif the web server has failed or if the response times are critically high.",{"type":26,"tag":35,"props":1699,"children":1700},{},[1701,1706,1708,1713,1715,1720,1722,1727],{"type":26,"tag":309,"props":1702,"children":1703},{},[1704],{"type":32,"value":1705},"Practical View:",{"type":32,"value":1707}," For medium-sized companies that may not have a 24/7 operating team, good alerting is even more\nimportant. It allows small teams to work efficiently because they can rely on the warning messages, instead of\nconstantly manually checking everything. However, even here, a poorly configured system that is constantly crying \"wolf,\nwolf, ...\" (keyword ",{"type":26,"tag":838,"props":1709,"children":1710},{},[1711],{"type":32,"value":1712},"false positives",{"type":32,"value":1714},"), will quickly be ignored. The trick is to define ",{"type":26,"tag":309,"props":1716,"children":1717},{},[1718],{"type":32,"value":1719},"meaningful threshold values",{"type":32,"value":1721},"\nand send ",{"type":26,"tag":309,"props":1723,"children":1724},{},[1725],{"type":32,"value":1726},"context-rich alerts",{"type":32,"value":1728}," (e.g., directly with an indication of which component is affected, attach logs, etc.).",{"type":26,"tag":35,"props":1730,"children":1731},{},[1732,1739,1741,1746],{"type":26,"tag":41,"props":1733,"children":1734},{"href":949},[1735],{"type":26,"tag":309,"props":1736,"children":1737},{},[1738],{"type":32,"value":166},{"type":32,"value":1740}," has proven itself in many of our projects and is often referred to internally as\nan ",{"type":26,"tag":309,"props":1742,"children":1743},{},[1744],{"type":32,"value":1745},"indispensable tool",{"type":32,"value":331},{"type":26,"tag":27,"props":1748,"children":1750},{"id":1749},"cicd-pipelines-standardized-deployments-also-for-beginners",[1751],{"type":32,"value":1752},"CI/CD Pipelines: Standardized Deployments - Also for Beginners",{"type":26,"tag":35,"props":1754,"children":1755},{},[1756,1760],{"type":26,"tag":309,"props":1757,"children":1758},{},[1759],{"type":32,"value":989},{"type":32,"value":1761}," CI/CD Pipelines enable standardized, safe deployments even for less experienced developers.",{"type":26,"tag":35,"props":1763,"children":1764},{},[1765,1767,1772,1774,1779,1780,1785,1787,1792],{"type":32,"value":1766},"The terms ",{"type":26,"tag":309,"props":1768,"children":1769},{},[1770],{"type":32,"value":1771},"CI/CD",{"type":32,"value":1773}," stand for ",{"type":26,"tag":838,"props":1775,"children":1776},{},[1777],{"type":32,"value":1778},"Continuous Integration",{"type":32,"value":917},{"type":26,"tag":838,"props":1781,"children":1782},{},[1783],{"type":32,"value":1784},"Continuous Delivery/Deployment",{"type":32,"value":1786},". A ",{"type":26,"tag":309,"props":1788,"children":1789},{},[1790],{"type":32,"value":1791},"CI/CD pipeline",{"type":32,"value":1793}," is an\nautomated process chain that builds, tests, and eventually deploys code from commit to rollout. Why is this so\nimportant - and how does it help less experienced developers?",{"type":26,"tag":35,"props":1795,"children":1796},{},[1797,1799,1804,1806,1811],{"type":32,"value":1798},"In traditional development workflows, the ",{"type":26,"tag":309,"props":1800,"children":1801},{},[1802],{"type":32,"value":1803},"deployment",{"type":32,"value":1805}," was often manual work carried out by experienced admins or\nDevOps engineers because many things could go wrong (missing dependencies, incorrect configs, avoiding downtime, etc.).\nHowever, with a well-configured CI/CD pipeline, deployment becomes a ",{"type":26,"tag":309,"props":1807,"children":1808},{},[1809],{"type":32,"value":1810},"standardized, repeatable operation",{"type":32,"value":1812}," - ideally at\nthe push of a button. Even if a developer has never manually set up a Linux server before, he can make his code live\nthrough the functionality of the pipeline because the pipeline takes over the necessary steps for him.",{"type":26,"tag":35,"props":1814,"children":1815},{},[1816,1821,1823,1828,1829,1834,1836,1840,1842,1847],{"type":26,"tag":309,"props":1817,"children":1818},{},[1819],{"type":32,"value":1820},"Safety and quality",{"type":32,"value":1822}," are not neglected - on the contrary. Particularly less experienced developers benefit from the\nfact that the pipeline carries out automated ",{"type":26,"tag":309,"props":1824,"children":1825},{},[1826],{"type":32,"value":1827},"tests",{"type":32,"value":917},{"type":26,"tag":309,"props":1830,"children":1831},{},[1832],{"type":32,"value":1833},"code checks",{"type":32,"value":1835}," ",{"type":26,"tag":838,"props":1837,"children":1838},{},[1839],{"type":32,"value":1458},{"type":32,"value":1841}," the deployment. This way, errors are\nintercepted before they're released to the user base. Additionally, the pipeline ensures that deployments always happen\nin ",{"type":26,"tag":309,"props":1843,"children":1844},{},[1845],{"type":32,"value":1846},"the same way",{"type":32,"value":1848}," - there are no deviations that occur due to human forgetfulness (e.g., \"Oops, loaded the staging\nconfig on Prod\" - such mistakes are eliminated). For SMEs, this means: faster updates with a simultaneously lower error\nrate.",{"type":26,"tag":35,"props":1850,"children":1851},{},[1852,1854,1859,1861,1866],{"type":32,"value":1853},"Of course, setting up a CI/CD pipeline initially requires ",{"type":26,"tag":309,"props":1855,"children":1856},{},[1857],{"type":32,"value":1858},"know-how and effort",{"type":32,"value":1860},". This is where a DevOps specialist\noften comes into play, who sets up such a pipeline (for example, with Jenkins, GitLab CI, GitHub Actions, or Bitbucket\nPipelines). ",{"type":26,"tag":309,"props":1862,"children":1863},{},[1864],{"type":32,"value":1865},"Upon critical examination",{"type":32,"value":1867},", some argue that in a perfect DevOps team, this distinction between developers\nand DevOps would be unnecessary because everyone would be responsible for the process. However, in reality, it is\nespecially beneficial for less experienced developers when a robust CI/CD system exists - it takes the fear of\ndeployment away from them (that applies to me as well as a project manager). A junior developer can click \"Deploy\" in\ngood conscience because they know, when automated tests have been run and the rollout is controlled, there's a minimum\namount of safety that the production system won't be impacted.",{"type":26,"tag":35,"props":1869,"children":1870},{},[1871,1873,1878,1880,1885,1887,1892],{"type":32,"value":1872},"It's important that CI/CD brings not only technical but also ",{"type":26,"tag":309,"props":1874,"children":1875},{},[1876],{"type":32,"value":1877},"cultural changes",{"type":32,"value":1879},". Deployments become smaller but more\nfrequent. This reduces risk and the impact of errors. Teams get used to deployments being ",{"type":26,"tag":838,"props":1881,"children":1882},{},[1883],{"type":32,"value":1884},"routine",{"type":32,"value":1886}," and not \"major\noperation days\". Especially in ",{"type":26,"tag":309,"props":1888,"children":1889},{},[1890],{"type":32,"value":1891},"Agile Development",{"type":32,"value":1893},", CI/CD is virtually the backbone to enable fast iterations.",{"type":26,"tag":35,"props":1895,"children":1896},{},[1897,1899,1904],{"type":32,"value":1898},"In summary: CI/CD pipelines are a game-changer that enables even less experienced developers to deliver ",{"type":26,"tag":309,"props":1900,"children":1901},{},[1902],{"type":32,"value":1903},"at the push of\na button",{"type":32,"value":1905}," – reliably and repeatably.",{"type":26,"tag":27,"props":1907,"children":1909},{"id":1908},"experience-counts-live-data-specific-errors-and-the-role-of-devops-experts",[1910],{"type":32,"value":1911},"Experience Counts: Live Data, Specific Errors, and the Role of DevOps Experts",{"type":26,"tag":35,"props":1913,"children":1914},{},[1915,1919],{"type":26,"tag":309,"props":1916,"children":1917},{},[1918],{"type":32,"value":989},{"type":32,"value":1920}," Certain errors and performance problems only manifest with live data and require experienced DevOps\nspecialists.",{"type":26,"tag":35,"props":1922,"children":1923},{},[1924,1926,1931,1933,1938,1940,1945],{"type":32,"value":1925},"Despite all automation and testing, the ",{"type":26,"tag":309,"props":1927,"children":1928},{},[1929],{"type":32,"value":1930},"experience",{"type":32,"value":1932}," in dealing with production systems is irreplaceable. There are\nerror patterns that only occur with real ",{"type":26,"tag":309,"props":1934,"children":1935},{},[1936],{"type":32,"value":1937},"live data and loads",{"type":32,"value":1939}," - due to complex data constellations or simply scaling\neffects. A query that is lightning-fast with 100 test data sets can suddenly become a bottleneck with 100 million real\ndata sets. Or a ",{"type":26,"tag":309,"props":1941,"children":1942},{},[1943],{"type":32,"value":1944},"memory leak",{"type":32,"value":1946}," in a certain library only becomes apparent after weeks of continuous operation when the\nprocess increasingly occupies memory. Identifying and fixing such problems often requires an experienced eye.",{"type":26,"tag":35,"props":1948,"children":1949},{},[1950,1952,1957,1959,1965,1966,1972,1974,1980,1982,1987,1989,1994,1996,2001],{"type":32,"value":1951},"A DevOps engineer with a lot of operational experience usually has a repertoire of ",{"type":26,"tag":309,"props":1953,"children":1954},{},[1955],{"type":32,"value":1956},"diagnostic techniques",{"type":32,"value":1958},". For\nexample, experienced people know how to debug on Linux with tools like ",{"type":26,"tag":270,"props":1960,"children":1962},{"className":1961},[],[1963],{"type":32,"value":1964},"htop",{"type":32,"value":935},{"type":26,"tag":270,"props":1967,"children":1969},{"className":1968},[],[1970],{"type":32,"value":1971},"iotop",{"type":32,"value":1973},", or ",{"type":26,"tag":270,"props":1975,"children":1977},{"className":1976},[],[1978],{"type":32,"value":1979},"strace",{"type":32,"value":1981},", which less routine\ndevelopers may never have needed. Experienced DevOps also know ",{"type":26,"tag":309,"props":1983,"children":1984},{},[1985],{"type":32,"value":1986},"duration load phenomena",{"type":32,"value":1988}," (keywords: ",{"type":26,"tag":838,"props":1990,"children":1991},{},[1992],{"type":32,"value":1993},"floating-point\nprecision bugs",{"type":32,"value":1995},", memory-induced rounding errors, etc.) from practice. A drastic but real scenario: A memory error occurs\n",{"type":26,"tag":838,"props":1997,"children":1998},{},[1999],{"type":32,"value":2000},"only",{"type":32,"value":2002}," under proper full load and only in combination with certain hardware conditions - here you need experts who may\nhave seen something similar before or know where to start.",{"type":26,"tag":27,"props":2004,"children":2006},{"id":2005},"conclusion",[2007],{"type":32,"value":2008},"Conclusion",{"type":26,"tag":35,"props":2010,"children":2011},{},[2012,2014,2019,2021,2026,2028,2035],{"type":32,"value":2013},"For (web) applications in productive use, ",{"type":26,"tag":309,"props":2015,"children":2016},{},[2017],{"type":32,"value":2018},"DevOps is not a luxury, but a necessity",{"type":32,"value":2020},". Development environments hit\ntheir limits, real users produce surprises, and without continuous monitoring, you're flying blind. Small and\nmedium-sized companies, which perhaps don't have huge IT departments, can benefit enormously from a DevOps approach.\nMore stable systems, quicker response times to problems, and more satisfied customers. However, you must be willing to\ninvest ",{"type":26,"tag":309,"props":2022,"children":2023},{},[2024],{"type":32,"value":2025},"time and resources",{"type":32,"value":2027}," even after the launch to analyze data and implement improvements. Tools like\n",{"type":26,"tag":41,"props":2029,"children":2030},{"href":927},[2031],{"type":26,"tag":309,"props":2032,"children":2033},{},[2034],{"type":32,"value":933},{"type":32,"value":2036},", Grafana, and Zabbix form the backbone of monitoring - they deliver the necessary data and\nsupporting mechanisms. Automation through CI/CD significantly reduces the risk of deployments and allows even less\nexperienced team members to safely implement changes live.",{"type":26,"tag":35,"props":2038,"children":2039},{},[2040,2042,2047],{"type":32,"value":2041},"In the end, it shows: ",{"type":26,"tag":309,"props":2043,"children":2044},{},[2045],{"type":32,"value":2046},"People",{"type":32,"value":2048}," make the difference. Experienced DevOps specialists can solve tricky live problems and\nbuild a bridge between developers and operations.",{"type":26,"tag":35,"props":2050,"children":2051},{},[2052,2057],{"type":26,"tag":309,"props":2053,"children":2054},{},[2055],{"type":32,"value":2056},"Note:",{"type":32,"value":2058}," This article was also generated with the support of AI (model: GPT-4).",{"title":7,"searchDepth":92,"depth":92,"links":2060},[2061,2062,2063,2064,2065,2066,2067,2068],{"id":849,"depth":92,"text":852},{"id":978,"depth":92,"text":981},{"id":1220,"depth":92,"text":1223},{"id":1364,"depth":92,"text":1367},{"id":1578,"depth":92,"text":1581},{"id":1749,"depth":92,"text":1752},{"id":1908,"depth":92,"text":1911},{"id":2005,"depth":92,"text":2008},{"_path":134,"_dir":135,"_draft":6,"_partial":6,"_locale":7,"slug":10,"teams":2070,"primaryTeam":138,"firstName":139,"lastName":140,"prefixTitle":7,"suffixTitle":7,"education":2071,"executiveRole":146,"role":2073,"workingSince":155,"inTheCompanySince":156,"techSkills":2074,"skills":2091,"projects":2098,"contactDetails":2104,"_image":233,"image":234,"_id":235,"_type":236,"title":237,"_source":135,"_file":238,"_stem":239,"_extension":236},[137,138],[2072],[143,144,145],[148,149,138,150,151,152,153,154],[2075,2076,2077,2078,2079,2080,2081,2082,2083,2084,2085,2086,2087,2088,2089,2090],{"name":159,"level":160,"icon":161},{"name":163,"level":160,"icon":164},{"name":166,"level":160},{"name":168,"level":160,"icon":169},{"name":171,"level":160},{"name":173,"level":160,"icon":174},{"name":176,"level":160},{"name":178,"level":160},{"name":180,"level":160},{"name":182,"level":160,"icon":183},{"name":185,"level":186,"icon":187},{"name":189,"level":186,"icon":190},{"name":192,"level":186,"icon":193},{"name":195,"level":186,"icon":196},{"name":198,"level":186,"icon":199},{"name":201,"level":186,"icon":202},[2092,2093,2094,2095,2096,2097],{"name":205,"level":160},{"name":207,"level":160},{"name":209,"level":160},{"name":211,"level":160},{"name":213,"level":160},{"name":215,"level":186},[2099,2100,2101,2102,2103],{"project":218,"position":219},{"project":221,"position":219},{"project":223,"position":219},{"project":225,"position":226},{"project":228,"position":219},{"eMail":230,"phone":231,"visibility":232},{"_path":2106,"_dir":135,"_draft":6,"_partial":6,"_locale":7,"slug":120,"teams":2107,"primaryTeam":2108,"firstName":2109,"lastName":2110,"prefixTitle":2111,"suffixTitle":7,"executiveRole":2112,"education":2113,"role":2120,"workingSince":145,"inTheCompanySince":2117,"techSkills":2125,"skills":2143,"projects":2155,"contactDetails":2159,"certifications":2162,"image":2168,"_id":2169,"_type":236,"title":2170,"_source":135,"_file":2171,"_stem":2172,"_extension":236},"/employees/jens-bornschein",[2108],"appDev","Jens","Bornschein","Dr. Ing.","Projektmanager | Consultant",[2114,2118],[2115,2116,2117],"Doktor-Ingenieur der Informatik","TU Dresden","2020",[2119,2116,145],"Diplom-Medieninformatiker (TU)",[2121,152,2122,2123,2124,154],"projectManager","fullstackDeveloper","UI/UX","accessibility",[2126,2127,2128,2129,2130,2131,2132,2135,2138,2141],{"name":176,"level":160},{"name":189,"level":160,"icon":190},{"name":192,"level":186,"icon":193},{"name":195,"level":186,"icon":196},{"name":201,"level":186,"icon":202},{"name":178,"level":186},{"name":2133,"level":160,"icon":2134},"Adobe Photoshop","/images/adobeps-logo.svg",{"name":2136,"level":160,"icon":2137},"Adobe Illustrator","/images/adobeai-logo.svg",{"name":2139,"level":186,"icon":2140},"Adobe XD","/images/adobexd-logo.svg",{"name":2142,"level":186},"Gitlab",[2144,2146,2147,2148,2150,2152,2153],{"name":2145,"level":160},"projectManagement",{"name":2124,"level":160},{"name":2123,"level":160},{"name":2149,"level":186},"consulting",{"name":2151,"level":186},"scrum",{"name":213,"level":186},{"name":2154,"level":186},"training",[2156,2158],{"project":223,"position":2157},"project manager",{"project":228,"position":2157},{"eMail":2160,"phone":2161,"visibility":232},"jens.bornschein@helmundwalter.de","+49 351 799 035 24",[2163],{"image":2164,"link":2165,"title":2166,"pdf":2167},"/images/certifications/KHZG_Badge.svg","https://www.bundesamtsozialesicherung.de/de/themen/innovationsfonds-und-krankenhausstrukturfonds/krankenhausstrukturfonds/","Berechtigung nach § 21 Absatz 5 Satz 1 KHSFV - Management für KHZG geförderte Vorhaben","/certificates/jb_KHSFV_Zertifikat.pdf","images/employees/Portraits/JensBornschein_MS.webp","employees:employees:5.jens-bornschein.json","Jens Bornschein","employees/5.jens-bornschein.json","employees/5.jens-bornschein",[2174,2190,2203,2215],{"_path":2175,"_dir":2176,"_draft":6,"_partial":2177,"_locale":7,"name":2178,"slug":2176,"text":2179,"hoverText":2180,"image":2181,"customer":2182,"tags":2183,"_id":2185,"_type":2186,"title":2187,"_source":98,"_file":2188,"_stem":2189,"_extension":2186},"/en/portfolio/gridside/_teaser","gridside",true,"Gridside HANS","Reconstruction planning of supra-regional power grids","Helm & Walter IT-Solutions GmbH was commissioned to develop a web application for the reconstruction planning of supra-regional power grids.","/images/portfolio/gridside/hero.png","A large international electronics company",[2184,21],"frontend","common:en:portfolio:890.gridside:_teaser.yaml","yaml","Teaser","en/portfolio/890.gridside/_teaser.yaml","en/portfolio/890.gridside/_teaser",{"_path":2191,"_dir":2192,"_draft":6,"_partial":2177,"_locale":7,"name":2193,"slug":2192,"text":2194,"hoverText":2195,"image":2196,"customer":2197,"tags":2198,"_id":2200,"_type":2186,"title":2187,"_source":98,"_file":2201,"_stem":2202,"_extension":2186},"/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",[2199,20],"shopware","common:en:portfolio:900.bitburger:_teaser.yaml","en/portfolio/900.bitburger/_teaser.yaml","en/portfolio/900.bitburger/_teaser",{"_path":2204,"_dir":2205,"_draft":6,"_partial":2177,"_locale":7,"name":2206,"slug":2205,"text":2207,"hoverText":2208,"image":2209,"customer":2210,"tags":2211,"_id":2212,"_type":2186,"title":2187,"_source":98,"_file":2213,"_stem":2214,"_extension":2186},"/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",[2199,20],"common:en:portfolio:9000.purize:_teaser.yaml","en/portfolio/9000.purize/_teaser.yaml","en/portfolio/9000.purize/_teaser",{"_path":2216,"_dir":2217,"_draft":6,"_partial":2177,"_locale":7,"name":2218,"slug":2217,"text":2219,"hoverText":2220,"image":2221,"customer":2218,"tags":2222,"_id":2223,"_type":2186,"title":2187,"_source":98,"_file":2224,"_stem":2225,"_extension":2186},"/en/portfolio/werner-consulting/_teaser","werner-consulting","Werner Consulting","Custom software for a trustworthy business","Tailor-made software solutions as desktop applications and development of plugins for software frameworks for complex consulting solutions, e-commerce platforms, and inventory management systems.","/images/portfolio/werner_consulting/consulting_portfolio.jpg",[21,20],"common:en:portfolio:9030.werner-consulting:_teaser.yaml","en/portfolio/9030.werner-consulting/_teaser.yaml","en/portfolio/9030.werner-consulting/_teaser",1782284057046]