diff --git a/public/jsons/roadmaps/docker.json b/public/jsons/roadmaps/docker.json index daa562685..7616907d8 100644 --- a/public/jsons/roadmaps/docker.json +++ b/public/jsons/roadmaps/docker.json @@ -1 +1,4420 @@ -{"mockup":{"controls":{"control":[{"ID":"2620","typeID":"Arrow","zOrder":"31","w":"1","h":"501","measuredW":"150","measuredH":"100","x":"1213","y":"766","properties":{"curvature":"0","leftArrow":"false","rightArrow":"false","color":"4273622","p0":{"x":-0.18181818181824383,"y":0},"p1":{"x":0.49995786685927396,"y":0.00035566936975390927},"p2":{"x":-0.18181818181824383,"y":501.00085499312513}}},{"ID":"2625","typeID":"Label","zOrder":"32","measuredW":"104","measuredH":"40","x":"1162","y":"714","properties":{"size":"32","text":"Docker"}},{"ID":"2626","typeID":"Canvas","zOrder":"33","w":"350","h":"141","measuredW":"100","measuredH":"70","x":"1433","y":"636"},{"ID":"2627","typeID":"Label","zOrder":"34","measuredW":"314","measuredH":"25","x":"1447","y":"653","properties":{"size":"17","text":"Find the detailed version of this roadmap"}},{"ID":"2628","typeID":"Label","zOrder":"35","measuredW":"319","measuredH":"25","x":"1447","y":"681","properties":{"size":"17","text":"along with resources and other roadmaps"}},{"ID":"2629","typeID":"__group__","zOrder":"36","measuredW":"320","measuredH":"45","w":"320","h":"45","x":"1448","y":"717","properties":{"controlName":"ext_link:roadmap.sh"},"children":{"controls":{"control":[{"ID":"0","typeID":"Canvas","zOrder":"0","w":"320","h":"45","measuredW":"100","measuredH":"70","x":"0","y":"0","properties":{"borderColor":"4273622","color":"4273622"}},{"ID":"2","typeID":"Label","zOrder":"1","measuredW":"172","measuredH":"28","x":"74","y":"8","properties":{"color":"16777215","size":"20","text":"https://roadmap.sh"}}]}}},{"ID":"2670","typeID":"Arrow","zOrder":"39","w":"1","h":"101","measuredW":"150","measuredH":"100","x":"1213","y":"600","properties":{"curvature":"0","leftArrow":"false","rightArrow":"false","color":"4273622","stroke":"dotted","p0":{"x":-0.18181818181824383,"y":0.060606060606005485},"p1":{"x":0.4999578668592744,"y":0.0003556693697539094},"p2":{"x":-0.18181818181824383,"y":101.15151515151513}}},{"ID":"2778","typeID":"Label","zOrder":"38","measuredW":"155","measuredH":"25","x":"721","y":"1101","properties":{"size":"17","text":"Linux Fundamentals"}},{"ID":"2785","typeID":"Label","zOrder":"40","measuredW":"108","measuredH":"26","x":"746","y":"1294","properties":{"text":"Prerequisites","size":"18"}},{"ID":"2786","typeID":"TextArea","zOrder":"41","w":"300","h":"44","measuredW":"200","measuredH":"140","x":"650","y":"907","properties":{"color":"16770457"}},{"ID":"2787","typeID":"Label","zOrder":"42","measuredW":"149","measuredH":"25","x":"724","y":"916","properties":{"size":"17","text":"Package Managers"}},{"ID":"2788","typeID":"TextArea","zOrder":"43","w":"300","h":"44","measuredW":"200","measuredH":"140","x":"650","y":"954","properties":{"color":"16770457"}},{"ID":"2789","typeID":"Label","zOrder":"44","measuredW":"216","measuredH":"25","x":"691","y":"963","properties":{"size":"17","text":"Users / Groups Permissions"}},{"ID":"2790","typeID":"TextArea","zOrder":"45","w":"300","h":"44","measuredW":"200","measuredH":"140","x":"650","y":"1001","properties":{"color":"16770457"}},{"ID":"2791","typeID":"Label","zOrder":"46","measuredW":"127","measuredH":"25","x":"735","y":"1010","properties":{"size":"17","text":"Shell commands"}},{"ID":"2792","typeID":"TextArea","zOrder":"47","w":"300","h":"44","measuredW":"200","measuredH":"140","x":"650","y":"1048","properties":{"color":"16770457"}},{"ID":"2793","typeID":"Label","zOrder":"48","measuredW":"108","measuredH":"25","x":"745","y":"1057","properties":{"size":"17","text":"Shell scripting"}},{"ID":"2797","typeID":"Label","zOrder":"49","measuredW":"142","measuredH":"25","x":"728","y":"1240","properties":{"size":"17","text":"Web Development"}},{"ID":"2798","typeID":"TextArea","zOrder":"50","w":"300","h":"44","measuredW":"200","measuredH":"140","x":"650","y":"1141","properties":{"color":"16770457"}},{"ID":"2799","typeID":"Label","zOrder":"51","measuredW":"175","measuredH":"25","x":"711","y":"1150","properties":{"size":"17","text":"Programming Lanuage"}},{"ID":"2800","typeID":"TextArea","zOrder":"52","w":"300","h":"44","measuredW":"200","measuredH":"140","x":"650","y":"1188","properties":{"color":"16770457"}},{"ID":"2801","typeID":"Label","zOrder":"53","measuredW":"183","measuredH":"25","x":"707","y":"1197","properties":{"size":"17","text":"Application Architecture"}},{"ID":"2822","typeID":"Arrow","zOrder":"27","w":"159","h":"23","measuredW":"150","measuredH":"100","x":"1336","y":"906","properties":{"curvature":"0","leftArrow":"false","rightArrow":"false","color":"4273622","stroke":"dotted","p0":{"x":0.4646359097735058,"y":23.353294775624022},"p1":{"x":0.5172121703355936,"y":-0.04134567000631401},"p2":{"x":159.51104906422256,"y":0.2084809210585945}}},{"ID":"2823","typeID":"Arrow","zOrder":"28","w":"157","h":"64","measuredW":"150","measuredH":"100","x":"1336","y":"855","properties":{"curvature":"0","leftArrow":"false","rightArrow":"false","color":"4273622","stroke":"dotted","p0":{"x":0.4646359097735058,"y":63.67107299659381},"p1":{"x":0.4603346517294317,"y":-0.10421022711848146},"p2":{"x":157.13722200221582,"y":0.1711990879144878}}},{"ID":"2824","typeID":"Arrow","zOrder":"29","w":"169","h":"24","measuredW":"150","measuredH":"100","x":"1328","y":"940","properties":{"curvature":"0","leftArrow":"false","rightArrow":"false","color":"4273622","stroke":"dotted","p0":{"x":0.15624119275003068,"y":0.628973320155751},"p1":{"x":0.5012965221560048,"y":0.04743407560804315},"p2":{"x":168.69796259522582,"y":24.367243940222806}}},{"ID":"2825","typeID":"Arrow","zOrder":"30","w":"152","h":"72","measuredW":"150","measuredH":"100","x":"1340","y":"946","properties":{"curvature":"0","leftArrow":"false","rightArrow":"false","color":"4273622","stroke":"dotted","p0":{"x":0.025376502783501564,"y":-0.0299157903291416},"p1":{"x":0.5934120757823323,"y":0.11641742644399297},"p2":{"x":151.95030847121234,"y":71.77835283537365}}},{"ID":"2826","typeID":"Canvas","zOrder":"59","w":"327","h":"126","measuredW":"100","measuredH":"70","x":"636","y":"620"},{"ID":"2827","typeID":"Label","zOrder":"60","measuredW":"268","measuredH":"25","x":"659","y":"641","properties":{"size":"17","text":"Roadmap was made in partnership"}},{"ID":"2834","typeID":"Canvas","zOrder":"123","w":"327","h":"129","measuredW":"100","measuredH":"70","x":"636","y":"736"},{"ID":"2836","typeID":"__group__","zOrder":"124","measuredW":"202","measuredH":"26","w":"202","h":"26","x":"659","y":"758","properties":{"controlName":"ext_link:roadmap.sh/kubernetes"},"children":{"controls":{"control":[{"ID":"0","typeID":"Label","zOrder":"0","measuredW":"169","measuredH":"25","x":"33","y":"0","properties":{"size":"17","text":"Kubernetes Roadmap"}},{"ID":"1","typeID":"__group__","zOrder":"1","measuredW":"24","measuredH":"24","w":"24","h":"24","x":"0","y":"2","children":{"controls":{"control":[{"ID":"0","typeID":"Icon","zOrder":"0","measuredW":"24","measuredH":"24","x":"0","y":"0","properties":{"color":"16777215","icon":{"ID":"circle","size":"small"}}},{"ID":"1","typeID":"Icon","zOrder":"1","measuredW":"24","measuredH":"24","x":"0","y":"0","properties":{"color":"10066329","icon":{"ID":"check-circle","size":"small"}}}]}}}]}}},{"ID":"2837","typeID":"__group__","zOrder":"125","measuredW":"174","measuredH":"26","w":"174","h":"26","x":"659","y":"788","properties":{"controlName":"ext_link:roadmap.sh/best-practices"},"children":{"controls":{"control":[{"ID":"0","typeID":"Label","zOrder":"0","measuredW":"141","measuredH":"25","x":"33","y":"0","properties":{"size":"17","text":"DevOps Roadmap"}},{"ID":"1","typeID":"__group__","zOrder":"1","measuredW":"24","measuredH":"24","w":"24","h":"24","x":"0","y":"2","children":{"controls":{"control":[{"ID":"0","typeID":"Icon","zOrder":"0","measuredW":"24","measuredH":"24","x":"0","y":"0","properties":{"color":"16777215","icon":{"ID":"circle","size":"small"}}},{"ID":"1","typeID":"Icon","zOrder":"1","measuredW":"24","measuredH":"24","x":"0","y":"0","properties":{"color":"10066329","icon":{"ID":"check-circle","size":"small"}}}]}}}]}}},{"ID":"2838","typeID":"Label","zOrder":"61","measuredW":"31","measuredH":"25","x":"659","y":"669","properties":{"size":"17","text":"with"}},{"ID":"2840","typeID":"Label","zOrder":"63","measuredW":"144","measuredH":"25","x":"763","y":"669","properties":{"size":"17","text":". Checkout his free"}},{"ID":"2841","typeID":"__group__","zOrder":"126","measuredW":"180","measuredH":"26","w":"180","h":"26","x":"659","y":"819","properties":{"controlName":"ext_link:roadmap.sh/backend"},"children":{"controls":{"control":[{"ID":"0","typeID":"Label","zOrder":"0","measuredW":"147","measuredH":"25","x":"33","y":"0","properties":{"size":"17","text":"Backend Roadmap"}},{"ID":"1","typeID":"__group__","zOrder":"1","measuredW":"24","measuredH":"24","w":"24","h":"24","x":"0","y":"2","children":{"controls":{"control":[{"ID":"0","typeID":"Icon","zOrder":"0","measuredW":"24","measuredH":"24","x":"0","y":"0","properties":{"color":"16777215","icon":{"ID":"circle","size":"small"}}},{"ID":"1","typeID":"Icon","zOrder":"1","measuredW":"24","measuredH":"24","x":"0","y":"0","properties":{"color":"10066329","icon":{"ID":"check-circle","size":"small"}}}]}}}]}}},{"ID":"2848","typeID":"Label","zOrder":"68","measuredW":"245","measuredH":"25","x":"1488","y":"1177","properties":{"size":"17","text":"Just get the basic idea of these."}},{"ID":"2849","typeID":"Arrow","zOrder":"26","w":"153","h":"2","measuredW":"150","measuredH":"100","x":"1350","y":"1098","properties":{"curvature":"0","leftArrow":"false","rightArrow":"false","color":"4273622","stroke":"dotted","p0":{"x":153.43623321529276,"y":2.1515151515150137},"p1":{"x":0.4999578668592745,"y":0.00035566936975391084},"p2":{"x":0.04816647286861553,"y":-0.34845706590590453}}},{"ID":"2850","typeID":"Arrow","zOrder":"25","h":"46","measuredW":"150","measuredH":"100","x":"1342","y":"1111","properties":{"curvature":"0","leftArrow":"false","rightArrow":"false","color":"4273622","stroke":"dotted","p0":{"x":149.95030847121234,"y":46.17526038328424},"p1":{"x":0.42265907915157874,"y":-0.08346266597689306},"p2":{"x":0.3992035647902412,"y":-0.11436732584661513}}},{"ID":"2893","typeID":"Arrow","zOrder":"24","w":"131","h":"24","measuredW":"150","measuredH":"100","x":"1363","y":"1455","properties":{"curvature":"0","leftArrow":"false","rightArrow":"false","color":"4273622","stroke":"dotted","p0":{"x":130.95544602123732,"y":23.867029894531242},"p1":{"x":0.3512843587716724,"y":-0.055651375067110674},"p2":{"x":-0.46006702341355776,"y":-0.02669974995069424}}},{"ID":"2896","typeID":"Arrow","zOrder":"23","w":"136","h":"24","measuredW":"150","measuredH":"100","x":"1359","y":"1417","properties":{"curvature":"0","leftArrow":"false","rightArrow":"false","color":"4273622","stroke":"dotted","p0":{"x":136.15013250346146,"y":-0.2566671811218839},"p1":{"x":0.4699759807846267,"y":0.06405124099279334},"p2":{"x":-0.04412647008598469,"y":23.637062463360053}}},{"ID":"2897","typeID":"Arrow","zOrder":"22","w":"333","h":"1","measuredW":"150","measuredH":"100","x":"857","y":"1449","properties":{"curvature":"0","leftArrow":"false","rightArrow":"false","color":"4273622","p0":{"x":0.04142925695464328,"y":0.362673214497363},"p1":{"x":0.499957866859274,"y":0.0003556693697539092},"p2":{"x":332.81818181818176,"y":0.362673214497363}}},{"ID":"2900","typeID":"Arrow","zOrder":"21","w":"161","h":"2","measuredW":"150","measuredH":"100","x":"1342","y":"1268","properties":{"curvature":"0","leftArrow":"false","rightArrow":"false","color":"4273622","stroke":"dotted","p0":{"x":161.43623321529276,"y":2.1515151515150137},"p1":{"x":0.49995786685927457,"y":0.00035566936975390845},"p2":{"x":0.34973142699914206,"y":-0.03412281550845364}}},{"ID":"2901","typeID":"Arrow","zOrder":"20","w":"154","h":"41","measuredW":"150","measuredH":"100","x":"1345","y":"1281","properties":{"curvature":"0","leftArrow":"false","rightArrow":"false","color":"4273622","stroke":"dotted","p0":{"x":154.37932265053473,"y":40.786503208687236},"p1":{"x":0.381694744782499,"y":-0.08021121448327811},"p2":{"x":-0.11753323068592181,"y":0.26273773164575687}}},{"ID":"2904","typeID":"Arrow","zOrder":"19","w":"1","h":"114","measuredW":"150","measuredH":"100","x":"1213","y":"1331","properties":{"curvature":"0","leftArrow":"false","rightArrow":"false","color":"4273622","p0":{"x":-0.18181818181824383,"y":0},"p1":{"x":0.4999578668592739,"y":0.0003556693697539093},"p2":{"x":-0.18181818181824383,"y":113.97948286209976}}},{"ID":"2906","typeID":"Arrow","zOrder":"18","w":"1","h":"94","measuredW":"150","measuredH":"100","x":"768","y":"1451","properties":{"curvature":"0","leftArrow":"false","rightArrow":"false","color":"4273622","p0":{"x":-0.18181818181824383,"y":0},"p1":{"x":0.49995786685927396,"y":0.0003556693697539094},"p2":{"x":-0.18181818181824383,"y":94.03541136954323},"stroke":"dotted"}},{"ID":"2913","typeID":"Arrow","zOrder":"17","w":"1","h":"238","measuredW":"150","measuredH":"100","x":"942","y":"1458","properties":{"curvature":"0","leftArrow":"false","rightArrow":"false","color":"4273622","p0":{"x":-0.18181818181824383,"y":0},"p1":{"x":0.49995786685927385,"y":0.00035566936975390943},"p2":{"x":-0.18181818181824383,"y":238.04006420899805}}},{"ID":"2923","typeID":"Arrow","zOrder":"16","w":"1","h":"73","measuredW":"150","measuredH":"100","x":"766","y":"1696","properties":{"curvature":"0","leftArrow":"false","rightArrow":"false","color":"4273622","stroke":"dotted","p0":{"x":-0.18181818181824383,"y":0},"p1":{"x":0.4999578668592739,"y":0.00035566936975390943},"p2":{"x":-0.18181818181824383,"y":73.08703041995386}}},{"ID":"2924","typeID":"Arrow","zOrder":"15","w":"333","h":"1","measuredW":"150","measuredH":"100","x":"903","y":"1695","properties":{"curvature":"0","leftArrow":"false","rightArrow":"false","color":"4273622","p0":{"x":0.04142925695464328,"y":0.362673214497363},"p1":{"x":0.499957866859274,"y":0.0003556693697539092},"p2":{"x":332.81818181818176,"y":0.362673214497363}}},{"ID":"2933","typeID":"Arrow","zOrder":"14","w":"1","h":"73","measuredW":"150","measuredH":"100","x":"1211","y":"1623","properties":{"curvature":"0","leftArrow":"false","rightArrow":"false","color":"4273622","stroke":"dotted","p0":{"x":-0.18181818181824383,"y":0},"p1":{"x":0.4999578668592739,"y":0.00035566936975390943},"p2":{"x":-0.18181818181824383,"y":73.08703041995386}}},{"ID":"2934","typeID":"Arrow","zOrder":"13","w":"202","h":"169","measuredW":"150","measuredH":"100","x":"1345","y":"1700","properties":{"curvature":"0","leftArrow":"false","rightArrow":"false","color":"4273622","p0":{"x":0.4407532602174342,"y":-0.33922541684933094},"p1":{"x":0.5377224186047156,"y":0.2397621873145367},"p2":{"x":202.5,"y":168.5}}},{"ID":"2947","typeID":"Arrow","zOrder":"12","w":"1","h":"114","measuredW":"150","measuredH":"100","x":"1701","y":"1756","properties":{"curvature":"0","leftArrow":"false","rightArrow":"false","color":"4273622","p0":{"x":-0.18181818181824383,"y":0},"p1":{"x":0.4999578668592739,"y":0.0003556693697539093},"p2":{"x":-0.18181818181824383,"y":113.97948286209976},"stroke":"dotted"}},{"ID":"2948","typeID":"Arrow","zOrder":"11","w":"1","h":"80","measuredW":"150","measuredH":"100","x":"1701","y":"1623","properties":{"curvature":"0","leftArrow":"false","rightArrow":"false","color":"4273622","stroke":"dotted","p0":{"x":-0.18181818181824383,"y":0},"p1":{"x":0.4999578668592739,"y":0.00035566936975390927},"p2":{"x":-0.18181818181824383,"y":79.5}}},{"ID":"2949","typeID":"Arrow","zOrder":"10","w":"184","h":"147","measuredW":"150","measuredH":"100","x":"1361","y":"1879","properties":{"curvature":"0","leftArrow":"false","rightArrow":"false","color":"4273622","p0":{"x":183.5,"y":-0.03666724399795385},"p1":{"x":0.4528877147224164,"y":0.2228100131869359},"p2":{"x":0,"y":146.5}}},{"ID":"2956","typeID":"Arrow","zOrder":"9","w":"1","h":"114","measuredW":"150","measuredH":"100","x":"1233","y":"1912","properties":{"curvature":"0","leftArrow":"false","rightArrow":"false","color":"4273622","p0":{"x":-0.18181818181824383,"y":0},"p1":{"x":0.4999578668592739,"y":0.0003556693697539093},"p2":{"x":-0.18181818181824383,"y":113.97948286209976},"stroke":"dotted"}},{"ID":"2957","typeID":"Arrow","zOrder":"8","w":"127","h":"1","measuredW":"150","measuredH":"100","x":"984","y":"2024","properties":{"curvature":"0","leftArrow":"false","rightArrow":"false","color":"4273622","p0":{"x":-0.4746082422041127,"y":0.362673214497363},"p1":{"x":0.49995786685927396,"y":0.00035566936975390927},"p2":{"x":126.69373677187127,"y":0.362673214497363}}},{"ID":"2960","typeID":"Arrow","zOrder":"7","w":"1","h":"151","measuredW":"150","measuredH":"100","x":"797","y":"1960","properties":{"curvature":"0","leftArrow":"false","rightArrow":"false","color":"4273622","stroke":"dotted","p0":{"x":0,"y":0},"p1":{"x":0.5016483571549873,"y":-0.00045943399456992786},"p2":{"x":0,"y":151}}},{"ID":"2961","typeID":"Arrow","zOrder":"6","w":"1","h":"151","measuredW":"150","measuredH":"100","x":"937","y":"1960","properties":{"curvature":"0","leftArrow":"false","rightArrow":"false","color":"4273622","stroke":"dotted","p0":{"x":0,"y":0},"p1":{"x":0.5016483571549873,"y":-0.00045943399456992786},"p2":{"x":0,"y":151}}},{"ID":"2971","typeID":"Arrow","zOrder":"5","h":"1","measuredW":"150","measuredH":"100","x":"658","y":"2024","properties":{"curvature":"0","leftArrow":"false","rightArrow":"false","color":"4273622","p0":{"x":0.16382818454974313,"y":0.362673214497363},"p1":{"x":0.4999578668592739,"y":0.0003556693697539094},"p2":{"x":149.69373677187127,"y":0.362673214497363}}},{"ID":"2972","typeID":"Arrow","zOrder":"101","w":"1","h":"175","measuredW":"150","measuredH":"100","x":"657","y":"2025","properties":{"curvature":"0","leftArrow":"false","rightArrow":"false","color":"4273622","p0":{"x":-0.18181818181824383,"y":0},"p1":{"x":0.4999578668592739,"y":0.0003556693697539095},"p2":{"x":-0.18181818181824383,"y":175}}},{"ID":"2975","typeID":"Arrow","zOrder":"4","w":"519","h":"1","measuredW":"150","measuredH":"100","x":"658","y":"2200","properties":{"curvature":"0","leftArrow":"false","rightArrow":"false","color":"4273622","p0":{"x":0.16382818454974313,"y":0.362673214497363},"p1":{"x":0.4999578668592739,"y":0.0003556693697539094},"p2":{"x":518.6666666666667,"y":0.3626732144975904}}},{"ID":"2984","typeID":"Arrow","zOrder":"3","w":"1","h":"105","measuredW":"150","measuredH":"100","x":"861","y":"2204","properties":{"curvature":"0","leftArrow":"false","rightArrow":"false","color":"4273622","stroke":"dotted","p0":{"x":0,"y":0},"p1":{"x":0.5016483571549873,"y":-0.0004594339945699278},"p2":{"x":0,"y":105}}},{"ID":"2987","typeID":"Arrow","zOrder":"2","w":"1","h":"85","measuredW":"150","measuredH":"100","x":"1213","y":"2200","properties":{"curvature":"0","leftArrow":"false","rightArrow":"false","color":"4273622","stroke":"dotted","p0":{"x":-0.18181818181824383,"y":0},"p1":{"x":0.49995786685927385,"y":0.0003556693697539093},"p2":{"x":-0.18181818181824383,"y":84.66666666666652}}},{"ID":"2996","typeID":"Arrow","zOrder":"1","w":"340","h":"1","measuredW":"150","measuredH":"100","x":"1267","y":"2200","properties":{"curvature":"0","leftArrow":"false","rightArrow":"false","color":"4273622","p0":{"x":0.16382818454974313,"y":0.362673214497363},"p1":{"x":0.4999578668592738,"y":0.0003556693697539093},"p2":{"x":340.33333333333326,"y":0.3626732144975904}}},{"ID":"2997","typeID":"Arrow","zOrder":"112","w":"1","h":"342","measuredW":"150","measuredH":"100","x":"1607","y":"2200","properties":{"curvature":"0","leftArrow":"false","rightArrow":"false","color":"4273622","p0":{"x":-0.18181818181824383,"y":0},"p1":{"x":0.4999578668592739,"y":0.0003556693697539096},"p2":{"x":-0.18181818181824383,"y":342}}},{"ID":"2998","typeID":"Arrow","zOrder":"113","w":"441","h":"1","measuredW":"150","measuredH":"100","x":"1166","y":"2543","properties":{"curvature":"0","leftArrow":"false","rightArrow":"false","color":"4273622","p0":{"x":0,"y":0.3626732144975904},"p1":{"x":0.49995786685927374,"y":0.00035566936975390954},"p2":{"x":441.33333333333326,"y":0.3626732144975904}}},{"ID":"2999","typeID":"Arrow","zOrder":"114","w":"1","h":"161","measuredW":"150","measuredH":"100","x":"1166","y":"2544","properties":{"curvature":"0","leftArrow":"false","rightArrow":"false","color":"4273622","p0":{"x":-0.18181818181824383,"y":0},"p1":{"x":0.4999578668592739,"y":0.00035566936975390965},"p2":{"x":-0.18181818181824383,"y":161}}},{"ID":"3000","typeID":"Arrow","zOrder":"115","w":"1","h":"81","measuredW":"150","measuredH":"100","x":"1166","y":"2729","properties":{"curvature":"0","leftArrow":"false","rightArrow":"false","stroke":"dotted","color":"10027263","p0":{"x":0,"y":0},"p1":{"x":0.49999999999999994,"y":0},"p2":{"x":0,"y":81.09090909090901}}},{"ID":"3001","typeID":"TextArea","zOrder":"116","w":"438","h":"118","measuredW":"200","measuredH":"140","x":"947","y":"2643"},{"ID":"3002","typeID":"Label","zOrder":"117","measuredW":"366","measuredH":"25","x":"983","y":"2662","properties":{"size":"17","text":"Continue Learning with following relevant tracks"}},{"ID":"3003","typeID":"__group__","zOrder":"118","measuredW":"198","measuredH":"44","w":"198","h":"44","x":"1170","y":"2699","properties":{"controlName":"ext_link:roadmap.sh/devops"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"198","h":"44","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16770457"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"141","measuredH":"25","x":"28","y":"9","properties":{"size":"17","text":"DevOps Roadmap"}}]}}},{"ID":"3004","typeID":"__group__","zOrder":"119","measuredW":"198","measuredH":"44","w":"198","h":"44","x":"962","y":"2699","properties":{"controlName":"ext_link:roadmap.sh/backend"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"198","h":"44","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16770457"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"147","measuredH":"25","x":"25","y":"9","properties":{"size":"17","text":"Backend Roadmap"}}]}}},{"ID":"3005","typeID":"Arrow","zOrder":"120","w":"45","h":"1","measuredW":"150","measuredH":"100","x":"613","y":"1387","properties":{"curvature":"0","leftArrow":"false","rightArrow":"false","color":"16777215","p0":{"x":0.04142925695464328,"y":0.362673214497363},"p1":{"x":0.49995786685927407,"y":0.0003556693697539088},"p2":{"x":45.203968575995304,"y":0.362673214497363}}},{"ID":"3006","typeID":"Arrow","zOrder":"121","w":"45","h":"1","measuredW":"150","measuredH":"100","x":"1754","y":"1371","properties":{"curvature":"0","leftArrow":"false","rightArrow":"false","color":"16777215","p0":{"x":0.04142925695464328,"y":0.362673214497363},"p1":{"x":0.49995786685927407,"y":0.0003556693697539088},"p2":{"x":45.203968575995304,"y":0.362673214497363}}},{"ID":"3007","typeID":"Arrow","zOrder":"122","w":"169","h":"1","measuredW":"150","measuredH":"100","x":"1081","y":"2882","properties":{"curvature":"0","leftArrow":"false","rightArrow":"false","stroke":"dotted","color":"16777215","p0":{"x":0,"y":0},"p1":{"x":0.4999999999999999,"y":0},"p2":{"x":168.6400000000001,"y":0}}},{"ID":"3008","typeID":"__group__","zOrder":"37","measuredW":"298","measuredH":"50","w":"298","h":"50","x":"1065","y":"909","properties":{"controlName":"100-introduction"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"298","h":"50","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16776960"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"93","measuredH":"25","x":"102","y":"12","properties":{"size":"17","text":"Introduction"}}]}}},{"ID":"3009","typeID":"__group__","zOrder":"58","measuredW":"298","measuredH":"50","w":"298","h":"50","x":"1065","y":"1081","properties":{"controlName":"101-underlying-technologies"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"298","h":"50","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16776960"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"189","measuredH":"25","x":"54","y":"12","properties":{"size":"17","text":"Underlying Technologies"}}]}}},{"ID":"3010","typeID":"__group__","zOrder":"69","measuredW":"298","measuredH":"50","w":"298","h":"50","x":"1065","y":"1249","properties":{"controlName":"102-installation-setup"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"298","h":"50","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16776960"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"145","measuredH":"25","x":"76","y":"12","properties":{"size":"17","text":"Installation / Setup"}}]}}},{"ID":"3011","typeID":"__group__","zOrder":"77","measuredW":"298","measuredH":"50","w":"298","h":"50","x":"1065","y":"1304","properties":{"controlName":"103-docker-basics"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"298","h":"50","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16776960"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"131","measuredH":"25","x":"83","y":"13","properties":{"size":"17","text":"Basics of Docker"}}]}}},{"ID":"3012","typeID":"__group__","zOrder":"72","measuredW":"298","measuredH":"50","w":"298","h":"50","x":"1076","y":"1423","properties":{"controlName":"104-data-persistence"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"298","h":"50","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16776960"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"132","measuredH":"25","x":"83","y":"12","properties":{"size":"17","text":"Data Persistence"}}]}}},{"ID":"3013","typeID":"__group__","zOrder":"76","measuredW":"340","measuredH":"50","w":"340","h":"50","x":"633","y":"1423","properties":{"controlName":"105-using-third-party-images"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"340","h":"50","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16776960"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"260","measuredH":"25","x":"40","y":"12","properties":{"size":"17","text":"Using 3rd Party Container Images"}}]}}},{"ID":"3014","typeID":"__group__","zOrder":"81","measuredW":"338","measuredH":"50","w":"338","h":"50","x":"633","y":"1671","properties":{"controlName":"106-building-container-images"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"338","h":"50","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16776960"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"205","measuredH":"25","x":"66","y":"12","properties":{"size":"17","text":"Building Container Images"}}]}}},{"ID":"3015","typeID":"__group__","zOrder":"85","measuredW":"298","measuredH":"50","w":"298","h":"50","x":"1076","y":"1672","properties":{"controlName":"107-container-registries"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"298","h":"50","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16776960"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"159","measuredH":"25","x":"69","y":"12","properties":{"size":"17","text":"Container Registries"}}]}}},{"ID":"3016","typeID":"__group__","zOrder":"89","measuredW":"298","measuredH":"50","w":"298","h":"50","x":"1460","y":"1842","properties":{"controlName":"108-running-containers"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"298","h":"50","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16776960"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"153","measuredH":"25","x":"72","y":"12","properties":{"size":"17","text":"Running Containers"}}]}}},{"ID":"3017","typeID":"__group__","zOrder":"93","measuredW":"298","measuredH":"50","w":"298","h":"50","x":"1089","y":"2000","properties":{"controlName":"109-container-security"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"298","h":"50","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16776960"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"142","measuredH":"25","x":"78","y":"12","properties":{"size":"17","text":"Container Security"}}]}}},{"ID":"3018","typeID":"__group__","zOrder":"96","measuredW":"267","measuredH":"50","w":"267","h":"50","x":"735","y":"2000","properties":{"controlName":"110-docker-cli"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"267","h":"50","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16776960"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"87","measuredH":"25","x":"90","y":"12","properties":{"size":"17","text":"Docker CLI"}}]}}},{"ID":"3019","typeID":"__group__","zOrder":"102","measuredW":"265","measuredH":"50","w":"265","h":"50","x":"737","y":"2176","properties":{"controlName":"111-developer-experience"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"265","h":"50","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16776960"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"173","measuredH":"25","x":"46","y":"12","properties":{"size":"17","text":"Developer Experience"}}]}}},{"ID":"3020","typeID":"__group__","zOrder":"107","measuredW":"265","measuredH":"50","w":"265","h":"50","x":"1089","y":"2176","properties":{"controlName":"112-deploying-containers"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"265","h":"50","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16776960"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"166","measuredH":"25","x":"42","y":"12","properties":{"size":"17","text":"Deploying Containers"}}]}}},{"ID":"3021","typeID":"__group__","zOrder":"54","measuredW":"299","measuredH":"44","w":"299","h":"44","x":"1484","y":"836","properties":{"controlName":"100-introduction:what-are-containers"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"299","h":"44","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16770457"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"167","measuredH":"25","x":"66","y":"9","properties":{"size":"17","text":"What are Containers?"}}]}}},{"ID":"3022","typeID":"__group__","zOrder":"55","measuredW":"299","measuredH":"44","w":"299","h":"44","x":"1484","y":"887","properties":{"controlName":"101-introduction:need-for-containers"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"299","h":"44","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16770457"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"223","measuredH":"25","x":"38","y":"9","properties":{"size":"17","text":"Why do we need Containers?"}}]}}},{"ID":"3023","typeID":"__group__","zOrder":"56","measuredW":"299","measuredH":"44","w":"299","h":"44","x":"1484","y":"937","properties":{"controlName":"102-introduction:bare-metal-vm-containers"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"299","h":"44","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16770457"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"254","measuredH":"25","x":"23","y":"9","properties":{"size":"17","text":"Bare Metal vs VMs vs Containers"}}]}}},{"ID":"3024","typeID":"__group__","zOrder":"57","measuredW":"299","measuredH":"44","w":"299","h":"44","x":"1484","y":"987","properties":{"controlName":"103-introduction:docker-and-oci"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"299","h":"44","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16770457"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"124","measuredH":"25","x":"88","y":"9","properties":{"size":"17","text":"Docker and OCI"}}]}}},{"ID":"3025","typeID":"__group__","zOrder":"65","measuredW":"182","measuredH":"44","w":"182","h":"44","x":"1484","y":"1079","properties":{"controlName":"100-underlying-technologies:namespaces"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"182","h":"44","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16770457"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"102","measuredH":"25","x":"40","y":"9","properties":{"size":"17","text":"Namespaces"}}]}}},{"ID":"3026","typeID":"__group__","zOrder":"66","measuredW":"107","measuredH":"44","w":"107","h":"44","x":"1674","y":"1079","properties":{"controlName":"101-underlying-technologies:cgroups"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"107","h":"44","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16770457"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"63","measuredH":"25","x":"22","y":"9","properties":{"size":"17","text":"cgroups"}}]}}},{"ID":"3027","typeID":"__group__","zOrder":"67","measuredW":"299","measuredH":"44","w":"299","h":"44","x":"1484","y":"1128","properties":{"controlName":"102-underlying-technologies:union-filesystems"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"299","h":"44","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16770457"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"140","measuredH":"25","x":"80","y":"9","properties":{"size":"17","text":"Union Filesystems"}}]}}},{"ID":"3028","typeID":"__group__","zOrder":"70","measuredW":"309","measuredH":"44","w":"309","h":"44","x":"1483","y":"1247","properties":{"controlName":"100-installation-setup:docker-desktop"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"309","h":"44","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16770457"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"268","measuredH":"25","x":"21","y":"10","properties":{"size":"17","text":"Docker Desktop ( Win / Mac Linux)"}}]}}},{"ID":"3029","typeID":"__group__","zOrder":"71","measuredW":"309","measuredH":"44","w":"309","h":"44","x":"1483","y":"1296","properties":{"controlName":"101-installation-setup:docker-engine"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"309","h":"44","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16770457"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"181","measuredH":"25","x":"64","y":"10","properties":{"size":"17","text":"Docker Engine ( Linux )"}}]}}},{"ID":"3030","typeID":"__group__","zOrder":"73","measuredW":"309","measuredH":"44","w":"309","h":"44","x":"1483","y":"1401","properties":{"controlName":"100-data-persistence:ephemeral-container-fs"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"309","h":"44","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16770457"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"242","measuredH":"25","x":"34","y":"10","properties":{"size":"17","text":"Ephemeral container filesystem"}}]}}},{"ID":"3031","typeID":"__group__","zOrder":"74","measuredW":"152","measuredH":"44","w":"152","h":"44","x":"1483","y":"1450","properties":{"controlName":"101-data-persistence:volume-mounts"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"152","h":"44","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16770457"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"118","measuredH":"25","x":"17","y":"10","properties":{"size":"17","text":"Volume Mounts"}}]}}},{"ID":"3032","typeID":"__group__","zOrder":"75","measuredW":"152","measuredH":"44","w":"152","h":"44","x":"1640","y":"1451","properties":{"controlName":"102-data-persistence:bind-mounts"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"152","h":"44","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16770457"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"97","measuredH":"25","x":"27","y":"9","properties":{"size":"17","text":"Bind Mounts"}}]}}},{"ID":"3034","typeID":"__group__","zOrder":"78","measuredW":"272","measuredH":"44","w":"272","h":"44","x":"633","y":"1501","properties":{"controlName":"100-using-third-party-images:databases"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"272","h":"44","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16770457"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"83","measuredH":"25","x":"94","y":"10","properties":{"size":"17","text":"Databases"}}]}}},{"ID":"3035","typeID":"__group__","zOrder":"79","measuredW":"272","measuredH":"44","w":"272","h":"44","x":"633","y":"1549","properties":{"controlName":"101-using-third-party-images:interactive-test-environments"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"272","h":"44","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16770457"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"228","measuredH":"25","x":"22","y":"10","properties":{"size":"17","text":"Interactive Test Environments"}}]}}},{"ID":"3036","typeID":"__group__","zOrder":"80","measuredW":"272","measuredH":"44","w":"272","h":"44","x":"633","y":"1597","properties":{"controlName":"102-using-third-party-images:command-line-utilities"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"272","h":"44","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16770457"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"179","measuredH":"25","x":"46","y":"10","properties":{"size":"17","text":"Command Line Utilities"}}]}}},{"ID":"3037","typeID":"__group__","zOrder":"82","measuredW":"272","measuredH":"44","w":"272","h":"44","x":"633","y":"1746","properties":{"controlName":"100-building-container-images:dockerfiles"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"272","h":"44","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16770457"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"86","measuredH":"25","x":"93","y":"10","properties":{"size":"17","text":"Dockerfiles"}}]}}},{"ID":"3038","typeID":"__group__","zOrder":"83","measuredW":"272","measuredH":"44","w":"272","h":"44","x":"633","y":"1794","properties":{"controlName":"101-building-container-images:efficient-layer-caching"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"272","h":"44","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16770457"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"168","measuredH":"25","x":"52","y":"10","properties":{"size":"17","text":"Efficient layer caching"}}]}}},{"ID":"3039","typeID":"__group__","zOrder":"84","measuredW":"272","measuredH":"44","w":"272","h":"44","x":"633","y":"1842","properties":{"controlName":"102-building-container-images:image-size-and-security"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"272","h":"44","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16770457"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"182","measuredH":"25","x":"45","y":"10","properties":{"size":"17","text":"Image size and security"}}]}}},{"ID":"3040","typeID":"__group__","zOrder":"86","measuredW":"272","measuredH":"44","w":"272","h":"44","x":"1089","y":"1597","properties":{"controlName":"100-container-registries:dockerhub"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"272","h":"44","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16770457"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"84","measuredH":"25","x":"94","y":"10","properties":{"size":"17","text":"Dockerhub"}}]}}},{"ID":"3041","typeID":"__group__","zOrder":"87","measuredW":"272","measuredH":"44","w":"272","h":"44","x":"1089","y":"1549","properties":{"controlName":"101-container-registries:dockerhub-alt"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"272","h":"44","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16770457"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"231","measuredH":"25","x":"20","y":"10","properties":{"size":"17","text":"Others (ghcr, ecr, gcr, act, etc)"}}]}}},{"ID":"3042","typeID":"__group__","zOrder":"88","measuredW":"272","measuredH":"44","w":"272","h":"44","x":"1089","y":"1501","properties":{"controlName":"102-container-registries:image-tagging-best-practices"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"272","h":"44","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16770457"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"231","measuredH":"25","x":"20","y":"9","properties":{"size":"17","text":"Image Tagging Best Practices"}}]}}},{"ID":"3043","typeID":"__group__","zOrder":"90","measuredW":"174","measuredH":"44","w":"174","h":"44","x":"1615","y":"1728","properties":{"controlName":"100-running-containers:docker-run"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"174","h":"44","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16770457"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"83","measuredH":"25","x":"45","y":"9","properties":{"size":"17","text":"docker run"}}]}}},{"ID":"3044","typeID":"__group__","zOrder":"91","measuredW":"174","measuredH":"44","w":"174","h":"44","x":"1615","y":"1680","properties":{"controlName":"101-running-containers:docker-compose"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"174","h":"44","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16770457"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"129","measuredH":"25","x":"22","y":"9","properties":{"size":"17","text":"docker compose"}}]}}},{"ID":"3045","typeID":"__group__","zOrder":"92","measuredW":"273","measuredH":"44","w":"273","h":"44","x":"1517","y":"1598","properties":{"controlName":"102-running-containers:runtime-config-options"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"273","h":"44","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16770457"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"236","measuredH":"25","x":"20","y":"9","properties":{"size":"17","text":"Runtime Configuration Options"}}]}}},{"ID":"3046","typeID":"__group__","zOrder":"94","measuredW":"219","measuredH":"44","w":"219","h":"44","x":"1124","y":"1892","properties":{"controlName":"100-container-security:image-security"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"219","h":"44","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16770457"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"116","measuredH":"25","x":"52","y":"9","properties":{"size":"17","text":"Image Security"}}]}}},{"ID":"3047","typeID":"__group__","zOrder":"95","measuredW":"219","measuredH":"44","w":"219","h":"44","x":"1124","y":"1844","properties":{"controlName":"101-container-security:runtime-security"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"219","h":"44","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16770457"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"131","measuredH":"25","x":"44","y":"9","properties":{"size":"17","text":"Runtime Security"}}]}}},{"ID":"3048","typeID":"__group__","zOrder":"97","measuredW":"122","measuredH":"44","w":"122","h":"44","x":"737","y":"1926","properties":{"controlName":"100-docker-cli:images"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"122","h":"44","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16770457"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"58","measuredH":"25","x":"32","y":"9","properties":{"size":"17","text":"Images"}}]}}},{"ID":"3049","typeID":"__group__","zOrder":"98","measuredW":"126","measuredH":"44","w":"126","h":"44","x":"875","y":"1926","properties":{"controlName":"101-docker-cli:containers"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"126","h":"44","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16770457"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"85","measuredH":"25","x":"20","y":"9","properties":{"size":"17","text":"Containers"}}]}}},{"ID":"3050","typeID":"__group__","zOrder":"99","measuredW":"122","measuredH":"44","w":"122","h":"44","x":"737","y":"2081","properties":{"controlName":"102-docker-cli:volumes"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"122","h":"44","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16770457"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"65","measuredH":"25","x":"28","y":"9","properties":{"size":"17","text":"Volumes"}}]}}},{"ID":"3051","typeID":"__group__","zOrder":"100","measuredW":"126","measuredH":"44","w":"126","h":"44","x":"875","y":"2081","properties":{"controlName":"102-docker-cli:networks"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"126","h":"44","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16770457"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"72","measuredH":"25","x":"27","y":"9","properties":{"size":"17","text":"Networks"}}]}}},{"ID":"3052","typeID":"__group__","zOrder":"103","measuredW":"219","measuredH":"44","w":"219","h":"44","x":"752","y":"2272","properties":{"controlName":"100-developer-experience:hot-reloading"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"219","h":"44","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16770457"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"110","measuredH":"25","x":"55","y":"9","properties":{"size":"17","text":"Hot Reloading"}}]}}},{"ID":"3053","typeID":"__group__","zOrder":"104","measuredW":"219","measuredH":"44","w":"219","h":"44","x":"752","y":"2320","properties":{"controlName":"101-developer-experience:debuggers"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"219","h":"44","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16770457"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"86","measuredH":"25","x":"67","y":"9","properties":{"size":"17","text":"Debuggers"}}]}}},{"ID":"3054","typeID":"__group__","zOrder":"105","measuredW":"219","measuredH":"44","w":"219","h":"44","x":"752","y":"2368","properties":{"controlName":"102-developer-experience:tests"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"219","h":"44","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16770457"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"41","measuredH":"25","x":"89","y":"9","properties":{"size":"17","text":"Tests"}}]}}},{"ID":"3055","typeID":"__group__","zOrder":"106","measuredW":"219","measuredH":"44","w":"219","h":"44","x":"752","y":"2416","properties":{"controlName":"103-developer-experience:continuous-integration"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"219","h":"44","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16770457"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"176","measuredH":"25","x":"22","y":"9","properties":{"size":"17","text":"Continuous Integration"}}]}}},{"ID":"3056","typeID":"__group__","zOrder":"108","measuredW":"219","measuredH":"44","w":"219","h":"44","x":"1102","y":"2272","properties":{"controlName":"100-deploying-containers:paas-options"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"219","h":"44","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16770457"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"104","measuredH":"25","x":"58","y":"9","properties":{"size":"17","text":"PaaS Options"}}]}}},{"ID":"3057","typeID":"__group__","zOrder":"109","measuredW":"219","measuredH":"44","w":"219","h":"44","x":"1102","y":"2320","properties":{"controlName":"101-deploying-containers:kubernetes"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"219","h":"44","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16770457"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"90","measuredH":"25","x":"65","y":"9","properties":{"size":"17","text":"Kubernetes"}}]}}},{"ID":"3058","typeID":"__group__","zOrder":"110","measuredW":"219","measuredH":"44","w":"219","h":"44","x":"1102","y":"2368","properties":{"controlName":"102-deploying-containers:docker-swarm"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"219","h":"44","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16770457"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"111","measuredH":"25","x":"54","y":"9","properties":{"size":"17","text":"Docker Swarm"}}]}}},{"ID":"3059","typeID":"__group__","zOrder":"111","measuredW":"219","measuredH":"44","w":"219","h":"44","x":"1102","y":"2416","properties":{"controlName":"103-deploying-containers:nomad"},"children":{"controls":{"control":[{"ID":"0","typeID":"TextArea","zOrder":"0","w":"219","h":"44","measuredW":"200","measuredH":"140","x":"0","y":"0","properties":{"color":"16770457"}},{"ID":"1","typeID":"Label","zOrder":"1","measuredW":"56","measuredH":"25","x":"77","y":"9","properties":{"size":"17","text":"Nomad"}}]}}},{"ID":"3060","typeID":"__group__","zOrder":"62","measuredW":"70","measuredH":"25","w":"70","h":"25","x":"693","y":"669","properties":{"controlName":"ext_link:twitter.com/sidpalas"},"children":{"controls":{"control":[{"ID":"0","typeID":"Label","zOrder":"0","measuredW":"70","measuredH":"25","x":"0","y":"0","properties":{"size":"17","text":"{color:purple}Sid Palas{color}"}}]}}},{"ID":"3061","typeID":"__group__","zOrder":"64","measuredW":"268","measuredH":"25","w":"268","h":"25","x":"659","y":"697","properties":{"controlName":"ext_link:courses.devopsdirective.com/docker-beginner-to-pro"},"children":{"controls":{"control":[{"ID":"0","typeID":"Label","zOrder":"0","measuredW":"268","measuredH":"25","x":"0","y":"0","properties":{"size":"17","text":"{color:purple}course covering this topic in depth.{color}"}}]}}},{"ID":"3063","typeID":"Canvas","zOrder":"0","w":"327","h":"393","measuredW":"100","measuredH":"70","x":"635","y":"892"}]},"attributes":{"name":"New Wireframe 9 copy 5","order":1000147.9446306123,"parentID":null,"notes":null},"branchID":"Master","resourceID":"A3B84AD1-CEAB-4958-B7C6-199A90A297E8","mockupH":"2283","mockupW":"1186","measuredW":"1799","measuredH":"2883","version":"1.0"},"groupOffset":{"x":0,"y":0},"dependencies":[],"projectID":"file:///Users/kamranahmed/Desktop/AWS%20Roadmap.bmpr"} \ No newline at end of file +{ + "mockup": { + "controls": { + "control": [ + { + "ID": "2620", + "typeID": "Arrow", + "zOrder": "31", + "w": "1", + "h": "501", + "measuredW": "150", + "measuredH": "100", + "x": "1213", + "y": "766", + "properties": { + "curvature": "0", + "leftArrow": "false", + "rightArrow": "false", + "color": "4273622", + "p0": { + "x": -0.18181818181824383, + "y": 0 + }, + "p1": { + "x": 0.49995786685927396, + "y": 0.00035566936975390927 + }, + "p2": { + "x": -0.18181818181824383, + "y": 501.00085499312513 + } + } + }, + { + "ID": "2625", + "typeID": "Label", + "zOrder": "32", + "measuredW": "104", + "measuredH": "40", + "x": "1162", + "y": "714", + "properties": { + "size": "32", + "text": "Docker" + } + }, + { + "ID": "2626", + "typeID": "Canvas", + "zOrder": "33", + "w": "350", + "h": "141", + "measuredW": "100", + "measuredH": "70", + "x": "1433", + "y": "636" + }, + { + "ID": "2627", + "typeID": "Label", + "zOrder": "34", + "measuredW": "314", + "measuredH": "25", + "x": "1447", + "y": "653", + "properties": { + "size": "17", + "text": "Find the detailed version of this roadmap" + } + }, + { + "ID": "2628", + "typeID": "Label", + "zOrder": "35", + "measuredW": "319", + "measuredH": "25", + "x": "1447", + "y": "681", + "properties": { + "size": "17", + "text": "along with resources and other roadmaps" + } + }, + { + "ID": "2629", + "typeID": "__group__", + "zOrder": "36", + "measuredW": "320", + "measuredH": "45", + "w": "320", + "h": "45", + "x": "1448", + "y": "717", + "properties": { + "controlName": "ext_link:roadmap.sh" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "Canvas", + "zOrder": "0", + "w": "320", + "h": "45", + "measuredW": "100", + "measuredH": "70", + "x": "0", + "y": "0", + "properties": { + "borderColor": "4273622", + "color": "4273622" + } + }, + { + "ID": "2", + "typeID": "Label", + "zOrder": "1", + "measuredW": "172", + "measuredH": "28", + "x": "74", + "y": "8", + "properties": { + "color": "16777215", + "size": "20", + "text": "https://roadmap.sh" + } + } + ] + } + } + }, + { + "ID": "2670", + "typeID": "Arrow", + "zOrder": "39", + "w": "1", + "h": "101", + "measuredW": "150", + "measuredH": "100", + "x": "1213", + "y": "600", + "properties": { + "curvature": "0", + "leftArrow": "false", + "rightArrow": "false", + "color": "4273622", + "stroke": "dotted", + "p0": { + "x": -0.18181818181824383, + "y": 0.060606060606005485 + }, + "p1": { + "x": 0.4999578668592744, + "y": 0.0003556693697539094 + }, + "p2": { + "x": -0.18181818181824383, + "y": 101.15151515151513 + } + } + }, + { + "ID": "2778", + "typeID": "Label", + "zOrder": "38", + "measuredW": "155", + "measuredH": "25", + "x": "721", + "y": "1101", + "properties": { + "size": "17", + "text": "Linux Fundamentals" + } + }, + { + "ID": "2785", + "typeID": "Label", + "zOrder": "40", + "measuredW": "108", + "measuredH": "26", + "x": "746", + "y": "1294", + "properties": { + "text": "Prerequisites", + "size": "18" + } + }, + { + "ID": "2786", + "typeID": "TextArea", + "zOrder": "41", + "w": "300", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "650", + "y": "907", + "properties": { + "color": "16770457" + } + }, + { + "ID": "2787", + "typeID": "Label", + "zOrder": "42", + "measuredW": "149", + "measuredH": "25", + "x": "724", + "y": "916", + "properties": { + "size": "17", + "text": "Package Managers" + } + }, + { + "ID": "2788", + "typeID": "TextArea", + "zOrder": "43", + "w": "300", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "650", + "y": "954", + "properties": { + "color": "16770457" + } + }, + { + "ID": "2789", + "typeID": "Label", + "zOrder": "44", + "measuredW": "216", + "measuredH": "25", + "x": "691", + "y": "963", + "properties": { + "size": "17", + "text": "Users / Groups Permissions" + } + }, + { + "ID": "2790", + "typeID": "TextArea", + "zOrder": "45", + "w": "300", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "650", + "y": "1001", + "properties": { + "color": "16770457" + } + }, + { + "ID": "2791", + "typeID": "Label", + "zOrder": "46", + "measuredW": "127", + "measuredH": "25", + "x": "735", + "y": "1010", + "properties": { + "size": "17", + "text": "Shell commands" + } + }, + { + "ID": "2792", + "typeID": "TextArea", + "zOrder": "47", + "w": "300", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "650", + "y": "1048", + "properties": { + "color": "16770457" + } + }, + { + "ID": "2793", + "typeID": "Label", + "zOrder": "48", + "measuredW": "108", + "measuredH": "25", + "x": "745", + "y": "1057", + "properties": { + "size": "17", + "text": "Shell scripting" + } + }, + { + "ID": "2797", + "typeID": "Label", + "zOrder": "49", + "measuredW": "142", + "measuredH": "25", + "x": "728", + "y": "1240", + "properties": { + "size": "17", + "text": "Web Development" + } + }, + { + "ID": "2798", + "typeID": "TextArea", + "zOrder": "50", + "w": "300", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "650", + "y": "1141", + "properties": { + "color": "16770457" + } + }, + { + "ID": "2799", + "typeID": "Label", + "zOrder": "51", + "measuredW": "175", + "measuredH": "25", + "x": "711", + "y": "1150", + "properties": { + "size": "17", + "text": "Programming Lanuage" + } + }, + { + "ID": "2800", + "typeID": "TextArea", + "zOrder": "52", + "w": "300", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "650", + "y": "1188", + "properties": { + "color": "16770457" + } + }, + { + "ID": "2801", + "typeID": "Label", + "zOrder": "53", + "measuredW": "183", + "measuredH": "25", + "x": "707", + "y": "1197", + "properties": { + "size": "17", + "text": "Application Architecture" + } + }, + { + "ID": "2822", + "typeID": "Arrow", + "zOrder": "27", + "w": "159", + "h": "23", + "measuredW": "150", + "measuredH": "100", + "x": "1336", + "y": "906", + "properties": { + "curvature": "0", + "leftArrow": "false", + "rightArrow": "false", + "color": "4273622", + "stroke": "dotted", + "p0": { + "x": 0.4646359097735058, + "y": 23.353294775624022 + }, + "p1": { + "x": 0.5172121703355936, + "y": -0.04134567000631401 + }, + "p2": { + "x": 159.51104906422256, + "y": 0.2084809210585945 + } + } + }, + { + "ID": "2823", + "typeID": "Arrow", + "zOrder": "28", + "w": "157", + "h": "64", + "measuredW": "150", + "measuredH": "100", + "x": "1336", + "y": "855", + "properties": { + "curvature": "0", + "leftArrow": "false", + "rightArrow": "false", + "color": "4273622", + "stroke": "dotted", + "p0": { + "x": 0.4646359097735058, + "y": 63.67107299659381 + }, + "p1": { + "x": 0.4603346517294317, + "y": -0.10421022711848146 + }, + "p2": { + "x": 157.13722200221582, + "y": 0.1711990879144878 + } + } + }, + { + "ID": "2824", + "typeID": "Arrow", + "zOrder": "29", + "w": "169", + "h": "24", + "measuredW": "150", + "measuredH": "100", + "x": "1328", + "y": "940", + "properties": { + "curvature": "0", + "leftArrow": "false", + "rightArrow": "false", + "color": "4273622", + "stroke": "dotted", + "p0": { + "x": 0.15624119275003068, + "y": 0.628973320155751 + }, + "p1": { + "x": 0.5012965221560048, + "y": 0.04743407560804315 + }, + "p2": { + "x": 168.69796259522582, + "y": 24.367243940222806 + } + } + }, + { + "ID": "2825", + "typeID": "Arrow", + "zOrder": "30", + "w": "152", + "h": "72", + "measuredW": "150", + "measuredH": "100", + "x": "1340", + "y": "946", + "properties": { + "curvature": "0", + "leftArrow": "false", + "rightArrow": "false", + "color": "4273622", + "stroke": "dotted", + "p0": { + "x": 0.025376502783501564, + "y": -0.0299157903291416 + }, + "p1": { + "x": 0.5934120757823323, + "y": 0.11641742644399297 + }, + "p2": { + "x": 151.95030847121234, + "y": 71.77835283537365 + } + } + }, + { + "ID": "2826", + "typeID": "Canvas", + "zOrder": "59", + "w": "327", + "h": "126", + "measuredW": "100", + "measuredH": "70", + "x": "636", + "y": "620" + }, + { + "ID": "2827", + "typeID": "Label", + "zOrder": "60", + "measuredW": "268", + "measuredH": "25", + "x": "659", + "y": "641", + "properties": { + "size": "17", + "text": "Roadmap was made in partnership" + } + }, + { + "ID": "2834", + "typeID": "Canvas", + "zOrder": "123", + "w": "327", + "h": "129", + "measuredW": "100", + "measuredH": "70", + "x": "636", + "y": "736" + }, + { + "ID": "2836", + "typeID": "__group__", + "zOrder": "124", + "measuredW": "202", + "measuredH": "26", + "w": "202", + "h": "26", + "x": "659", + "y": "758", + "properties": { + "controlName": "ext_link:roadmap.sh/kubernetes" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "Label", + "zOrder": "0", + "measuredW": "169", + "measuredH": "25", + "x": "33", + "y": "0", + "properties": { + "size": "17", + "text": "Kubernetes Roadmap" + } + }, + { + "ID": "1", + "typeID": "__group__", + "zOrder": "1", + "measuredW": "24", + "measuredH": "24", + "w": "24", + "h": "24", + "x": "0", + "y": "2", + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "Icon", + "zOrder": "0", + "measuredW": "24", + "measuredH": "24", + "x": "0", + "y": "0", + "properties": { + "color": "16777215", + "icon": { + "ID": "circle", + "size": "small" + } + } + }, + { + "ID": "1", + "typeID": "Icon", + "zOrder": "1", + "measuredW": "24", + "measuredH": "24", + "x": "0", + "y": "0", + "properties": { + "color": "10066329", + "icon": { + "ID": "check-circle", + "size": "small" + } + } + } + ] + } + } + } + ] + } + } + }, + { + "ID": "2837", + "typeID": "__group__", + "zOrder": "125", + "measuredW": "174", + "measuredH": "26", + "w": "174", + "h": "26", + "x": "659", + "y": "788", + "properties": { + "controlName": "ext_link:roadmap.sh/best-practices" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "Label", + "zOrder": "0", + "measuredW": "141", + "measuredH": "25", + "x": "33", + "y": "0", + "properties": { + "size": "17", + "text": "DevOps Roadmap" + } + }, + { + "ID": "1", + "typeID": "__group__", + "zOrder": "1", + "measuredW": "24", + "measuredH": "24", + "w": "24", + "h": "24", + "x": "0", + "y": "2", + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "Icon", + "zOrder": "0", + "measuredW": "24", + "measuredH": "24", + "x": "0", + "y": "0", + "properties": { + "color": "16777215", + "icon": { + "ID": "circle", + "size": "small" + } + } + }, + { + "ID": "1", + "typeID": "Icon", + "zOrder": "1", + "measuredW": "24", + "measuredH": "24", + "x": "0", + "y": "0", + "properties": { + "color": "10066329", + "icon": { + "ID": "check-circle", + "size": "small" + } + } + } + ] + } + } + } + ] + } + } + }, + { + "ID": "2838", + "typeID": "Label", + "zOrder": "61", + "measuredW": "31", + "measuredH": "25", + "x": "659", + "y": "669", + "properties": { + "size": "17", + "text": "with" + } + }, + { + "ID": "2840", + "typeID": "Label", + "zOrder": "63", + "measuredW": "144", + "measuredH": "25", + "x": "763", + "y": "669", + "properties": { + "size": "17", + "text": ". Checkout his free" + } + }, + { + "ID": "2841", + "typeID": "__group__", + "zOrder": "126", + "measuredW": "180", + "measuredH": "26", + "w": "180", + "h": "26", + "x": "659", + "y": "819", + "properties": { + "controlName": "ext_link:roadmap.sh/backend" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "Label", + "zOrder": "0", + "measuredW": "147", + "measuredH": "25", + "x": "33", + "y": "0", + "properties": { + "size": "17", + "text": "Backend Roadmap" + } + }, + { + "ID": "1", + "typeID": "__group__", + "zOrder": "1", + "measuredW": "24", + "measuredH": "24", + "w": "24", + "h": "24", + "x": "0", + "y": "2", + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "Icon", + "zOrder": "0", + "measuredW": "24", + "measuredH": "24", + "x": "0", + "y": "0", + "properties": { + "color": "16777215", + "icon": { + "ID": "circle", + "size": "small" + } + } + }, + { + "ID": "1", + "typeID": "Icon", + "zOrder": "1", + "measuredW": "24", + "measuredH": "24", + "x": "0", + "y": "0", + "properties": { + "color": "10066329", + "icon": { + "ID": "check-circle", + "size": "small" + } + } + } + ] + } + } + } + ] + } + } + }, + { + "ID": "2848", + "typeID": "Label", + "zOrder": "68", + "measuredW": "245", + "measuredH": "25", + "x": "1488", + "y": "1177", + "properties": { + "size": "17", + "text": "Just get the basic idea of these." + } + }, + { + "ID": "2849", + "typeID": "Arrow", + "zOrder": "26", + "w": "153", + "h": "2", + "measuredW": "150", + "measuredH": "100", + "x": "1350", + "y": "1098", + "properties": { + "curvature": "0", + "leftArrow": "false", + "rightArrow": "false", + "color": "4273622", + "stroke": "dotted", + "p0": { + "x": 153.43623321529276, + "y": 2.1515151515150137 + }, + "p1": { + "x": 0.4999578668592745, + "y": 0.00035566936975391084 + }, + "p2": { + "x": 0.04816647286861553, + "y": -0.34845706590590453 + } + } + }, + { + "ID": "2850", + "typeID": "Arrow", + "zOrder": "25", + "h": "46", + "measuredW": "150", + "measuredH": "100", + "x": "1342", + "y": "1111", + "properties": { + "curvature": "0", + "leftArrow": "false", + "rightArrow": "false", + "color": "4273622", + "stroke": "dotted", + "p0": { + "x": 149.95030847121234, + "y": 46.17526038328424 + }, + "p1": { + "x": 0.42265907915157874, + "y": -0.08346266597689306 + }, + "p2": { + "x": 0.3992035647902412, + "y": -0.11436732584661513 + } + } + }, + { + "ID": "2893", + "typeID": "Arrow", + "zOrder": "24", + "w": "131", + "h": "24", + "measuredW": "150", + "measuredH": "100", + "x": "1363", + "y": "1455", + "properties": { + "curvature": "0", + "leftArrow": "false", + "rightArrow": "false", + "color": "4273622", + "stroke": "dotted", + "p0": { + "x": 130.95544602123732, + "y": 23.867029894531242 + }, + "p1": { + "x": 0.3512843587716724, + "y": -0.055651375067110674 + }, + "p2": { + "x": -0.46006702341355776, + "y": -0.02669974995069424 + } + } + }, + { + "ID": "2896", + "typeID": "Arrow", + "zOrder": "23", + "w": "136", + "h": "24", + "measuredW": "150", + "measuredH": "100", + "x": "1359", + "y": "1417", + "properties": { + "curvature": "0", + "leftArrow": "false", + "rightArrow": "false", + "color": "4273622", + "stroke": "dotted", + "p0": { + "x": 136.15013250346146, + "y": -0.2566671811218839 + }, + "p1": { + "x": 0.4699759807846267, + "y": 0.06405124099279334 + }, + "p2": { + "x": -0.04412647008598469, + "y": 23.637062463360053 + } + } + }, + { + "ID": "2897", + "typeID": "Arrow", + "zOrder": "22", + "w": "333", + "h": "1", + "measuredW": "150", + "measuredH": "100", + "x": "857", + "y": "1449", + "properties": { + "curvature": "0", + "leftArrow": "false", + "rightArrow": "false", + "color": "4273622", + "p0": { + "x": 0.04142925695464328, + "y": 0.362673214497363 + }, + "p1": { + "x": 0.499957866859274, + "y": 0.0003556693697539092 + }, + "p2": { + "x": 332.81818181818176, + "y": 0.362673214497363 + } + } + }, + { + "ID": "2900", + "typeID": "Arrow", + "zOrder": "21", + "w": "161", + "h": "2", + "measuredW": "150", + "measuredH": "100", + "x": "1342", + "y": "1268", + "properties": { + "curvature": "0", + "leftArrow": "false", + "rightArrow": "false", + "color": "4273622", + "stroke": "dotted", + "p0": { + "x": 161.43623321529276, + "y": 2.1515151515150137 + }, + "p1": { + "x": 0.49995786685927457, + "y": 0.00035566936975390845 + }, + "p2": { + "x": 0.34973142699914206, + "y": -0.03412281550845364 + } + } + }, + { + "ID": "2901", + "typeID": "Arrow", + "zOrder": "20", + "w": "154", + "h": "41", + "measuredW": "150", + "measuredH": "100", + "x": "1345", + "y": "1281", + "properties": { + "curvature": "0", + "leftArrow": "false", + "rightArrow": "false", + "color": "4273622", + "stroke": "dotted", + "p0": { + "x": 154.37932265053473, + "y": 40.786503208687236 + }, + "p1": { + "x": 0.381694744782499, + "y": -0.08021121448327811 + }, + "p2": { + "x": -0.11753323068592181, + "y": 0.26273773164575687 + } + } + }, + { + "ID": "2904", + "typeID": "Arrow", + "zOrder": "19", + "w": "1", + "h": "114", + "measuredW": "150", + "measuredH": "100", + "x": "1213", + "y": "1331", + "properties": { + "curvature": "0", + "leftArrow": "false", + "rightArrow": "false", + "color": "4273622", + "p0": { + "x": -0.18181818181824383, + "y": 0 + }, + "p1": { + "x": 0.4999578668592739, + "y": 0.0003556693697539093 + }, + "p2": { + "x": -0.18181818181824383, + "y": 113.97948286209976 + } + } + }, + { + "ID": "2906", + "typeID": "Arrow", + "zOrder": "18", + "w": "1", + "h": "94", + "measuredW": "150", + "measuredH": "100", + "x": "768", + "y": "1451", + "properties": { + "curvature": "0", + "leftArrow": "false", + "rightArrow": "false", + "color": "4273622", + "p0": { + "x": -0.18181818181824383, + "y": 0 + }, + "p1": { + "x": 0.49995786685927396, + "y": 0.0003556693697539094 + }, + "p2": { + "x": -0.18181818181824383, + "y": 94.03541136954323 + }, + "stroke": "dotted" + } + }, + { + "ID": "2913", + "typeID": "Arrow", + "zOrder": "17", + "w": "1", + "h": "238", + "measuredW": "150", + "measuredH": "100", + "x": "942", + "y": "1458", + "properties": { + "curvature": "0", + "leftArrow": "false", + "rightArrow": "false", + "color": "4273622", + "p0": { + "x": -0.18181818181824383, + "y": 0 + }, + "p1": { + "x": 0.49995786685927385, + "y": 0.00035566936975390943 + }, + "p2": { + "x": -0.18181818181824383, + "y": 238.04006420899805 + } + } + }, + { + "ID": "2923", + "typeID": "Arrow", + "zOrder": "16", + "w": "1", + "h": "73", + "measuredW": "150", + "measuredH": "100", + "x": "766", + "y": "1696", + "properties": { + "curvature": "0", + "leftArrow": "false", + "rightArrow": "false", + "color": "4273622", + "stroke": "dotted", + "p0": { + "x": -0.18181818181824383, + "y": 0 + }, + "p1": { + "x": 0.4999578668592739, + "y": 0.00035566936975390943 + }, + "p2": { + "x": -0.18181818181824383, + "y": 73.08703041995386 + } + } + }, + { + "ID": "2924", + "typeID": "Arrow", + "zOrder": "15", + "w": "333", + "h": "1", + "measuredW": "150", + "measuredH": "100", + "x": "903", + "y": "1695", + "properties": { + "curvature": "0", + "leftArrow": "false", + "rightArrow": "false", + "color": "4273622", + "p0": { + "x": 0.04142925695464328, + "y": 0.362673214497363 + }, + "p1": { + "x": 0.499957866859274, + "y": 0.0003556693697539092 + }, + "p2": { + "x": 332.81818181818176, + "y": 0.362673214497363 + } + } + }, + { + "ID": "2933", + "typeID": "Arrow", + "zOrder": "14", + "w": "1", + "h": "73", + "measuredW": "150", + "measuredH": "100", + "x": "1211", + "y": "1623", + "properties": { + "curvature": "0", + "leftArrow": "false", + "rightArrow": "false", + "color": "4273622", + "stroke": "dotted", + "p0": { + "x": -0.18181818181824383, + "y": 0 + }, + "p1": { + "x": 0.4999578668592739, + "y": 0.00035566936975390943 + }, + "p2": { + "x": -0.18181818181824383, + "y": 73.08703041995386 + } + } + }, + { + "ID": "2934", + "typeID": "Arrow", + "zOrder": "13", + "w": "202", + "h": "169", + "measuredW": "150", + "measuredH": "100", + "x": "1345", + "y": "1700", + "properties": { + "curvature": "0", + "leftArrow": "false", + "rightArrow": "false", + "color": "4273622", + "p0": { + "x": 0.4407532602174342, + "y": -0.33922541684933094 + }, + "p1": { + "x": 0.5377224186047156, + "y": 0.2397621873145367 + }, + "p2": { + "x": 202.5, + "y": 168.5 + } + } + }, + { + "ID": "2947", + "typeID": "Arrow", + "zOrder": "12", + "w": "1", + "h": "114", + "measuredW": "150", + "measuredH": "100", + "x": "1701", + "y": "1756", + "properties": { + "curvature": "0", + "leftArrow": "false", + "rightArrow": "false", + "color": "4273622", + "p0": { + "x": -0.18181818181824383, + "y": 0 + }, + "p1": { + "x": 0.4999578668592739, + "y": 0.0003556693697539093 + }, + "p2": { + "x": -0.18181818181824383, + "y": 113.97948286209976 + }, + "stroke": "dotted" + } + }, + { + "ID": "2948", + "typeID": "Arrow", + "zOrder": "11", + "w": "1", + "h": "80", + "measuredW": "150", + "measuredH": "100", + "x": "1701", + "y": "1623", + "properties": { + "curvature": "0", + "leftArrow": "false", + "rightArrow": "false", + "color": "4273622", + "stroke": "dotted", + "p0": { + "x": -0.18181818181824383, + "y": 0 + }, + "p1": { + "x": 0.4999578668592739, + "y": 0.00035566936975390927 + }, + "p2": { + "x": -0.18181818181824383, + "y": 79.5 + } + } + }, + { + "ID": "2949", + "typeID": "Arrow", + "zOrder": "10", + "w": "184", + "h": "147", + "measuredW": "150", + "measuredH": "100", + "x": "1361", + "y": "1879", + "properties": { + "curvature": "0", + "leftArrow": "false", + "rightArrow": "false", + "color": "4273622", + "p0": { + "x": 183.5, + "y": -0.03666724399795385 + }, + "p1": { + "x": 0.4528877147224164, + "y": 0.2228100131869359 + }, + "p2": { + "x": 0, + "y": 146.5 + } + } + }, + { + "ID": "2956", + "typeID": "Arrow", + "zOrder": "9", + "w": "1", + "h": "114", + "measuredW": "150", + "measuredH": "100", + "x": "1233", + "y": "1912", + "properties": { + "curvature": "0", + "leftArrow": "false", + "rightArrow": "false", + "color": "4273622", + "p0": { + "x": -0.18181818181824383, + "y": 0 + }, + "p1": { + "x": 0.4999578668592739, + "y": 0.0003556693697539093 + }, + "p2": { + "x": -0.18181818181824383, + "y": 113.97948286209976 + }, + "stroke": "dotted" + } + }, + { + "ID": "2957", + "typeID": "Arrow", + "zOrder": "8", + "w": "127", + "h": "1", + "measuredW": "150", + "measuredH": "100", + "x": "984", + "y": "2024", + "properties": { + "curvature": "0", + "leftArrow": "false", + "rightArrow": "false", + "color": "4273622", + "p0": { + "x": -0.4746082422041127, + "y": 0.362673214497363 + }, + "p1": { + "x": 0.49995786685927396, + "y": 0.00035566936975390927 + }, + "p2": { + "x": 126.69373677187127, + "y": 0.362673214497363 + } + } + }, + { + "ID": "2960", + "typeID": "Arrow", + "zOrder": "7", + "w": "1", + "h": "151", + "measuredW": "150", + "measuredH": "100", + "x": "797", + "y": "1960", + "properties": { + "curvature": "0", + "leftArrow": "false", + "rightArrow": "false", + "color": "4273622", + "stroke": "dotted", + "p0": { + "x": 0, + "y": 0 + }, + "p1": { + "x": 0.5016483571549873, + "y": -0.00045943399456992786 + }, + "p2": { + "x": 0, + "y": 151 + } + } + }, + { + "ID": "2961", + "typeID": "Arrow", + "zOrder": "6", + "w": "1", + "h": "151", + "measuredW": "150", + "measuredH": "100", + "x": "937", + "y": "1960", + "properties": { + "curvature": "0", + "leftArrow": "false", + "rightArrow": "false", + "color": "4273622", + "stroke": "dotted", + "p0": { + "x": 0, + "y": 0 + }, + "p1": { + "x": 0.5016483571549873, + "y": -0.00045943399456992786 + }, + "p2": { + "x": 0, + "y": 151 + } + } + }, + { + "ID": "2971", + "typeID": "Arrow", + "zOrder": "5", + "h": "1", + "measuredW": "150", + "measuredH": "100", + "x": "658", + "y": "2024", + "properties": { + "curvature": "0", + "leftArrow": "false", + "rightArrow": "false", + "color": "4273622", + "p0": { + "x": 0.16382818454974313, + "y": 0.362673214497363 + }, + "p1": { + "x": 0.4999578668592739, + "y": 0.0003556693697539094 + }, + "p2": { + "x": 149.69373677187127, + "y": 0.362673214497363 + } + } + }, + { + "ID": "2972", + "typeID": "Arrow", + "zOrder": "101", + "w": "1", + "h": "175", + "measuredW": "150", + "measuredH": "100", + "x": "657", + "y": "2025", + "properties": { + "curvature": "0", + "leftArrow": "false", + "rightArrow": "false", + "color": "4273622", + "p0": { + "x": -0.18181818181824383, + "y": 0 + }, + "p1": { + "x": 0.4999578668592739, + "y": 0.0003556693697539095 + }, + "p2": { + "x": -0.18181818181824383, + "y": 175 + } + } + }, + { + "ID": "2975", + "typeID": "Arrow", + "zOrder": "4", + "w": "519", + "h": "1", + "measuredW": "150", + "measuredH": "100", + "x": "658", + "y": "2200", + "properties": { + "curvature": "0", + "leftArrow": "false", + "rightArrow": "false", + "color": "4273622", + "p0": { + "x": 0.16382818454974313, + "y": 0.362673214497363 + }, + "p1": { + "x": 0.4999578668592739, + "y": 0.0003556693697539094 + }, + "p2": { + "x": 518.6666666666667, + "y": 0.3626732144975904 + } + } + }, + { + "ID": "2984", + "typeID": "Arrow", + "zOrder": "3", + "w": "1", + "h": "105", + "measuredW": "150", + "measuredH": "100", + "x": "861", + "y": "2204", + "properties": { + "curvature": "0", + "leftArrow": "false", + "rightArrow": "false", + "color": "4273622", + "stroke": "dotted", + "p0": { + "x": 0, + "y": 0 + }, + "p1": { + "x": 0.5016483571549873, + "y": -0.0004594339945699278 + }, + "p2": { + "x": 0, + "y": 105 + } + } + }, + { + "ID": "2987", + "typeID": "Arrow", + "zOrder": "2", + "w": "1", + "h": "85", + "measuredW": "150", + "measuredH": "100", + "x": "1213", + "y": "2200", + "properties": { + "curvature": "0", + "leftArrow": "false", + "rightArrow": "false", + "color": "4273622", + "stroke": "dotted", + "p0": { + "x": -0.18181818181824383, + "y": 0 + }, + "p1": { + "x": 0.49995786685927385, + "y": 0.0003556693697539093 + }, + "p2": { + "x": -0.18181818181824383, + "y": 84.66666666666652 + } + } + }, + { + "ID": "2996", + "typeID": "Arrow", + "zOrder": "1", + "w": "340", + "h": "1", + "measuredW": "150", + "measuredH": "100", + "x": "1267", + "y": "2200", + "properties": { + "curvature": "0", + "leftArrow": "false", + "rightArrow": "false", + "color": "4273622", + "p0": { + "x": 0.16382818454974313, + "y": 0.362673214497363 + }, + "p1": { + "x": 0.4999578668592738, + "y": 0.0003556693697539093 + }, + "p2": { + "x": 340.33333333333326, + "y": 0.3626732144975904 + } + } + }, + { + "ID": "2997", + "typeID": "Arrow", + "zOrder": "112", + "w": "1", + "h": "342", + "measuredW": "150", + "measuredH": "100", + "x": "1607", + "y": "2200", + "properties": { + "curvature": "0", + "leftArrow": "false", + "rightArrow": "false", + "color": "4273622", + "p0": { + "x": -0.18181818181824383, + "y": 0 + }, + "p1": { + "x": 0.4999578668592739, + "y": 0.0003556693697539096 + }, + "p2": { + "x": -0.18181818181824383, + "y": 342 + } + } + }, + { + "ID": "2998", + "typeID": "Arrow", + "zOrder": "113", + "w": "441", + "h": "1", + "measuredW": "150", + "measuredH": "100", + "x": "1166", + "y": "2543", + "properties": { + "curvature": "0", + "leftArrow": "false", + "rightArrow": "false", + "color": "4273622", + "p0": { + "x": 0, + "y": 0.3626732144975904 + }, + "p1": { + "x": 0.49995786685927374, + "y": 0.00035566936975390954 + }, + "p2": { + "x": 441.33333333333326, + "y": 0.3626732144975904 + } + } + }, + { + "ID": "2999", + "typeID": "Arrow", + "zOrder": "114", + "w": "1", + "h": "161", + "measuredW": "150", + "measuredH": "100", + "x": "1166", + "y": "2544", + "properties": { + "curvature": "0", + "leftArrow": "false", + "rightArrow": "false", + "color": "4273622", + "p0": { + "x": -0.18181818181824383, + "y": 0 + }, + "p1": { + "x": 0.4999578668592739, + "y": 0.00035566936975390965 + }, + "p2": { + "x": -0.18181818181824383, + "y": 161 + } + } + }, + { + "ID": "3000", + "typeID": "Arrow", + "zOrder": "115", + "w": "1", + "h": "81", + "measuredW": "150", + "measuredH": "100", + "x": "1166", + "y": "2729", + "properties": { + "curvature": "0", + "leftArrow": "false", + "rightArrow": "false", + "stroke": "dotted", + "color": "10027263", + "p0": { + "x": 0, + "y": 0 + }, + "p1": { + "x": 0.49999999999999994, + "y": 0 + }, + "p2": { + "x": 0, + "y": 81.09090909090901 + } + } + }, + { + "ID": "3001", + "typeID": "TextArea", + "zOrder": "116", + "w": "438", + "h": "118", + "measuredW": "200", + "measuredH": "140", + "x": "947", + "y": "2643" + }, + { + "ID": "3002", + "typeID": "Label", + "zOrder": "117", + "measuredW": "366", + "measuredH": "25", + "x": "983", + "y": "2662", + "properties": { + "size": "17", + "text": "Continue Learning with following relevant tracks" + } + }, + { + "ID": "3003", + "typeID": "__group__", + "zOrder": "118", + "measuredW": "198", + "measuredH": "44", + "w": "198", + "h": "44", + "x": "1170", + "y": "2699", + "properties": { + "controlName": "ext_link:roadmap.sh/devops" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "198", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16770457" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "141", + "measuredH": "25", + "x": "28", + "y": "9", + "properties": { + "size": "17", + "text": "DevOps Roadmap" + } + } + ] + } + } + }, + { + "ID": "3004", + "typeID": "__group__", + "zOrder": "119", + "measuredW": "198", + "measuredH": "44", + "w": "198", + "h": "44", + "x": "962", + "y": "2699", + "properties": { + "controlName": "ext_link:roadmap.sh/backend" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "198", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16770457" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "147", + "measuredH": "25", + "x": "25", + "y": "9", + "properties": { + "size": "17", + "text": "Backend Roadmap" + } + } + ] + } + } + }, + { + "ID": "3005", + "typeID": "Arrow", + "zOrder": "120", + "w": "45", + "h": "1", + "measuredW": "150", + "measuredH": "100", + "x": "613", + "y": "1387", + "properties": { + "curvature": "0", + "leftArrow": "false", + "rightArrow": "false", + "color": "16777215", + "p0": { + "x": 0.04142925695464328, + "y": 0.362673214497363 + }, + "p1": { + "x": 0.49995786685927407, + "y": 0.0003556693697539088 + }, + "p2": { + "x": 45.203968575995304, + "y": 0.362673214497363 + } + } + }, + { + "ID": "3006", + "typeID": "Arrow", + "zOrder": "121", + "w": "45", + "h": "1", + "measuredW": "150", + "measuredH": "100", + "x": "1754", + "y": "1371", + "properties": { + "curvature": "0", + "leftArrow": "false", + "rightArrow": "false", + "color": "16777215", + "p0": { + "x": 0.04142925695464328, + "y": 0.362673214497363 + }, + "p1": { + "x": 0.49995786685927407, + "y": 0.0003556693697539088 + }, + "p2": { + "x": 45.203968575995304, + "y": 0.362673214497363 + } + } + }, + { + "ID": "3007", + "typeID": "Arrow", + "zOrder": "122", + "w": "169", + "h": "1", + "measuredW": "150", + "measuredH": "100", + "x": "1081", + "y": "2882", + "properties": { + "curvature": "0", + "leftArrow": "false", + "rightArrow": "false", + "stroke": "dotted", + "color": "16777215", + "p0": { + "x": 0, + "y": 0 + }, + "p1": { + "x": 0.4999999999999999, + "y": 0 + }, + "p2": { + "x": 168.6400000000001, + "y": 0 + } + } + }, + { + "ID": "3008", + "typeID": "__group__", + "zOrder": "37", + "measuredW": "298", + "measuredH": "50", + "w": "298", + "h": "50", + "x": "1065", + "y": "909", + "properties": { + "controlName": "100-introduction" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "298", + "h": "50", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16776960" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "93", + "measuredH": "25", + "x": "102", + "y": "12", + "properties": { + "size": "17", + "text": "Introduction" + } + } + ] + } + } + }, + { + "ID": "3009", + "typeID": "__group__", + "zOrder": "58", + "measuredW": "298", + "measuredH": "50", + "w": "298", + "h": "50", + "x": "1065", + "y": "1081", + "properties": { + "controlName": "101-underlying-technologies" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "298", + "h": "50", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16776960" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "189", + "measuredH": "25", + "x": "54", + "y": "12", + "properties": { + "size": "17", + "text": "Underlying Technologies" + } + } + ] + } + } + }, + { + "ID": "3010", + "typeID": "__group__", + "zOrder": "69", + "measuredW": "298", + "measuredH": "50", + "w": "298", + "h": "50", + "x": "1065", + "y": "1249", + "properties": { + "controlName": "102-installation-setup" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "298", + "h": "50", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16776960" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "145", + "measuredH": "25", + "x": "76", + "y": "12", + "properties": { + "size": "17", + "text": "Installation / Setup" + } + } + ] + } + } + }, + { + "ID": "3011", + "typeID": "__group__", + "zOrder": "77", + "measuredW": "298", + "measuredH": "50", + "w": "298", + "h": "50", + "x": "1065", + "y": "1304", + "properties": { + "controlName": "103-docker-basics" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "298", + "h": "50", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16776960" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "131", + "measuredH": "25", + "x": "83", + "y": "13", + "properties": { + "size": "17", + "text": "Basics of Docker" + } + } + ] + } + } + }, + { + "ID": "3012", + "typeID": "__group__", + "zOrder": "72", + "measuredW": "298", + "measuredH": "50", + "w": "298", + "h": "50", + "x": "1076", + "y": "1423", + "properties": { + "controlName": "104-data-persistence" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "298", + "h": "50", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16776960" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "132", + "measuredH": "25", + "x": "83", + "y": "12", + "properties": { + "size": "17", + "text": "Data Persistence" + } + } + ] + } + } + }, + { + "ID": "3013", + "typeID": "__group__", + "zOrder": "76", + "measuredW": "340", + "measuredH": "50", + "w": "340", + "h": "50", + "x": "633", + "y": "1423", + "properties": { + "controlName": "105-using-third-party-images" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "340", + "h": "50", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16776960" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "260", + "measuredH": "25", + "x": "40", + "y": "12", + "properties": { + "size": "17", + "text": "Using 3rd Party Container Images" + } + } + ] + } + } + }, + { + "ID": "3014", + "typeID": "__group__", + "zOrder": "81", + "measuredW": "338", + "measuredH": "50", + "w": "338", + "h": "50", + "x": "633", + "y": "1671", + "properties": { + "controlName": "106-building-container-images" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "338", + "h": "50", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16776960" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "205", + "measuredH": "25", + "x": "66", + "y": "12", + "properties": { + "size": "17", + "text": "Building Container Images" + } + } + ] + } + } + }, + { + "ID": "3015", + "typeID": "__group__", + "zOrder": "85", + "measuredW": "298", + "measuredH": "50", + "w": "298", + "h": "50", + "x": "1076", + "y": "1672", + "properties": { + "controlName": "107-container-registries" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "298", + "h": "50", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16776960" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "159", + "measuredH": "25", + "x": "69", + "y": "12", + "properties": { + "size": "17", + "text": "Container Registries" + } + } + ] + } + } + }, + { + "ID": "3016", + "typeID": "__group__", + "zOrder": "89", + "measuredW": "298", + "measuredH": "50", + "w": "298", + "h": "50", + "x": "1460", + "y": "1842", + "properties": { + "controlName": "108-running-containers" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "298", + "h": "50", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16776960" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "153", + "measuredH": "25", + "x": "72", + "y": "12", + "properties": { + "size": "17", + "text": "Running Containers" + } + } + ] + } + } + }, + { + "ID": "3017", + "typeID": "__group__", + "zOrder": "93", + "measuredW": "298", + "measuredH": "50", + "w": "298", + "h": "50", + "x": "1089", + "y": "2000", + "properties": { + "controlName": "109-container-security" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "298", + "h": "50", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16776960" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "142", + "measuredH": "25", + "x": "78", + "y": "12", + "properties": { + "size": "17", + "text": "Container Security" + } + } + ] + } + } + }, + { + "ID": "3018", + "typeID": "__group__", + "zOrder": "96", + "measuredW": "267", + "measuredH": "50", + "w": "267", + "h": "50", + "x": "735", + "y": "2000", + "properties": { + "controlName": "110-docker-cli" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "267", + "h": "50", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16776960" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "87", + "measuredH": "25", + "x": "90", + "y": "12", + "properties": { + "size": "17", + "text": "Docker CLI" + } + } + ] + } + } + }, + { + "ID": "3019", + "typeID": "__group__", + "zOrder": "102", + "measuredW": "265", + "measuredH": "50", + "w": "265", + "h": "50", + "x": "737", + "y": "2176", + "properties": { + "controlName": "111-developer-experience" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "265", + "h": "50", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16776960" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "173", + "measuredH": "25", + "x": "46", + "y": "12", + "properties": { + "size": "17", + "text": "Developer Experience" + } + } + ] + } + } + }, + { + "ID": "3020", + "typeID": "__group__", + "zOrder": "107", + "measuredW": "265", + "measuredH": "50", + "w": "265", + "h": "50", + "x": "1089", + "y": "2176", + "properties": { + "controlName": "112-deploying-containers" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "265", + "h": "50", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16776960" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "166", + "measuredH": "25", + "x": "42", + "y": "12", + "properties": { + "size": "17", + "text": "Deploying Containers" + } + } + ] + } + } + }, + { + "ID": "3021", + "typeID": "__group__", + "zOrder": "54", + "measuredW": "299", + "measuredH": "44", + "w": "299", + "h": "44", + "x": "1484", + "y": "836", + "properties": { + "controlName": "100-introduction:what-are-containers" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "299", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16770457" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "167", + "measuredH": "25", + "x": "66", + "y": "9", + "properties": { + "size": "17", + "text": "What are Containers?" + } + } + ] + } + } + }, + { + "ID": "3022", + "typeID": "__group__", + "zOrder": "55", + "measuredW": "299", + "measuredH": "44", + "w": "299", + "h": "44", + "x": "1484", + "y": "887", + "properties": { + "controlName": "101-introduction:need-for-containers" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "299", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16770457" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "223", + "measuredH": "25", + "x": "38", + "y": "9", + "properties": { + "size": "17", + "text": "Why do we need Containers?" + } + } + ] + } + } + }, + { + "ID": "3023", + "typeID": "__group__", + "zOrder": "56", + "measuredW": "299", + "measuredH": "44", + "w": "299", + "h": "44", + "x": "1484", + "y": "937", + "properties": { + "controlName": "102-introduction:bare-metal-vm-containers" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "299", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16770457" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "254", + "measuredH": "25", + "x": "23", + "y": "9", + "properties": { + "size": "17", + "text": "Bare Metal vs VMs vs Containers" + } + } + ] + } + } + }, + { + "ID": "3024", + "typeID": "__group__", + "zOrder": "57", + "measuredW": "299", + "measuredH": "44", + "w": "299", + "h": "44", + "x": "1484", + "y": "987", + "properties": { + "controlName": "103-introduction:docker-and-oci" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "299", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16770457" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "124", + "measuredH": "25", + "x": "88", + "y": "9", + "properties": { + "size": "17", + "text": "Docker and OCI" + } + } + ] + } + } + }, + { + "ID": "3025", + "typeID": "__group__", + "zOrder": "65", + "measuredW": "182", + "measuredH": "44", + "w": "182", + "h": "44", + "x": "1484", + "y": "1079", + "properties": { + "controlName": "100-underlying-technologies:namespaces" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "182", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16770457" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "102", + "measuredH": "25", + "x": "40", + "y": "9", + "properties": { + "size": "17", + "text": "Namespaces" + } + } + ] + } + } + }, + { + "ID": "3026", + "typeID": "__group__", + "zOrder": "66", + "measuredW": "107", + "measuredH": "44", + "w": "107", + "h": "44", + "x": "1674", + "y": "1079", + "properties": { + "controlName": "101-underlying-technologies:cgroups" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "107", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16770457" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "63", + "measuredH": "25", + "x": "22", + "y": "9", + "properties": { + "size": "17", + "text": "cgroups" + } + } + ] + } + } + }, + { + "ID": "3027", + "typeID": "__group__", + "zOrder": "67", + "measuredW": "299", + "measuredH": "44", + "w": "299", + "h": "44", + "x": "1484", + "y": "1128", + "properties": { + "controlName": "102-underlying-technologies:union-filesystems" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "299", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16770457" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "140", + "measuredH": "25", + "x": "80", + "y": "9", + "properties": { + "size": "17", + "text": "Union Filesystems" + } + } + ] + } + } + }, + { + "ID": "3028", + "typeID": "__group__", + "zOrder": "70", + "measuredW": "316", + "measuredH": "44", + "w": "316", + "h": "44", + "x": "1476", + "y": "1247", + "properties": { + "controlName": "100-installation-setup:docker-desktop" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "316", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16770457" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "281", + "measuredH": "25", + "x": "21", + "y": "10", + "properties": { + "size": "17", + "text": "Docker Desktop ( Win / Mac / Linux)" + } + } + ] + } + } + }, + { + "ID": "3029", + "typeID": "__group__", + "zOrder": "71", + "measuredW": "316", + "measuredH": "44", + "w": "316", + "h": "44", + "x": "1476", + "y": "1296", + "properties": { + "controlName": "101-installation-setup:docker-engine" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "316", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16770457" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "181", + "measuredH": "25", + "x": "71", + "y": "10", + "properties": { + "size": "17", + "text": "Docker Engine ( Linux )" + } + } + ] + } + } + }, + { + "ID": "3030", + "typeID": "__group__", + "zOrder": "73", + "measuredW": "309", + "measuredH": "44", + "w": "309", + "h": "44", + "x": "1483", + "y": "1401", + "properties": { + "controlName": "100-data-persistence:ephemeral-container-fs" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "309", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16770457" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "242", + "measuredH": "25", + "x": "34", + "y": "10", + "properties": { + "size": "17", + "text": "Ephemeral container filesystem" + } + } + ] + } + } + }, + { + "ID": "3031", + "typeID": "__group__", + "zOrder": "74", + "measuredW": "152", + "measuredH": "44", + "w": "152", + "h": "44", + "x": "1483", + "y": "1450", + "properties": { + "controlName": "101-data-persistence:volume-mounts" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "152", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16770457" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "118", + "measuredH": "25", + "x": "17", + "y": "10", + "properties": { + "size": "17", + "text": "Volume Mounts" + } + } + ] + } + } + }, + { + "ID": "3032", + "typeID": "__group__", + "zOrder": "75", + "measuredW": "152", + "measuredH": "44", + "w": "152", + "h": "44", + "x": "1640", + "y": "1451", + "properties": { + "controlName": "102-data-persistence:bind-mounts" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "152", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16770457" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "97", + "measuredH": "25", + "x": "27", + "y": "9", + "properties": { + "size": "17", + "text": "Bind Mounts" + } + } + ] + } + } + }, + { + "ID": "3034", + "typeID": "__group__", + "zOrder": "78", + "measuredW": "272", + "measuredH": "44", + "w": "272", + "h": "44", + "x": "633", + "y": "1501", + "properties": { + "controlName": "100-using-third-party-images:databases" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "272", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16770457" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "83", + "measuredH": "25", + "x": "94", + "y": "10", + "properties": { + "size": "17", + "text": "Databases" + } + } + ] + } + } + }, + { + "ID": "3035", + "typeID": "__group__", + "zOrder": "79", + "measuredW": "272", + "measuredH": "44", + "w": "272", + "h": "44", + "x": "633", + "y": "1549", + "properties": { + "controlName": "101-using-third-party-images:interactive-test-environments" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "272", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16770457" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "228", + "measuredH": "25", + "x": "22", + "y": "10", + "properties": { + "size": "17", + "text": "Interactive Test Environments" + } + } + ] + } + } + }, + { + "ID": "3036", + "typeID": "__group__", + "zOrder": "80", + "measuredW": "272", + "measuredH": "44", + "w": "272", + "h": "44", + "x": "633", + "y": "1597", + "properties": { + "controlName": "102-using-third-party-images:command-line-utilities" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "272", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16770457" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "179", + "measuredH": "25", + "x": "46", + "y": "10", + "properties": { + "size": "17", + "text": "Command Line Utilities" + } + } + ] + } + } + }, + { + "ID": "3037", + "typeID": "__group__", + "zOrder": "82", + "measuredW": "272", + "measuredH": "44", + "w": "272", + "h": "44", + "x": "633", + "y": "1746", + "properties": { + "controlName": "100-building-container-images:dockerfiles" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "272", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16770457" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "86", + "measuredH": "25", + "x": "93", + "y": "10", + "properties": { + "size": "17", + "text": "Dockerfiles" + } + } + ] + } + } + }, + { + "ID": "3038", + "typeID": "__group__", + "zOrder": "83", + "measuredW": "272", + "measuredH": "44", + "w": "272", + "h": "44", + "x": "633", + "y": "1794", + "properties": { + "controlName": "101-building-container-images:efficient-layer-caching" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "272", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16770457" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "168", + "measuredH": "25", + "x": "52", + "y": "10", + "properties": { + "size": "17", + "text": "Efficient layer caching" + } + } + ] + } + } + }, + { + "ID": "3039", + "typeID": "__group__", + "zOrder": "84", + "measuredW": "272", + "measuredH": "44", + "w": "272", + "h": "44", + "x": "633", + "y": "1842", + "properties": { + "controlName": "102-building-container-images:image-size-and-security" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "272", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16770457" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "182", + "measuredH": "25", + "x": "45", + "y": "10", + "properties": { + "size": "17", + "text": "Image size and security" + } + } + ] + } + } + }, + { + "ID": "3040", + "typeID": "__group__", + "zOrder": "86", + "measuredW": "272", + "measuredH": "44", + "w": "272", + "h": "44", + "x": "1089", + "y": "1597", + "properties": { + "controlName": "100-container-registries:dockerhub" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "272", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16770457" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "84", + "measuredH": "25", + "x": "94", + "y": "10", + "properties": { + "size": "17", + "text": "Dockerhub" + } + } + ] + } + } + }, + { + "ID": "3041", + "typeID": "__group__", + "zOrder": "87", + "measuredW": "272", + "measuredH": "44", + "w": "272", + "h": "44", + "x": "1089", + "y": "1549", + "properties": { + "controlName": "101-container-registries:dockerhub-alt" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "272", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16770457" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "231", + "measuredH": "25", + "x": "20", + "y": "10", + "properties": { + "size": "17", + "text": "Others (ghcr, ecr, gcr, act, etc)" + } + } + ] + } + } + }, + { + "ID": "3042", + "typeID": "__group__", + "zOrder": "88", + "measuredW": "272", + "measuredH": "44", + "w": "272", + "h": "44", + "x": "1089", + "y": "1501", + "properties": { + "controlName": "102-container-registries:image-tagging-best-practices" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "272", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16770457" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "231", + "measuredH": "25", + "x": "20", + "y": "9", + "properties": { + "size": "17", + "text": "Image Tagging Best Practices" + } + } + ] + } + } + }, + { + "ID": "3043", + "typeID": "__group__", + "zOrder": "90", + "measuredW": "174", + "measuredH": "44", + "w": "174", + "h": "44", + "x": "1615", + "y": "1728", + "properties": { + "controlName": "100-running-containers:docker-run" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "174", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16770457" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "83", + "measuredH": "25", + "x": "45", + "y": "9", + "properties": { + "size": "17", + "text": "docker run" + } + } + ] + } + } + }, + { + "ID": "3044", + "typeID": "__group__", + "zOrder": "91", + "measuredW": "174", + "measuredH": "44", + "w": "174", + "h": "44", + "x": "1615", + "y": "1680", + "properties": { + "controlName": "101-running-containers:docker-compose" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "174", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16770457" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "129", + "measuredH": "25", + "x": "22", + "y": "9", + "properties": { + "size": "17", + "text": "docker compose" + } + } + ] + } + } + }, + { + "ID": "3045", + "typeID": "__group__", + "zOrder": "92", + "measuredW": "273", + "measuredH": "44", + "w": "273", + "h": "44", + "x": "1517", + "y": "1598", + "properties": { + "controlName": "102-running-containers:runtime-config-options" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "273", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16770457" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "236", + "measuredH": "25", + "x": "20", + "y": "9", + "properties": { + "size": "17", + "text": "Runtime Configuration Options" + } + } + ] + } + } + }, + { + "ID": "3046", + "typeID": "__group__", + "zOrder": "94", + "measuredW": "219", + "measuredH": "44", + "w": "219", + "h": "44", + "x": "1124", + "y": "1892", + "properties": { + "controlName": "100-container-security:image-security" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "219", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16770457" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "116", + "measuredH": "25", + "x": "52", + "y": "9", + "properties": { + "size": "17", + "text": "Image Security" + } + } + ] + } + } + }, + { + "ID": "3047", + "typeID": "__group__", + "zOrder": "95", + "measuredW": "219", + "measuredH": "44", + "w": "219", + "h": "44", + "x": "1124", + "y": "1844", + "properties": { + "controlName": "101-container-security:runtime-security" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "219", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16770457" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "131", + "measuredH": "25", + "x": "44", + "y": "9", + "properties": { + "size": "17", + "text": "Runtime Security" + } + } + ] + } + } + }, + { + "ID": "3048", + "typeID": "__group__", + "zOrder": "97", + "measuredW": "122", + "measuredH": "44", + "w": "122", + "h": "44", + "x": "737", + "y": "1926", + "properties": { + "controlName": "100-docker-cli:images" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "122", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16770457" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "58", + "measuredH": "25", + "x": "32", + "y": "9", + "properties": { + "size": "17", + "text": "Images" + } + } + ] + } + } + }, + { + "ID": "3049", + "typeID": "__group__", + "zOrder": "98", + "measuredW": "126", + "measuredH": "44", + "w": "126", + "h": "44", + "x": "875", + "y": "1926", + "properties": { + "controlName": "101-docker-cli:containers" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "126", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16770457" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "85", + "measuredH": "25", + "x": "20", + "y": "9", + "properties": { + "size": "17", + "text": "Containers" + } + } + ] + } + } + }, + { + "ID": "3050", + "typeID": "__group__", + "zOrder": "99", + "measuredW": "122", + "measuredH": "44", + "w": "122", + "h": "44", + "x": "737", + "y": "2081", + "properties": { + "controlName": "102-docker-cli:volumes" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "122", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16770457" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "65", + "measuredH": "25", + "x": "28", + "y": "9", + "properties": { + "size": "17", + "text": "Volumes" + } + } + ] + } + } + }, + { + "ID": "3051", + "typeID": "__group__", + "zOrder": "100", + "measuredW": "126", + "measuredH": "44", + "w": "126", + "h": "44", + "x": "875", + "y": "2081", + "properties": { + "controlName": "102-docker-cli:networks" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "126", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16770457" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "72", + "measuredH": "25", + "x": "27", + "y": "9", + "properties": { + "size": "17", + "text": "Networks" + } + } + ] + } + } + }, + { + "ID": "3052", + "typeID": "__group__", + "zOrder": "103", + "measuredW": "219", + "measuredH": "44", + "w": "219", + "h": "44", + "x": "752", + "y": "2272", + "properties": { + "controlName": "100-developer-experience:hot-reloading" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "219", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16770457" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "110", + "measuredH": "25", + "x": "55", + "y": "9", + "properties": { + "size": "17", + "text": "Hot Reloading" + } + } + ] + } + } + }, + { + "ID": "3053", + "typeID": "__group__", + "zOrder": "104", + "measuredW": "219", + "measuredH": "44", + "w": "219", + "h": "44", + "x": "752", + "y": "2320", + "properties": { + "controlName": "101-developer-experience:debuggers" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "219", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16770457" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "86", + "measuredH": "25", + "x": "67", + "y": "9", + "properties": { + "size": "17", + "text": "Debuggers" + } + } + ] + } + } + }, + { + "ID": "3054", + "typeID": "__group__", + "zOrder": "105", + "measuredW": "219", + "measuredH": "44", + "w": "219", + "h": "44", + "x": "752", + "y": "2368", + "properties": { + "controlName": "102-developer-experience:tests" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "219", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16770457" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "41", + "measuredH": "25", + "x": "89", + "y": "9", + "properties": { + "size": "17", + "text": "Tests" + } + } + ] + } + } + }, + { + "ID": "3055", + "typeID": "__group__", + "zOrder": "106", + "measuredW": "219", + "measuredH": "44", + "w": "219", + "h": "44", + "x": "752", + "y": "2416", + "properties": { + "controlName": "103-developer-experience:continuous-integration" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "219", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16770457" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "176", + "measuredH": "25", + "x": "22", + "y": "9", + "properties": { + "size": "17", + "text": "Continuous Integration" + } + } + ] + } + } + }, + { + "ID": "3056", + "typeID": "__group__", + "zOrder": "108", + "measuredW": "219", + "measuredH": "44", + "w": "219", + "h": "44", + "x": "1102", + "y": "2272", + "properties": { + "controlName": "100-deploying-containers:paas-options" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "219", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16770457" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "104", + "measuredH": "25", + "x": "58", + "y": "9", + "properties": { + "size": "17", + "text": "PaaS Options" + } + } + ] + } + } + }, + { + "ID": "3057", + "typeID": "__group__", + "zOrder": "109", + "measuredW": "219", + "measuredH": "44", + "w": "219", + "h": "44", + "x": "1102", + "y": "2320", + "properties": { + "controlName": "101-deploying-containers:kubernetes" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "219", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16770457" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "90", + "measuredH": "25", + "x": "65", + "y": "9", + "properties": { + "size": "17", + "text": "Kubernetes" + } + } + ] + } + } + }, + { + "ID": "3058", + "typeID": "__group__", + "zOrder": "110", + "measuredW": "219", + "measuredH": "44", + "w": "219", + "h": "44", + "x": "1102", + "y": "2368", + "properties": { + "controlName": "102-deploying-containers:docker-swarm" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "219", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16770457" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "111", + "measuredH": "25", + "x": "54", + "y": "9", + "properties": { + "size": "17", + "text": "Docker Swarm" + } + } + ] + } + } + }, + { + "ID": "3059", + "typeID": "__group__", + "zOrder": "111", + "measuredW": "219", + "measuredH": "44", + "w": "219", + "h": "44", + "x": "1102", + "y": "2416", + "properties": { + "controlName": "103-deploying-containers:nomad" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "TextArea", + "zOrder": "0", + "w": "219", + "h": "44", + "measuredW": "200", + "measuredH": "140", + "x": "0", + "y": "0", + "properties": { + "color": "16770457" + } + }, + { + "ID": "1", + "typeID": "Label", + "zOrder": "1", + "measuredW": "56", + "measuredH": "25", + "x": "77", + "y": "9", + "properties": { + "size": "17", + "text": "Nomad" + } + } + ] + } + } + }, + { + "ID": "3060", + "typeID": "__group__", + "zOrder": "62", + "measuredW": "70", + "measuredH": "25", + "w": "70", + "h": "25", + "x": "693", + "y": "669", + "properties": { + "controlName": "ext_link:twitter.com/sidpalas" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "Label", + "zOrder": "0", + "measuredW": "70", + "measuredH": "25", + "x": "0", + "y": "0", + "properties": { + "size": "17", + "text": "{color:purple}Sid Palas{color}" + } + } + ] + } + } + }, + { + "ID": "3061", + "typeID": "__group__", + "zOrder": "64", + "measuredW": "268", + "measuredH": "25", + "w": "268", + "h": "25", + "x": "659", + "y": "697", + "properties": { + "controlName": "ext_link:courses.devopsdirective.com/docker-beginner-to-pro" + }, + "children": { + "controls": { + "control": [ + { + "ID": "0", + "typeID": "Label", + "zOrder": "0", + "measuredW": "268", + "measuredH": "25", + "x": "0", + "y": "0", + "properties": { + "size": "17", + "text": "{color:purple}course covering this topic in depth.{color}" + } + } + ] + } + } + }, + { + "ID": "3063", + "typeID": "Canvas", + "zOrder": "0", + "w": "327", + "h": "393", + "measuredW": "100", + "measuredH": "70", + "x": "635", + "y": "892" + } + ] + }, + "attributes": { + "name": "New Wireframe 9 copy 5", + "order": 1000147.9446306123, + "parentID": null, + "notes": null + }, + "branchID": "Master", + "resourceID": "A3B84AD1-CEAB-4958-B7C6-199A90A297E8", + "mockupH": "2283", + "mockupW": "1186", + "measuredW": "1799", + "measuredH": "2883", + "version": "1.0" + }, + "groupOffset": { + "x": 0, + "y": 0 + }, + "dependencies": [], + "projectID": "file:///Users/kamranahmed/Desktop/AWS%20Roadmap.bmpr" +} \ No newline at end of file diff --git a/public/pdfs/roadmaps/docker.pdf b/public/pdfs/roadmaps/docker.pdf new file mode 100644 index 000000000..233930744 Binary files /dev/null and b/public/pdfs/roadmaps/docker.pdf differ diff --git a/public/roadmaps/docker.png b/public/roadmaps/docker.png new file mode 100644 index 000000000..a3cddad81 Binary files /dev/null and b/public/roadmaps/docker.png differ diff --git a/src/data/roadmaps/docker/content/100-introduction/100-what-are-containers.md b/src/data/roadmaps/docker/content/100-introduction/100-what-are-containers.md index 71842ddf0..8b572f330 100644 --- a/src/data/roadmaps/docker/content/100-introduction/100-what-are-containers.md +++ b/src/data/roadmaps/docker/content/100-introduction/100-what-are-containers.md @@ -13,15 +13,4 @@ Unlike traditional virtualization, which emulates a complete operating system wi ## Containers and Docker -Docker is a platform that simplifies the process of creating, deploying, and managing containers. It provides developers and administrators with a set of tools and APIs to manage containerized applications. With Docker, you can build and package application code, libraries, and dependencies into a container image, which can be distributed and run consistently in any environment that supports Docker. - -Some key components of the Docker platform include: - -- **Docker Engine**: The core component responsible for building, shipping, and running containerized applications. -- **Docker Images**: Read-only templates that contain the application code, runtime, libraries, and all necessary dependencies. -- **Docker Containers**: Instances of Docker Images that run the packaged application in isolated environments. -- **Docker Hub**: A public registry that hosts Docker images, allowing developers to share and distribute their containerized applications. - -## Recap - -Containers provide a lightweight, portable, and consistent way to package and deploy applications. They help in reducing the complexities associated with managing dependencies, improving resource efficiency, and simplifying application management. Docker is a popular platform that makes it easy to create and manage containers in various environments, providing a consistent and efficient solution for modern application development and deployment. \ No newline at end of file +Docker is a platform that simplifies the process of creating, deploying, and managing containers. It provides developers and administrators with a set of tools and APIs to manage containerized applications. With Docker, you can build and package application code, libraries, and dependencies into a container image, which can be distributed and run consistently in any environment that supports Docker. \ No newline at end of file diff --git a/src/data/roadmaps/docker/content/100-introduction/101-need-for-containers.md b/src/data/roadmaps/docker/content/100-introduction/101-need-for-containers.md index ddf169e7d..910ac811e 100644 --- a/src/data/roadmaps/docker/content/100-introduction/101-need-for-containers.md +++ b/src/data/roadmaps/docker/content/100-introduction/101-need-for-containers.md @@ -1,8 +1,6 @@ # Need for Containers -In the world of software development and deployment, consistency and efficiency are crucial. Before containers came into the picture, developers often faced challenges when deploying applications across different environments. Here, we discuss the need for containers and why they have become essential in modern software development. - -### Challenges with Traditional Deployment Methods +In the world of software development and deployment, consistency and efficiency are crucial. Before containers came into the picture, developers often faced challenges when deploying applications across different environments including: - **Inconsistent environments:** Developers often work in different environments which might have different configurations and libraries compared to production servers. This leads to compatibility issues in deploying applications. @@ -10,7 +8,7 @@ In the world of software development and deployment, consistency and efficiency - **Slow processes and scalability issues:** Traditional deployment methods have a slower time to market and scaling difficulties, which hinders fast delivery of software updates. -### How Containers Address These Challenges +How Containers Address These Challenges is as follows: - **Consistent environment:** Containers solve environment inconsistencies by bundling an application and its dependencies, configurations, and libraries into a single container. This guarantees that the application runs smoothly across different environments. @@ -18,6 +16,4 @@ In the world of software development and deployment, consistency and efficiency - **Faster processes and scalability:** Containers can be easily created, destroyed, and replaced, leading to faster development and deployment cycles. Scaling applications becomes easier as multiple containers can be deployed without consuming significant resources. -Overall, containers have become an essential tool for organizations that want to respond quickly to market changes, improve resource efficiency, and ensure reliable and consistent software delivery. They have revolutionized modern software development practices and have long-lasting impact in the world of deployment and application management. - -In the following sections of this guide, we will explore more about containers, and especially focus on Docker, a leading container platform. \ No newline at end of file +Overall, containers have become an essential tool for organizations that want to respond quickly to market changes, improve resource efficiency, and ensure reliable and consistent software delivery. They have revolutionized modern software development practices and have long-lasting impact in the world of deployment and application management. \ No newline at end of file diff --git a/src/data/roadmaps/docker/content/100-introduction/102-bare-metal-vm-containers.md b/src/data/roadmaps/docker/content/100-introduction/102-bare-metal-vm-containers.md index c89180094..75a13216c 100644 --- a/src/data/roadmaps/docker/content/100-introduction/102-bare-metal-vm-containers.md +++ b/src/data/roadmaps/docker/content/100-introduction/102-bare-metal-vm-containers.md @@ -1,7 +1,19 @@ -# Bare Metal VM Containers +# Bare Metal vs VM vs Containers -In this section, we will discuss **bare metal VM containers**, which are virtual machines running directly on the hardware without a hypervisor. This type of container provides better performance compared to traditional virtualization methods, as it eliminates the overhead typically associated with hypervisors. +Here is a quick overview of the differences between bare metal, virtual machines, and containers. -## How bare metal VM containers work +## Bare Metal -Bare metal VM containers, also known as container runtimes, are designed to run multiple isolated operating system instances directly on the host's hardware, without the need for a \ No newline at end of file +Bare metal is a term used to describe a computer that is running directly on the hardware without any virtualization. This is the most performant way to run an application, but it is also the least flexible. You can only run one application per server, and you cannot easily move the application to another server. + +## Virtual Machines + +Virtual machines (VMs) are a way to run multiple applications on a single server. Each VM runs on top of a hypervisor, which is a piece of software that emulates the hardware of a computer. The hypervisor allows you to run multiple operating systems on a single server, and it also provides isolation between applications running on different VMs. + +## Containers + +Containers are a way to run multiple applications on a single server without the overhead of a hypervisor. Each container runs on top of a container engine, which is a piece of software that emulates the operating system of a computer. The container engine allows you to run multiple applications on a single server, and it also provides isolation between applications running on different containers. + +You can learn more from the following resources: + +- [History of Virtualization](https://courses.devopsdirective.com/docker-beginner-to-pro/lessons/01-history-and-motivation/03-history-of-virtualization) \ No newline at end of file diff --git a/src/data/roadmaps/docker/content/100-introduction/103-docker-and-oci.md b/src/data/roadmaps/docker/content/100-introduction/103-docker-and-oci.md index 32aa227b7..581190b0b 100644 --- a/src/data/roadmaps/docker/content/100-introduction/103-docker-and-oci.md +++ b/src/data/roadmaps/docker/content/100-introduction/103-docker-and-oci.md @@ -1,9 +1,5 @@ # Docker and OCI -In this section, we will discuss the relationship between Docker and the Open Container Initiative (OCI), as well as the important role they play in the container ecosystem. - -### Open Container Initiative - The [Open Container Initiative (OCI)](https://opencontainers.org/) is a Linux Foundation project which aims at creating industry standards for container formats and runtimes. Its primary goal is to ensure the compatibility and interoperability of container environments through defined technical specifications. ### Docker's role in OCI @@ -22,6 +18,4 @@ OCI has two main specifications: Docker remains committed to supporting the OCI specifications and, since its involvement in OCI, has continuously updated its software to be compliant with OCI standards. Docker's containerd runtime and image format are fully compatible with OCI specifications, enabling Docker containers to be run by other OCI-compliant container runtimes and vice versa. -### Conclusion - In summary, Docker and the Open Container Initiative work together to maintain standardization and compatibility within the container industry. Docker has played a significant role in the development of the OCI specifications, ensuring that the container ecosystem remains healthy, interoperable, and accessible to a wide range of users and platforms across the industry. \ No newline at end of file diff --git a/src/data/roadmaps/docker/content/100-introduction/index.md b/src/data/roadmaps/docker/content/100-introduction/index.md index 37750f0dc..8eb202ddd 100644 --- a/src/data/roadmaps/docker/content/100-introduction/index.md +++ b/src/data/roadmaps/docker/content/100-introduction/index.md @@ -1,26 +1,3 @@ -# Introduction - -In this introductory section, we will discuss the basics of Docker, a powerful platform used by developers and system administrators to simplify the deployment and management of applications within containers. This guide aims to provide a clear understanding of Docker's key concepts, its benefits, and how it can improve your application development and deployment process. - ## What is Docker? -Docker is an open-source platform that automates the deployment, scaling, and management of applications by isolating them into lightweight, portable containers. Containers are standalone executable units that encapsulate all necessary dependencies, libraries, and configuration files required for an application to run consistently across various environments. - -## Why Use Docker? - -- **Consistent environments:** Docker containers ensure a consistent environment for both development and production, eliminating the "works on my machine" problem. -- **Isolation and security:** Containers isolate applications from each other, reducing security risks and simplifying dependency management. -- **Portability:** Containerized applications can be effortlessly moved across environments and platforms. -- **Scalability:** Docker makes it easy to create and manage multiple instances of an application, simplifying scaling and load balancing. -- **Resource-efficient:** Containers share the host operating system's resources, making them more efficient than traditional virtual machines. - -## Key Components - -- **Docker Engine:** The core component responsible for building and running containers. -- **Docker Images:** Immutable snapshots of the container's file system, serving as a blueprint for creating a container. -- **Docker Containers:** Running instances of Docker images, which can be started, stopped, and restarted. -- **Dockerfile:** A text file containing instructions to build a Docker image from scratch or modify an existing one. -- **Docker Volumes:** A way to persist data across container restarts and share data between containers. -- **Docker Compose:** A tool for defining and running multi-container Docker applications using a YAML configuration file. - -Throughout this guide, we will dive deeper into these concepts and explore various use-cases of Docker, helping you become proficient in containerization and application deployment. So, let's get started! \ No newline at end of file +Docker is an open-source platform that automates the deployment, scaling, and management of applications by isolating them into lightweight, portable containers. Containers are standalone executable units that encapsulate all necessary dependencies, libraries, and configuration files required for an application to run consistently across various environments. \ No newline at end of file diff --git a/src/data/roadmaps/docker/content/101-underlying-technologies/102-union-filesystems.md b/src/data/roadmaps/docker/content/101-underlying-technologies/102-union-filesystems.md index 5ef8ac751..63b3be6de 100644 --- a/src/data/roadmaps/docker/content/101-underlying-technologies/102-union-filesystems.md +++ b/src/data/roadmaps/docker/content/101-underlying-technologies/102-union-filesystems.md @@ -1,12 +1,6 @@ # Union Filesystems -Union filesystems, also known as UnionFS, play a crucial role in the overall functioning of Docker. In this section, we will discuss what union filesystems are and how they contribute to the seamless operation of Docker containers. - -## Overview - -A union filesystem is a unique type of filesystem that creates a virtual, layered file structure by overlaying multiple directories. Instead of modifying the original file system or merging directories, UnionFS enables the simultaneous mounting of multiple directories on a single mount point while keeping their contents separate. This feature is especially beneficial in the context of Docker, as it allows us to manage and optimize storage performance by minimizing duplication and reducing the container image size. - -## Key Features of Union Filesystems +Union filesystems, also known as UnionFS, play a crucial role in the overall functioning of Docker. It's a unique type of filesystem that creates a virtual, layered file structure by overlaying multiple directories. Instead of modifying the original file system or merging directories, UnionFS enables the simultaneous mounting of multiple directories on a single mount point while keeping their contents separate. This feature is especially beneficial in the context of Docker, as it allows us to manage and optimize storage performance by minimizing duplication and reducing the container image size. These are some of the essential features of union filesystems: @@ -25,8 +19,4 @@ Docker supports multiple union filesystems that facilitate building and managing - [**AUFS (Advanced Multi-Layered Unification Filesystem)**](http://aufs.sourceforge.net/): AUFS is widely used as a Docker storage driver, enabling efficient management of multiple layers. - [**OverlayFS (Overlay Filesystem)**](https://www.kernel.org/doc/html/latest/filesystems/overlayfs.html): OverlayFS is another union filesystem supported by Docker. It uses a simplified approach compared to AUFS to create and manage overlayed directories. - [**Btrfs (B-Tree Filesystem)**](https://btrfs.wiki.kernel.org/index.php/Main_Page): Btrfs, a modern file system, offers compatibility with union filesystems in addition to advanced storage features like snapshots and checksumming. -- [**ZFS (Z File System)**](https://zfsonlinux.org/): ZFS is a high-capacity and robust storage platform that provides union filesystem features along with data protection, compression, and deduplication. - -## Conclusion - -Union filesystems play an integral role in the Docker ecosystem, enabling the creation of layered structures that facilitate efficient container operations, storage management, and optimization. By understanding the underlying technologies and concepts, such as layered organization and copy-on-write, you can effectively harness the power of union filesystems to manage and optimize container images. \ No newline at end of file +- [**ZFS (Z File System)**](https://zfsonlinux.org/): ZFS is a high-capacity and robust storage platform that provides union filesystem features along with data protection, compression, and deduplication. \ No newline at end of file diff --git a/src/data/roadmaps/docker/content/101-underlying-technologies/index.md b/src/data/roadmaps/docker/content/101-underlying-technologies/index.md index 9cfdb6aeb..b91d21210 100644 --- a/src/data/roadmaps/docker/content/101-underlying-technologies/index.md +++ b/src/data/roadmaps/docker/content/101-underlying-technologies/index.md @@ -1,6 +1,6 @@ # Underlying Technologies -In this section, we will discuss the core technologies that power Docker. Understanding these technologies will provide you with a deeper insight into how Docker works and will help you use the platform more effectively. +Understanding the core technologies that power Docker will provide you with a deeper insight into how Docker works and will help you use the platform more effectively. ## Linux Containers (LXC) @@ -17,13 +17,3 @@ UnionFS is a file system service that allows the overlaying of multiple file sys ## Namespaces Namespaces are another Linux kernel feature that provides process isolation. They allow Docker to create isolated workspaces called containers. Namespaces ensure that processes within a container cannot interfere with processes outside the container or on the host system. There are several types of namespaces, like PID, NET, MNT, and USER, each responsible for isolating a different aspect of a process. - -## Docker Engine - -Docker Engine is the core component that builds and runs containers. It is a lightweight runtime and management tool that communicates with the Linux kernel using an API to create and operate containers. Docker Engine understands both Dockerfile instructions and Docker commands. - -## Docker Hub - -Docker Hub is a cloud-based registry service that allows users to store and share Docker images. This centralized repository is used to distribute existing pre-built images and to share custom-built images with other developers. Public and private repositories are available on Docker Hub, depending on your needs. - -In summary, Docker's underlying technologies like LXC, cgroups, UnionFS, and namespaces work together to provide a lightweight, flexible, and consistent environment for deploying applications. Understanding these core technologies will enable you to harness the full power of Docker in your development workflow. \ No newline at end of file diff --git a/src/data/roadmaps/docker/content/102-installation-setup/100-docker-desktop.md b/src/data/roadmaps/docker/content/102-installation-setup/100-docker-desktop.md index 309395e63..396678521 100644 --- a/src/data/roadmaps/docker/content/102-installation-setup/100-docker-desktop.md +++ b/src/data/roadmaps/docker/content/102-installation-setup/100-docker-desktop.md @@ -25,12 +25,8 @@ To install Docker Desktop on your machine, follow these steps: ``` If the installation was successful, the command should output the Docker version information. -### Getting Started +Learn more from the following resources: -After installing Docker Desktop, you can start using Docker right away. Here are a few resources to help you get started: - -- [Docker Desktop Documentation](https://docs.docker.com/desktop/): Official documentation for Docker Desktop, including installation instructions and product features. -- [Docker Get Started Guide](https://docs.docker.com/get-started/): A beginner-friendly tutorial that covers the basics of Docker and how to use it to build, share, and run containerized applications. -- [Docker Hub](https://hub.docker.com/): A repository of Docker images that can be downloaded and used in your own projects. Docker Hub is also integrated directly into Docker Desktop for easy access. - -Now that you have a basic understanding of Docker Desktop, you can continue exploring its features and benefits as a part of your Docker learning journey. Happy containerizing! \ No newline at end of file +- [Docker Desktop Documentation](https://docs.docker.com/desktop/) +- [Docker Get Started Guide](https://docs.docker.com/get-started/) +- [Docker Hub](https://hub.docker.com/) \ No newline at end of file diff --git a/src/data/roadmaps/docker/content/102-installation-setup/101-docker-engine.md b/src/data/roadmaps/docker/content/102-installation-setup/101-docker-engine.md index 99b50b2b2..753a06eaa 100644 --- a/src/data/roadmaps/docker/content/102-installation-setup/101-docker-engine.md +++ b/src/data/roadmaps/docker/content/102-installation-setup/101-docker-engine.md @@ -1,27 +1,14 @@ # Docker Engine -Docker Engine is the core component of the Docker platform which allows you to build, ship, and run applications and services in containers. It is a lightweight runtime and a powerful building tool that is designed to simplify the task of application development and deployment. +There is often confusion between "Docker Desktop" and "Docker Engine". Docker Engine refers specifically to a subset of the Docker Desktop components which are free and open source and can be installed only on Linux. -### Docker Engine Components +Docker Engine includes: -The Docker Engine consists of three main components: +- Docker Command Line Interface (CLI) +- Docker daemon (dockerd), exposing the Docker Application Programming Interface (API) -- **Docker Daemon (dockerd)**: This is the main part of the Docker Engine that is responsible for running and managing containers on your host server. It listens for Docker API requests and creates, starts, stops, or removes containers. +Docker Engine can build container images, run containers from them, and generally do most things that Docker Desktop but is Linux only and doesn't provide all of the developer experience polish that Docker Desktop provides. -- **Docker REST API**: Docker Engine exposes an API that allows you to interact with the Docker Daemon. This powerful interface allows you to interact with the Docker system, control container behavior, and access various Docker features using any programming language or application capable of sending HTTP requests. +For more information about docker engine see: -- **Docker CLI (Command Line Interface)**: The Docker CLI is a command-line tool that provides a convenient and user-friendly way to interact with the Docker REST API. Using the Docker CLI, you can issue commands to build, start, stop, and manage containers, networks, and volumes, among other things. - -### Docker Engine Editions - -Docker Engine comes in two main editions, each catering to the specific needs of different developers and organizations: - -- **Community Edition (CE)**: This edition is designed for individual developers and small teams who want to get started with Docker in their environment. It offers the essential features for building and running containers and is available for free use. - -- **Enterprise Edition (EE)**: This edition is designed for large organizations and offers more features, including advanced security, enhanced management, and support. It is available as a subscription-based service, with various support tiers to meet the needs of different organization sizes and requirements. - -### Platforms and Architectures - -Docker Engine is available for various platforms and architectures, making it an excellent choice for cross-platform development and deployment. The most common platforms supported by Docker Engine include Linux distributions (such as Ubuntu, CentOS, and Red Hat Enterprise Linux), Windows Server, and macOS. - -By leveraging the Docker Engine, you can ensure a consistent development environment and a predictable deployment experience, regardless of the underlying infrastructure. This flexibility and portability are among the main reasons why Docker has become such a popular choice among developers and IT professionals. \ No newline at end of file +- [Docker Engine - Docker Documentation](https://docs.docker.com/engine/) \ No newline at end of file diff --git a/src/data/roadmaps/docker/content/102-installation-setup/index.md b/src/data/roadmaps/docker/content/102-installation-setup/index.md index 6c9a6dbe1..38fe69274 100644 --- a/src/data/roadmaps/docker/content/102-installation-setup/index.md +++ b/src/data/roadmaps/docker/content/102-installation-setup/index.md @@ -1,61 +1,6 @@ # Installation Setup -In this section, we'll discuss the necessary steps to setup Docker on your machine. We'll cover the installation process for various platforms including Windows, macOS, and Linux. +Docker provides a desktop application called **Docker Desktop** that simplifies the installation and setup process. There is also another option to install using the **Docker Engine**. -### Windows - -If you are using Windows, Docker provides a desktop application called **Docker Desktop** that simplifies the installation and setup process. Here are the steps to install Docker Desktop on Windows: - -- Download the installer from the official [Docker Desktop website](https://www.docker.com/products/docker-desktop). -- Run the installer and follow the on-screen instructions. -- Restart your computer after the installation is complete. -- Launch Docker Desktop from the Start menu. - -_NOTE: Docker Desktop requires Windows 10 Pro, Enterprise or Education edition._ - -### macOS - -For macOS users, Docker also provides a desktop application called **Docker Desktop** which makes the installation and setup process hassle-free. Follow these steps to install Docker Desktop on macOS: - -- Download the installer from the official [Docker Desktop website](https://www.docker.com/products/docker-desktop). -- Open the downloaded `.dmg` file and follow the on-screen instructions. -- After successfully installing the application, launch "Docker Desktop" from the Applications folder. - -### Linux - -Linux users can install Docker using their respective package manager. Below, we'll provide installation instructions for some popular distributions. For other distributions, refer to the [official Docker documentation](https://docs.docker.com/engine/install/). - -#### Ubuntu - -Run the following commands in the terminal to install Docker on Ubuntu: - -```bash -sudo apt-get update -sudo apt-get install docker.io -``` - -#### Fedora - -Install Docker on Fedora using the `dnf` command: - -```bash -sudo dnf update -sudo dnf install docker -``` - -#### CentOS - -To install Docker on CentOS, run the following commands: - -```bash -sudo yum update -sudo yum install docker -``` - -### Post-Installation Steps - -After successfully installing Docker, it's essential to perform some post-installation steps to manage Docker as a non-root user and ensure that it starts on system boot. - -For Linux users, follow the [post-installation steps](https://docs.docker.com/engine/install/linux-postinstall/) provided in the official Docker documentation. - -Windows and macOS users can configure Docker Desktop settings, such as memory and CPU allocation, by right-clicking the Docker icon in the system tray and selecting "Preferences" or "Settings". \ No newline at end of file +- [Docker Desktop website](https://www.docker.com/products/docker-desktop). +- [Docker Engine](https://docs.docker.com/engine/install/). \ No newline at end of file diff --git a/src/data/roadmaps/docker/content/103-docker-basics.md b/src/data/roadmaps/docker/content/103-docker-basics.md index 1c6be9d4e..ab938ba09 100644 --- a/src/data/roadmaps/docker/content/103-docker-basics.md +++ b/src/data/roadmaps/docker/content/103-docker-basics.md @@ -2,11 +2,11 @@ Docker is a platform that simplifies the process of building, packaging, and deploying applications in lightweight, portable containers. In this section, we'll cover the basics of Docker, its components, and key commands you'll need to get started. -#### What is a Container? +## What is a Container? A container is a lightweight, standalone, and executable software package that includes all the dependencies (libraries, binaries, and configuration files) required to run an application. Containers isolate applications from their environment, ensuring they work consistently across different systems. -#### Docker Components +## Docker Components There are three key components in the Docker ecosystem: @@ -14,19 +14,15 @@ There are three key components in the Docker ecosystem: - **Docker Image**: A snapshot of a container, created from a Dockerfile. Images are stored in a registry, like Docker Hub, and can be pulled or pushed to the registry. - **Docker Container**: A running instance of a Docker image. -#### Docker Commands +## Docker Commands Below are some essential Docker commands you'll use frequently: - `docker pull `: Download an image from a registry, like Docker Hub. - `docker build -t `: Build an image from a Dockerfile, where `` is the directory containing the Dockerfile. -- `docker images`: List all images available on your local machine. +- `docker image ls`: List all images available on your local machine. - `docker run -d -p : --name `: Run a container from an image, mapping host ports to container ports. -- `docker ps`: List all running containers. -- `docker stop `: Stop a running container. -- `docker rm `: Remove a stopped container. -- `docker rmi `: Remove an image from your local machine. - -#### Conclusion - -In this section, we covered the basics of Docker, including containers, components, and essential commands. With this foundation, you can begin building and deploying applications using Docker. Make sure to consult the [official Docker documentation](https://docs.docker.com/) for comprehensive information and best practices. \ No newline at end of file +- `docker container ls`: List all running containers. +- `docker container stop `: Stop a running container. +- `docker container rm `: Remove a stopped container. +- `docker image rm `: Remove an image from your local machine. \ No newline at end of file diff --git a/src/data/roadmaps/docker/content/104-data-persistence/100-ephemeral-container-fs.md b/src/data/roadmaps/docker/content/104-data-persistence/100-ephemeral-container-fs.md index e3700f911..54aa8a231 100644 --- a/src/data/roadmaps/docker/content/104-data-persistence/100-ephemeral-container-fs.md +++ b/src/data/roadmaps/docker/content/104-data-persistence/100-ephemeral-container-fs.md @@ -1,7 +1,3 @@ -# Ephemeral Container FS - -In this section, we'll discuss the concept of **Ephemeral Container File System (FS)** and its implications on data persistence in Docker. - ### Ephemeral FS By default, the storage within a Docker container is ephemeral, meaning that any data changes or modifications made inside a container will only persist as long as the container is running. Once the container is stopped and removed, all the associated data will be lost. This is because Docker containers are designed to be stateless by nature. @@ -18,10 +14,4 @@ To overcome these challenges, Docker provides several methods for data persisten - **Bind mounts**: Mapping a host machine's directory or file into a container, effectively sharing host's storage with the container. - **tmpfs mounts**: In-memory storage, useful for cases where just the persistence of data within the life-cycle of the container is required. -By implementing these strategies, Docker ensures that application data can be preserved beyond the life-cycle of a single container, making it possible to work with stateful applications. - -### Key Takeaways - -- "Ephemeral Container FS" refers to the temporary and short-lived storage within a Docker container. -- By default, any data stored within the container's ephemeral FS is lost when the container is stopped or removed. -- Docker provides options like volumes, bind mounts, and tmpfs mounts to ensure data persistence beyond a container's life-cycle. \ No newline at end of file +By implementing these strategies, Docker ensures that application data can be preserved beyond the life-cycle of a single container, making it possible to work with stateful applications. \ No newline at end of file diff --git a/src/data/roadmaps/docker/content/104-data-persistence/101-volume-mounts.md b/src/data/roadmaps/docker/content/104-data-persistence/101-volume-mounts.md index 561e3830e..d6112fd58 100644 --- a/src/data/roadmaps/docker/content/104-data-persistence/101-volume-mounts.md +++ b/src/data/roadmaps/docker/content/104-data-persistence/101-volume-mounts.md @@ -1,62 +1,58 @@ # Volume Mounts -Volume mounts are a key feature in Docker that helps in managing and persisting data generated by and used by containers. In this section, we will discuss the concept of volume mounts and how to use them with Docker containers. - -### What are Volume Mounts - Volume mounts are a way to map a folder or file on the host system to a folder or file inside a container. This allows the data to persist outside the container even when the container is removed. Additionally, multiple containers can share the same volume, making data sharing between containers easy. -### Creating a Volume +## Creating a Volume To create a volume in Docker, you need to run the following command: -``` +```bash docker volume create my-volume ``` This command will create a volume named `my-volume`. You can inspect the details of the created volume using the command: -``` +```bash docker volume inspect my-volume ``` -### Mounting a Volume in a Container +## Mounting a Volume in a Container To mount a volume to a container, you need to use the `-v` or `--mount` flag while running the container. Here's an example: Using `-v` flag: -``` +```bash docker run -d -v my-volume:/data your-image ``` Using `--mount` flag: -``` +```bash docker run -d --mount source=my-volume,destination=/data your-image ``` In both examples above, `my-volume` is the name of the volume we created earlier, and `/data` is the path inside the container where the volume will be mounted. -### Sharing Volumes Between Containers +## Sharing Volumes Between Containers To share a volume between multiple containers, simply mount the same volume on multiple containers. Here's how to share `my-volume` between two containers running different images: -``` +```bash docker run -d -v my-volume:/data1 image1 docker run -d -v my-volume:/data2 image2 ``` In this example, `image1` and `image2` would have access to the same data stored in `my-volume`. -### Removing a Volume +## Removing a Volume To remove a volume, you can use the `docker volume rm` command followed by the volume name: -``` +```bash docker volume rm my-volume ``` -**Note**: Removing a volume will delete all the data stored inside the volume. Make sure to backup the data beforehand. +That's it! Now you have a basic understanding of volume mounts in Docker. You can use them to persist and share data between your containers efficiently and securely. -That's it! Now you have a basic understanding of volume mounts in Docker. You can use them to persist and share data between your containers efficiently and securely. \ No newline at end of file +- [Docker Volumes](https://docs.docker.com/storage/volumes/). \ No newline at end of file diff --git a/src/data/roadmaps/docker/content/104-data-persistence/102-bind-mounts.md b/src/data/roadmaps/docker/content/104-data-persistence/102-bind-mounts.md index 77243d266..f2cb84f6e 100644 --- a/src/data/roadmaps/docker/content/104-data-persistence/102-bind-mounts.md +++ b/src/data/roadmaps/docker/content/104-data-persistence/102-bind-mounts.md @@ -1,24 +1,9 @@ # Bind Mounts -**Bind mounts** are a powerful and flexible mechanism for data persistence in Docker containers. This type of mount effectively maps a specific directory or file from the host system to a specified location within the container. By doing so, the container can read and write data on the host file system, making it possible to preserve state and transfer data between containers or even different hosts. +Bind mounts have limited functionality compared to volumes. When you use a bind mount, a file or directory on the host machine is mounted into a container. The file or directory is referenced by its absolute path on the host machine. By contrast, when you use a volume, a new directory is created within Docker’s storage directory on the host machine, and Docker manages that directory’s contents. -### How to Use Bind Mounts +The file or directory does not need to exist on the Docker host already. It is created on demand if it does not yet exist. Bind mounts are very performant, but they rely on the host machine’s filesystem having a specific directory structure available. -When creating a new container, bind mounts can be specified using the `-v` or `--volume` option followed by a colon-separated pair of paths. The first path is the source directory or file on the host system, and the second path is the target location within the container. For example: +Learn more about bind mounts here: -``` -docker run -d -v /path/on/host:/path/in/container my-image -``` - -### Advantages of Bind Mounts - -- **Flexibility**: Bind mounts can be used to share entire directories, single files, or specific file system subtrees between the host and the container. -- **Performance**: Since bind mounts don't rely on network file systems, they generally provide better performance, especially for operations that involve heavy file I/O or random access. -- **Ease of use**: By directly mapping host paths into the container, bind mounts offer a simple and familiar way to manage data persistence and sharing between containers. - -### Disadvantages of Bind Mounts - -- **Host file system dependency**: As bind mounts directly rely on the host file system, they introduce tight coupling between the container and the host. This can create issues when attempting to move containers to different hosts or platforms, especially if files and directories have specific ownership or permissions requirements. -- **Security**: By exposing parts of the host file system to the container, bind mounts can introduce potential security risks. It's important to consider the permissions and visibility of the host data you expose to containers. - -While bind mounts are a useful tool for managing container data, they are not the only option available. In some cases, using Docker volumes or other tools and strategies may be a better choice for data persistence. Remember to consider the specific requirements and constraints of your application when deciding on a persistence mechanism. \ No newline at end of file +- [Docker Bind Mounts](https://docs.docker.com/storage/bind-mounts/). \ No newline at end of file diff --git a/src/data/roadmaps/docker/content/105-using-third-party-images/100-databases.md b/src/data/roadmaps/docker/content/105-using-third-party-images/100-databases.md index 2ca28bc8e..369a2ed81 100644 --- a/src/data/roadmaps/docker/content/105-using-third-party-images/100-databases.md +++ b/src/data/roadmaps/docker/content/105-using-third-party-images/100-databases.md @@ -1,91 +1,65 @@ # Using Third Party Images: Databases -Databases are an essential component of many applications and services. In this section, we'll discuss how to use third party images for databases within your Docker projects. - -### Overview - Running your database in a Docker container can help streamline your development process and ease deployment. Docker Hub provides numerous pre-made images for popular databases such as MySQL, PostgreSQL, and MongoDB. ### Example: Using MySQL Image To use a MySQL database, search for the official image on Docker Hub: -``` +```bash docker search mysql ``` Find the official image, and pull it: -``` +```bash docker pull mysql ``` Now, you can run a MySQL container. Specify the required environment variables, such as `MYSQL_ROOT_PASSWORD`, and optionally map the container's port to your host machine: -``` +```bash docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -p 3306:3306 -d mysql ``` This command creates a new container named `some-mysql`, sets the root password to `my-secret-pw`, and maps port 3306 on the host to port 3306 on the container. -To connect to the database from another container, use the `--link` flag: - -``` -docker run --name some-app --link some-mysql:mysql -d my-app -``` - -### Example: Using PostgreSQL Image +## Example: Using PostgreSQL Image For PostgreSQL, follow similar steps to those outlined above. First, search for the official image: -``` +```bash docker search postgres ``` Pull the image: -``` +```bash docker pull postgres ``` Run a PostgreSQL container, specifying environment variables such as `POSTGRES_PASSWORD`: -``` +```bash docker run --name some-postgres -e POSTGRES_PASSWORD=my-secret-pw -p 5432:5432 -d postgres ``` -Link the container to another container to allow communication: - -``` -docker run --name some-app --link some-postgres:postgres -d my-app -``` - ### Example: Using MongoDB Image Running a MongoDB container with Docker follows a similar pattern as previous examples. Search for the official image: -``` +```bash docker search mongo ``` Pull the image: -``` +```bash docker pull mongo ``` Run a MongoDB container: -``` +```bash docker run --name some-mongo -p 27017:27017 -d mongo -``` - -Link the container to another container: - -``` -docker run --name some-app --link some-mongo:mongo -d my-app -``` - -### Conclusion - -Docker makes it easy to use third-party images for databases, streamlining your development process and ensuring a consistent environment for your applications. This guide demonstrated examples of using MySQL, PostgreSQL, and MongoDB, but many other database images are available on Docker Hub. \ No newline at end of file +``` \ No newline at end of file diff --git a/src/data/roadmaps/docker/content/105-using-third-party-images/101-interactive-test-environments.md b/src/data/roadmaps/docker/content/105-using-third-party-images/101-interactive-test-environments.md index 7f6cf2938..ab91f584b 100644 --- a/src/data/roadmaps/docker/content/105-using-third-party-images/101-interactive-test-environments.md +++ b/src/data/roadmaps/docker/content/105-using-third-party-images/101-interactive-test-environments.md @@ -1,14 +1,10 @@ # Interactive Test Environments with Docker -In this section, we will discuss how to use Docker for setting up interactive test environments. Interactive test environments are useful when you want to explore and test software in isolated, controlled spaces without affecting your local machine. - -## Why use Docker for Interactive Test Environments? - Docker allows you to create isolated, disposable environments that can be deleted once you're done with testing. This makes it much easier to work with third party software, test different dependencies or versions, and quickly experiment without the risk of damaging your local setup. ## Creating an Interactive Test Environment with Docker -To demonstrate how to setup an interactive test environment, let's use the popular Python programming language as an example. We will use a public Python image available on [Docker Hub](https://hub.docker.com/_/python). +To demonstrate how to setup an interactive test environment, let's use the Python programming language as an example. We will use a public Python image available on [Docker Hub](https://hub.docker.com/_/python). - To start an interactive test environment using the Python image, simply run the following command: diff --git a/src/data/roadmaps/docker/content/105-using-third-party-images/102-command-line-utilities.md b/src/data/roadmaps/docker/content/105-using-third-party-images/102-command-line-utilities.md index 9a85ae01d..81a3962a7 100644 --- a/src/data/roadmaps/docker/content/105-using-third-party-images/102-command-line-utilities.md +++ b/src/data/roadmaps/docker/content/105-using-third-party-images/102-command-line-utilities.md @@ -2,13 +2,11 @@ Docker images can include command line utilities or standalone applications that we can run inside containers. This can be really useful when working with third-party images, as the tools we want to use are already packaged and available to be run without any installation or configuration. -In this section, we will be discussing a few examples of command line utilities that are available in Docker images and how we can use them. - ### BusyBox BusyBox is a small (1-2 Mb) and simple command line application that provides a large number of the commonly used Unix utilities, such as `awk`, `grep`, `vi`, etc. To run BusyBox inside a Docker container, you simply need to pull the image and run it with Docker: -``` +```bash docker pull busybox docker run -it busybox /bin/sh ``` @@ -19,7 +17,7 @@ Once inside the container, you can start running various BusyBox utilities just cURL is a well-known command line tool that can be used to transfer data using various network protocols. It is often used for testing APIs or downloading files from the internet. To use cURL inside a Docker container, you can use the official cURL image available on Docker Hub: -``` +```bash docker pull curlimages/curl docker run --rm curlimages/curl https://example.com ``` diff --git a/src/data/roadmaps/docker/content/105-using-third-party-images/index.md b/src/data/roadmaps/docker/content/105-using-third-party-images/index.md index 0a9197e31..9912c719d 100644 --- a/src/data/roadmaps/docker/content/105-using-third-party-images/index.md +++ b/src/data/roadmaps/docker/content/105-using-third-party-images/index.md @@ -1,20 +1,14 @@ # Using Third Party Images -In this section, we'll dive into using third-party images in Docker. Third-party images are pre-built Docker container images that are available on Docker Hub or other container registries. These images are created and maintained by individuals or organizations and can be used as a starting point for your containerized applications. +Third-party images are pre-built Docker container images that are available on Docker Hub or other container registries. These images are created and maintained by individuals or organizations and can be used as a starting point for your containerized applications. -### Benefits of Using Third-Party Images - -- **Time-saving**: Using pre-built images saves time by removing the need to create and configure your own base images. -- **Consistency**: Third-party images help maintain consistent environment configurations across projects and teams. -- **Updated & Secure**: Official images from reputable sources are frequently updated and maintained for security and dependency updates. - -### Finding Third-Party Images +## Finding Third-Party Images [Docker Hub](https://hub.docker.com) is the largest and most popular container image registry containing both official and community-maintained images. You can search for images based on the name or the technology you want to use. For example: If you're looking for a `Node.js` image, you can search for "node" on Docker Hub and you'll find the official Node.js image along with many other community-maintained images. -### Using an Image in Your Dockerfile +## Using an Image in Your Dockerfile To use a third-party image in your Dockerfile, simply set the image name as the base image using the `FROM` directive. Here's an example using the official Node.js image: @@ -24,12 +18,10 @@ FROM node:14 # The rest of your Dockerfile... ``` -### Be Aware of Security Concerns +## Be Aware of Security Concerns Keep in mind that third-party images can potentially have security vulnerabilities or misconfigurations. Always verify the source of the image and check its reputation before using it in production. Prefer using official images or well-maintained community images. -### Maintaining Your Images - -When using third-party images, it's essential to keep them updated to incorporate the latest security updates and dependency changes. Regularly check for updates in your base images and rebuild your application containers accordingly. +## Maintaining Your Images -In summary, using third-party images is a convenient and time-saving approach to building and deploying containers. Ensure that you're using trustworthy and up-to-date images, and always verify their security before deploying them in production environments. \ No newline at end of file +When using third-party images, it's essential to keep them updated to incorporate the latest security updates and dependency changes. Regularly check for updates in your base images and rebuild your application containers accordingly. \ No newline at end of file diff --git a/src/data/roadmaps/docker/content/106-building-container-images/100-dockerfiles.md b/src/data/roadmaps/docker/content/106-building-container-images/100-dockerfiles.md index 6f194216f..1de93588f 100644 --- a/src/data/roadmaps/docker/content/106-building-container-images/100-dockerfiles.md +++ b/src/data/roadmaps/docker/content/106-building-container-images/100-dockerfiles.md @@ -1,22 +1,18 @@ -# Dockerfiles - -In this section, we will discuss Dockerfiles, which are essential for building container images. - -### What is a Dockerfile? +# Dockerfile A Dockerfile is a text document that contains a list of instructions used by the Docker engine to build an image. Each instruction in the Dockerfile adds a new layer to the image. Docker will build the image based on these instructions, and then you can run containers from the image. Dockerfiles are one of the main elements of *infrastructure as code*. -### Structure of a Dockerfile +## Structure of a Dockerfile A Dockerfile is organized in a series of instructions, one per line. Each instruction has a specific format. -``` +```bash INSTRUCTION arguments ``` The following is an example of a simple Dockerfile: -``` +```bash # Use an official Python runtime as a parent image FROM python:3.7-slim @@ -39,7 +35,7 @@ ENV NAME World CMD ["python", "app.py"] ``` -### Common Dockerfile Instructions +## Common Dockerfile Instructions Here's a list of some common Dockerfile instructions and their purpose: @@ -53,14 +49,12 @@ Here's a list of some common Dockerfile instructions and their purpose: - `EXPOSE`: Informs Docker that the container will listen on the specified network ports at runtime. - `ENV`: Sets environment variables for the container. -### Building an Image from a Dockerfile +## Building an Image from a Dockerfile To build an image from the Dockerfile, use the `docker build` command, specifying the build context (usually the current directory), and an optional tag for the image. -``` +```bash docker build -t my-image:tag . ``` -After running this command, Docker will execute each instruction in the Dockerfile, in order, creating a new layer for each. - -Now you have a clear understanding of Dockerfiles, their structure, and their most important instructions. In the next sections, we will discuss how to manage and deploy containerized applications effectively. \ No newline at end of file +After running this command, Docker will execute each instruction in the Dockerfile, in order, creating a new layer for each. \ No newline at end of file diff --git a/src/data/roadmaps/docker/content/106-building-container-images/101-efficient-layer-caching.md b/src/data/roadmaps/docker/content/106-building-container-images/101-efficient-layer-caching.md index 1e9129d69..bdf6c6cdb 100644 --- a/src/data/roadmaps/docker/content/106-building-container-images/101-efficient-layer-caching.md +++ b/src/data/roadmaps/docker/content/106-building-container-images/101-efficient-layer-caching.md @@ -2,13 +2,13 @@ When building container images, Docker caches the newly created layers. These layers can then be used later on when building other images, reducing the build time and minimizing bandwidth usage. However, to make the most of this caching mechanism, you should be aware of how to efficiently use layer caching. -### How Docker Layer Caching Works +## How Docker Layer Caching Works Docker creates a new layer for each instruction (e.g., `RUN`, `COPY`, `ADD`, etc.) in the Dockerfile. If the instruction hasn't changed since the last build, Docker will reuse the existing layer. For example, consider the following Dockerfile: -```docker +```Dockerfile FROM node:14 WORKDIR /app @@ -23,7 +23,7 @@ CMD ["npm", "start"] When you build the image for the first time, Docker will execute each instruction and create a new layer for each of them. If you make some changes to the application and build the image again, Docker will check if the changed instructions affect any of the layers. If none of the layers is affected by the changes, Docker will reuse the cached layers. -### Tips for Efficient Layer Caching +## Tips for Efficient Layer Caching - **Minimize changes in the Dockerfile:** Try to minimize the frequency of changes in your Dockerfile, and structure your instructions in a way that most frequently changed lines appear at the bottom. @@ -35,4 +35,6 @@ When you build the image for the first time, Docker will execute each instructio - **Combine multiple instructions:** In some cases, combining instructions (e.g., `RUN`) can help minimize the number of layers, making caching more efficient. -By following these best practices, you can optimize the layer caching process and reduce the build time for your Docker images, making your development and deployment processes more efficient. \ No newline at end of file +By following these best practices, you can optimize the layer caching process and reduce the build time for your Docker images, making your development and deployment processes more efficient. + +- [Docker Layer Caching](https://docs.docker.com/build/cache/). \ No newline at end of file diff --git a/src/data/roadmaps/docker/content/106-building-container-images/102-image-size-and-security.md b/src/data/roadmaps/docker/content/106-building-container-images/102-image-size-and-security.md index 7a52d9b0a..9ea554373 100644 --- a/src/data/roadmaps/docker/content/106-building-container-images/102-image-size-and-security.md +++ b/src/data/roadmaps/docker/content/106-building-container-images/102-image-size-and-security.md @@ -2,9 +2,7 @@ When building container images, it's essential to be aware of both image size and security. The size of the image affects the speed at which your containers are built and deployed. Smaller images lead to faster builds and reduced network overhead when downloading the image. Security is crucial because container images can contain vulnerabilities that could potentially put your applications at risk. -In this section, we'll discuss some best practices for optimizing image size and improving security when building container images. - -### Reducing Image Size +## Reducing Image Size - **Use an appropriate base image:** Choose a smaller, more lightweight base image that includes only the necessary components for your application. For example, consider using the `alpine` variant of an official image, if available, as it's typically much smaller in size. @@ -28,15 +26,32 @@ In this section, we'll discuss some best practices for optimizing image size and rm -rf /var/lib/apt/lists/* ``` -- **Use `.dockerignore` file:** Add a `.dockerignore` file in your project directory to exclude files and directories that are not required in the container image. +- **Use multi-stage builds:** Use multi-stage builds to create smaller images. Multi-stage builds allow you to use multiple `FROM` statements in your Dockerfile. Each `FROM` statement creates a new stage in the build process. You can copy files from one stage to another using the `COPY --from` statement. + + ```Dockerfile + FROM node:14-alpine AS build + WORKDIR /app + COPY package*.json ./ + RUN npm install + COPY . . + RUN npm run build + + FROM node:14-alpine + WORKDIR /app + COPY --from=build /app/dist ./dist + COPY package*.json ./ + RUN npm install --production + CMD ["npm", "start"] + ``` + +- **Use `.dockerignore` file:** Use a `.dockerignore` file to exclude unnecessary files from the build context that might cause cache invalidation and increase the final image size. ```dockerignore - .git node_modules - logs/ + npm-debug.log ``` -### Enhancing Security +## Enhancing Security - **Keep base images updated:** Regularly update the base images you're using in your Dockerfiles to ensure they include the latest security patches. diff --git a/src/data/roadmaps/docker/content/106-building-container-images/index.md b/src/data/roadmaps/docker/content/106-building-container-images/index.md index 1bdd9b0a4..11e83b06f 100644 --- a/src/data/roadmaps/docker/content/106-building-container-images/index.md +++ b/src/data/roadmaps/docker/content/106-building-container-images/index.md @@ -1,12 +1,12 @@ # Building Container Images -In this section, we will discuss the process of building container images, which are the foundation of Docker containers. Container images are executable packages that include everything required to run an application: code, runtime, system tools, libraries, and settings. By building custom images, you can deploy applications seamlessly with all their dependencies on any Docker-supported platform. +Container images are executable packages that include everything required to run an application: code, runtime, system tools, libraries, and settings. By building custom images, you can deploy applications seamlessly with all their dependencies on any Docker-supported platform. ## Dockerfile The key component in building a container image is the `Dockerfile`. It is essentially a script containing instructions on how to assemble a Docker image. Each instruction in the Dockerfile creates a new layer in the image, making it easier to track changes and minimize the image size. Here's a simple example of a Dockerfile: -``` +```Dockerfile # Use an official Python runtime as a parent image FROM python:3.7-slim @@ -41,10 +41,10 @@ This command tells Docker to build an image using the Dockerfile in the current ## Inspecting Images and Layers -After a successful build, you can inspect the created image using `docker images` command: +After a successful build, you can inspect the created image using `docker image` command: ```sh -docker images +docker image ls ``` To take a closer look at the individual layers of an image, use the `docker history` command: @@ -53,6 +53,19 @@ To take a closer look at the individual layers of an image, use the `docker hist docker history your-image-name ``` +To view the layers of an image, you can also use the `docker inspect` command: + +```sh +docker inspect your-image-name +``` + +To remove an image, use the `docker image rm` command: + +```sh +docker image rm your-image-name +``` + + ## Pushing Images to a Registry Once your image is built, you can push it to a container registry (e.g., Docker Hub, Google Container Registry, etc.) to easily distribute and deploy your application. First, log in to the registry using your credentials: @@ -73,6 +86,4 @@ Finally, push the tagged image to the registry: docker push username/repository:tag ``` -## Conclusion - Building container images is a crucial aspect of using Docker, as it enables you to package and deploy your applications with ease. By creating a Dockerfile with precise instructions, you can effortlessly build and distribute images across various platforms. \ No newline at end of file diff --git a/src/data/roadmaps/docker/content/107-container-registries/100-dockerhub.md b/src/data/roadmaps/docker/content/107-container-registries/100-dockerhub.md index 3a096b171..c23c6d65a 100644 --- a/src/data/roadmaps/docker/content/107-container-registries/100-dockerhub.md +++ b/src/data/roadmaps/docker/content/107-container-registries/100-dockerhub.md @@ -2,7 +2,7 @@ [DockerHub](https://hub.docker.com/) is a cloud-based registry service provided by Docker Inc. It is the default public container registry where you can store, manage, and distribute your Docker images. DockerHub makes it easy for other users to find and use your images or to share their own images with the Docker community. -### Features of DockerHub +## Features of DockerHub - **Public and private repositories:** Store your images in public repositories that are accessible to everyone, or opt for private repositories with access limited to your team or organization. @@ -14,22 +14,20 @@ - **Official Images:** DockerHub provides a curated set of official images for popular software like MongoDB, Node.js, Redis, etc. These images are maintained by Docker Inc. and the upstream software vendor, ensuring that they are up-to-date and secure. -### Getting started with DockerHub - To start using DockerHub, you need to create a free account on their website. Once you've signed up, you can create repositories, manage organizations and teams, and browse the available images. When you're ready to share your own images, you can use the `docker` command line tool to push your local images to DockerHub: ```bash -$ docker login -$ docker tag your-image your-username/your-repository:your-tag -$ docker push your-username/your-repository:your-tag +docker login +docker tag your-image your-username/your-repository:your-tag +docker push your-username/your-repository:your-tag ``` To pull images from DockerHub, you can use the `docker pull` command: ```bash -$ docker pull your-username/your-repository:your-tag +docker pull your-username/your-repository:your-tag ``` DockerHub is essential for distributing and sharing Docker images, making it easier for developers to deploy applications and manage container infrastructure. \ No newline at end of file diff --git a/src/data/roadmaps/docker/content/107-container-registries/102-image-tagging-best-practices.md b/src/data/roadmaps/docker/content/107-container-registries/102-image-tagging-best-practices.md index bcefd9a1a..fcdd724df 100644 --- a/src/data/roadmaps/docker/content/107-container-registries/102-image-tagging-best-practices.md +++ b/src/data/roadmaps/docker/content/107-container-registries/102-image-tagging-best-practices.md @@ -2,36 +2,35 @@ Properly tagging your Docker images is crucial for efficient container management and deployment. In this section, we will discuss some best practices for image tagging. -### 1. Use Semantic Versioning +## Use Semantic Versioning When tagging your image, it is recommended to follow [Semantic Versioning guidelines](https://semver.org/). Semantic versioning is a widely recognized method that can help better maintain your application. Docker image tags should have the following structure `..`. Example: `3.2.1`. -### 2. Tag the Latest Version +## Tag the Latest Version Docker allows you to tag an image as 'latest' in addition to a version number. It is a common practice to tag the most recent stable version of your image as 'latest' so that users can quickly access it without having to specify a version number. However, it is important to keep this tag updated as the new versions are released. ```sh -# Example docker build -t your-username/app-name:latest . ``` -### 3. Be Descriptive and Consistent +## Be Descriptive and Consistent Choose clear and descriptive tag names that convey the purpose of the image or changes from the previous version. Your tags should also be consistent across your images and repositories for better organization and ease of use. -### 4. Include Build and Git Information (Optional) +## Include Build and Git Information (Optional) In some situations, it might be helpful to include information about the build and Git commit in the image tag. This can help identify the source code and environment used for building the image. Example: `app-name-1.2.3-b567-d1234efg`. -### 5. Use Environment and Architecture-Specific Tags +## Use Environment and Architecture-Specific Tags If your application is deployed in different environments (production, staging, development) or has multiple architectures (amd64, arm64), you can use tags that specify these variations. Example: `your-username/app-name:1.2.3-production-amd64`. -### 6. Retag Images When Needed +## Retag Images When Needed Sometimes, you may need to retag an image after it has been pushed to the registry. For example, if you have released a patch for your application, you may want to retag the new patched version with the same tag as the previous version. This allows for smoother application updates and less manual work for users who need to apply the patch. -### 7. Use Automated Build and Tagging Tools +## Use Automated Build and Tagging Tools Consider using CI/CD tools (Jenkins, GitLab CI, Travis-CI) to automate image builds and tagging based on commits, branches, or other rules. This ensures consistency and reduces the likelihood of errors caused by manual intervention. diff --git a/src/data/roadmaps/docker/content/107-container-registries/index.md b/src/data/roadmaps/docker/content/107-container-registries/index.md index 880260f0c..c37aa6ada 100644 --- a/src/data/roadmaps/docker/content/107-container-registries/index.md +++ b/src/data/roadmaps/docker/content/107-container-registries/index.md @@ -2,18 +2,6 @@ A **Container Registry** is a centralized storage and distribution system for Docker container images. It allows developers to easily share and deploy applications in the form of these images. Container registries play a crucial role in the deployment of containerized applications, as they provide a fast, reliable, and secure way to distribute container images across various production environments. -### Key features of Container Registries: - -- **Organizing and Storing Images:** Container registries store and organize container images, allowing developers to quickly and easily access them when required. - -- **Versioning and Tagging:** Container registries support versioning and tagging of images, allowing developers to deploy specific versions of applications and maintain efficient deployment pipelines. - -- **Security and Access Control:** Container registries offer built-in access control mechanisms, ensuring that only authorized users can access and deploy images, thus maintaining security across the application life cycle. - -- **Integration with Continuous Integration (CI) / Continuous Deployment (CD) systems:** Integration of container registries with CI/CD systems streamlines the entire process of building, testing, and deploying containerized applications, making it easier for developers to get code changes into production. - -### Popular Container Registries: - Below is a list of popular container registries available today: - **Docker Hub**: Docker Hub is the default registry for public Docker images and serves as a platform for sharing and distributing images among developers. @@ -22,6 +10,4 @@ Below is a list of popular container registries available today: - **Amazon Elastic Container Registry (ECR)**: Amazon ECR is a fully-managed Docker container registry provided by Amazon Web Services, offering high scalability and performance for storing, managing, and deploying container images. -- **Azure Container Registry (ACR)**: ACR is a managed registry provided by Microsoft Azure, offering Geo-replication, access control, and integration with other Azure services. - -In conclusion, understanding the concept of container registries is essential for deploying and distributing containerized applications efficiently. Adopting container registries streamlines application life cycle management and enhances the overall development and deployment workflow. \ No newline at end of file +- **Azure Container Registry (ACR)**: ACR is a managed registry provided by Microsoft Azure, offering Geo-replication, access control, and integration with other Azure services. \ No newline at end of file diff --git a/src/data/roadmaps/docker/content/108-running-containers/100-docker-run.md b/src/data/roadmaps/docker/content/108-running-containers/100-docker-run.md index 477fc2b46..2ccc7639a 100644 --- a/src/data/roadmaps/docker/content/108-running-containers/100-docker-run.md +++ b/src/data/roadmaps/docker/content/108-running-containers/100-docker-run.md @@ -2,8 +2,6 @@ In this section, we'll discuss the `docker run` command, which enables you to run Docker containers. The `docker run` command creates a new container from the specified image and starts it. -## Basic Syntax - The basic syntax for the `docker run` command is as follows: ```bash @@ -52,5 +50,3 @@ docker run -d --name=my-mysql -e MYSQL_ROOT_PASSWORD=secret -e MYSQL_DATABASE=my ```bash docker run -d --name=my-data -v /path/on/host:/path/in/container some-image ``` - -In summary, using the `docker run` command, you can create and start new containers from images with various options to customize the container's behavior and settings. With a deep understanding of `docker run`, you can successfully deploy and manage your applications using Docker containers. \ No newline at end of file diff --git a/src/data/roadmaps/docker/content/108-running-containers/101-docker-compose.md b/src/data/roadmaps/docker/content/108-running-containers/101-docker-compose.md index 7f11969a1..5c5969134 100644 --- a/src/data/roadmaps/docker/content/108-running-containers/101-docker-compose.md +++ b/src/data/roadmaps/docker/content/108-running-containers/101-docker-compose.md @@ -2,7 +2,7 @@ Docker Compose is a tool for defining and running multi-container Docker applications. It allows you to create, manage, and run your applications using a simple YAML file called `docker-compose.yml`. This file describes your application's services, networks, and volumes, allowing you to easily run and manage your containers using just a single command. -### Features: +Some of the benefits of using Docker Compose include: - **Simplified Container Management:** Docker Compose allows you to define and configure all your services, networks, and volumes in one place, making it easy to manage and maintain. @@ -10,7 +10,7 @@ Docker Compose is a tool for defining and running multi-container Docker applica - **Versioning Support:** Docker Compose files can be versioned for easier compatibility across different versions of the Docker Compose tool itself. -### Creating a Docker Compose File: +## Creating a Docker Compose File: To create a `docker-compose.yml` file, start by specifying the version of Docker Compose you want to use, followed by the services you want to define. Here's an example of a basic `docker-compose.yml` file: @@ -29,7 +29,7 @@ services: In this example, we have specified two services: a web server (`web`) running the latest version of the nginx image, and a database server (`db`) running MySQL. The web server exposes its port 80 to the host machine, and the database server has an environment variable set for the root password. -### Running Docker Compose: +## Running Docker Compose: To run your Docker Compose application, simply navigate to the directory containing your `docker-compose.yml` file and run the following command: @@ -39,7 +39,7 @@ docker-compose up Docker Compose will read the file and start the defined services in the specified order. -### Other Useful Commands: +## Other Useful Commands: - `docker-compose down`: Stops and removes all running containers, networks, and volumes defined in the `docker-compose.yml` file. - `docker-compose ps`: Lists the status of all containers defined in the `docker-compose.yml` file. diff --git a/src/data/roadmaps/docker/content/108-running-containers/102-runtime-config-options.md b/src/data/roadmaps/docker/content/108-running-containers/102-runtime-config-options.md index fcc40d5db..08a39dbc3 100644 --- a/src/data/roadmaps/docker/content/108-running-containers/102-runtime-config-options.md +++ b/src/data/roadmaps/docker/content/108-running-containers/102-runtime-config-options.md @@ -6,13 +6,13 @@ Runtime configuration options allow you to customize the behavior and resources - **CPU:** You can limit the CPU usage of a container with the `--cpus` and `--cpu-shares` options. `--cpus` limits the number of CPU cores a container can use, while `--cpu-shares` assigns relative share of CPU time for the container. - ``` + ```bash docker run --cpus=2 --cpu-shares=512 your-image ``` - **Memory:** You can limit and reserve memory for a container using the `--memory` and `--memory-reservation` options. This can help prevent a container from consuming too many system resources. - ``` + ```bash docker run --memory=1G --memory-reservation=500M your-image ``` @@ -20,13 +20,13 @@ Runtime configuration options allow you to customize the behavior and resources - **User:** By default, containers run as the `root` user. To increase security, you can use the `--user` option to run a container as another user or UID. - ``` + ```bash docker run --user 1000 your-image ``` - **Read-only root file system:** To prevent unwanted changes to the container file system, you can use the `--read-only` option to mount the root file system as read-only. - ``` + ```bash docker run --read-only your-image ``` @@ -34,13 +34,13 @@ Runtime configuration options allow you to customize the behavior and resources - **Publish Ports:** You can use the `--publish` (or `-p`) option to publish a container's ports to the host system. This allows external systems to access the containerized service. - ``` + ```bash docker run -p 80:80 your-image ``` - **Hostname and DNS:** You can customize the hostname and DNS settings of a container using the `--hostname` and `--dns` options. - ``` + ```bash docker run --hostname=my-container --dns=8.8.8.8 your-image ``` diff --git a/src/data/roadmaps/docker/content/108-running-containers/index.md b/src/data/roadmaps/docker/content/108-running-containers/index.md index 00d62a305..2ff1e4dd5 100644 --- a/src/data/roadmaps/docker/content/108-running-containers/index.md +++ b/src/data/roadmaps/docker/content/108-running-containers/index.md @@ -1,18 +1,14 @@ # Running Containers -In this section, we will explore running Docker containers. A container is an isolated environment that runs a single application or a group of applications. Containers are lightweight and portable, allowing for easy sharing and deployment. - -## Starting a New Container - To start a new container, we use the `docker run` command followed by the image name. The basic syntax is as follows: -``` +```bash docker run [options] IMAGE [COMMAND] [ARG...] ``` For example, to run the official Nginx image, we would use: -``` +```bash docker run -d -p 8080:80 nginx ``` @@ -22,15 +18,15 @@ This starts a new container and maps the host's port 8080 to the container's por To list all running containers, use the `docker ps` command. To view all containers (including those that have stopped), use the `-a` flag: -``` -docker ps -a +```bash +docker container ls -a ``` ## Accessing Containers To access a running container's shell, use the `docker exec` command: -``` +```bash docker exec -it CONTAINER_ID bash ``` @@ -40,22 +36,20 @@ Replace `CONTAINER_ID` with the ID or name of your desired container. You can fi To stop a running container, use the `docker stop` command followed by the container ID or name: -``` -docker stop CONTAINER_ID +```bash +docker container stop CONTAINER_ID ``` ## Removing Containers Once a container is stopped, we can remove it using the `docker rm` command followed by the container ID or name: -``` -docker rm CONTAINER_ID +```bash +docker container rm CONTAINER_ID ``` To automatically remove containers when they exit, add the `--rm` flag when running a container: -``` +```bash docker run --rm IMAGE -``` - -In this section, we covered the basics of running Docker containers, including starting, accessing, stopping, and removing containers. Now you can confidently manage containers and build powerful applications using Docker. \ No newline at end of file +``` \ No newline at end of file diff --git a/src/data/roadmaps/docker/content/109-container-security/100-image-security.md b/src/data/roadmaps/docker/content/109-container-security/100-image-security.md index bcd807e34..11106a4d0 100644 --- a/src/data/roadmaps/docker/content/109-container-security/100-image-security.md +++ b/src/data/roadmaps/docker/content/109-container-security/100-image-security.md @@ -2,7 +2,7 @@ Image security is a crucial aspect of deploying Docker containers in your environment. Ensuring the images you use are secure, up to date, and free of vulnerabilities is essential. In this section, we will review best practices and tools for securing and managing your Docker images. -### Use Trusted Image Sources +## Use Trusted Image Sources When pulling images from public repositories, always use trusted, official images as a starting point for your containerized applications. Official images are vetted by Docker and are regularly updated with security fixes. You can find these images on the Docker Hub or other trusted registries. @@ -10,7 +10,7 @@ When pulling images from public repositories, always use trusted, official image When downloading images from other users or creating your own, always verify the source, and inspect the Dockerfile and other provided files to ensure they follow best practices and don't introduce vulnerabilities. -### Keep Images Up-to-Date +## Keep Images Up-to-Date Continuously monitor your images and update them regularly. This helps to minimize exposure to known vulnerabilities, as updates often contain security patches. @@ -20,7 +20,7 @@ You can use the following tools to scan and check for updates to your images: * Anchore: https://anchore.com/ * Clair: https://github.com/quay/clair -### Use Minimal Base Images +## Use Minimal Base Images A minimal base image contains only the bare essentials required to run a containerized application. The fewer components present in the base image, the smaller the attack surface for potential vulnerabilities. @@ -28,11 +28,11 @@ An example of a minimal base image is the Alpine Linux distribution, which is co * Alpine Linux: https://alpinelinux.org/ -### Scan Images for Vulnerabilities +## Scan Images for Vulnerabilities Regularly scan your images for known vulnerabilities using tools like Clair or Anchore. These tools can detect potential risks in your images and container configurations, allowing you to address them before pushing images to a registry or deploying them in production. -### Sign and Verify Images +## Sign and Verify Images To ensure the integrity and authenticity of your images, always sign them using Docker Content Trust (DCT). DCT uses digital signatures to guarantee that the images you pull or push are the ones you expect and haven't been tampered with in transit. @@ -42,7 +42,7 @@ Enable DCT for your Docker environment by setting the following environment vari export DOCKER_CONTENT_TRUST=1 ``` -### Utilize Multi-Stage Builds +## Utilize Multi-Stage Builds Multi-stage builds allow you to use multiple `FROM` instructions within the same Dockerfile. Each stage can have a different base image or set of instructions, but only the final stage determines the final image's content. By using multi-stage builds, you can minimize the size and complexity of your final image, reducing the risk of vulnerabilities. diff --git a/src/data/roadmaps/docker/content/109-container-security/101-runtime-security.md b/src/data/roadmaps/docker/content/109-container-security/101-runtime-security.md index 9504fd95e..483acf6ac 100644 --- a/src/data/roadmaps/docker/content/109-container-security/101-runtime-security.md +++ b/src/data/roadmaps/docker/content/109-container-security/101-runtime-security.md @@ -2,9 +2,7 @@ Runtime security focuses on ensuring the security of Docker containers while they are running in production. This is a critical aspect of container security, as threats may arrive or be discovered after your containers have been deployed. Proper runtime security measures help to minimize the damage that can be done if a vulnerability is exploited. -In this section, we'll discuss some of the key aspects of runtime security, including: - -#### 1. Least Privilege Principle +## Least Privilege Principle Ensure that your containers follow the principle of least privilege, meaning they should only have the minimum permissions necessary to perform their intended functions. This can help to limit the potential damage if a container is compromised. @@ -12,28 +10,28 @@ Ensure that your containers follow the principle of least privilege, meaning the - Avoid running privileged containers, which have access to all of the host's resources. - Use Linux capabilities to strip away unnecessary permissions from your containers. -#### 2. Read-only Filesystems +## Read-only Filesystems By setting your containers' filesystems to read-only, you can prevent attackers from modifying critical files or planting malware inside your containers. - Use the `--read-only` flag when starting your containers to make their filesystems read-only. - Implement volume mounts or `tmpfs` mounts for locations that require write access. -#### 3. Security Scanning and Monitoring +## Security Scanning and Monitoring Ensure that your containers are regularly scanned for vulnerabilities, both in the images themselves and in the runtime environment. - Use container scanning tools to detect and patch vulnerabilities in your images. - Implement runtime monitoring to detect and respond to security events, such as unauthorized access attempts or unexpected process launches. -#### 4. Resource Isolation +## Resource Isolation Isolate your containers' resources, such as CPU, memory, and network, to prevent a single compromised container from affecting other containers or the host system. - Use Docker's built-in resource constraints to limit the resources your containers can consume. - Use network segmentation and firewalls to isolate your containers and limit their communication. -#### 5. Audit Logs +## Audit Logs Maintain audit logs of container activity to help with incident response, troubleshooting, and compliance. diff --git a/src/data/roadmaps/docker/content/109-container-security/index.md b/src/data/roadmaps/docker/content/109-container-security/index.md index 2d03d3903..47ed28d60 100644 --- a/src/data/roadmaps/docker/content/109-container-security/index.md +++ b/src/data/roadmaps/docker/content/109-container-security/index.md @@ -2,20 +2,14 @@ Container security is a critical aspect of implementing and managing container technologies like Docker. It encompasses a set of practices, tools, and technologies designed to protect containerized applications and the infrastructure they run on. In this section, we'll discuss some key container security considerations, best practices, and recommendations. -## Main Topics -- [Container Isolation](#container-isolation) -- [Security Patterns and Practices](#security-patterns-and-practices) -- [Secure Access Controls](#secure-access-controls) -- [Container Vulnerability Management](#container-vulnerability-management) - -### Container Isolation +## Container Isolation Isolation is crucial for ensuring the robustness and security of containerized environments. Containers should be isolated from each other and the host system, to prevent unauthorized access and mitigate the potential damage in case an attacker manages to compromise one container. - **Namespaces**: Docker uses namespace technology to provide isolated environments for running containers. Namespaces restrict what a container can see and access in the broader system, including process and network resources. - **Cgroups**: Control groups (`cgroups`) are used to limit the resources consumed by containers, such as CPU, memory, and I/O. Proper use of `cgroups` aids in preventing DoS attacks and resource exhaustion scenarios. -### Security Patterns and Practices +## Security Patterns and Practices Implementing best practices and specific security patterns during the development, deployment, and operation of containers is essential to maintaining a secure environment. @@ -23,14 +17,14 @@ Implementing best practices and specific security patterns during the developmen - **Immutable Infrastructure**: Containers should be treated as immutable units - once built, they should not be altered. Any change should come by deploying a new container from an updated image. - **Version Control**: Images should be version-controlled and stored in a secure container registry. -### Secure Access Controls +## Secure Access Controls Access controls should be applied to both container management and container data, in order to protect sensitive information and maintain the overall security posture. - **Container Management**: Use Role-Based Access Control (RBAC) to restrict access to container management platforms (e.g., Kubernetes) and ensure that users have only the minimum permissions necessary. - **Container Data**: Encrypt data at rest and in transit, especially when handling sensitive information. -### Container Vulnerability Management +## Container Vulnerability Management Containers can be vulnerable to attacks, as their images depend on a variety of packages and libraries. To mitigate these risks, vulnerability management should be included in the container lifecycle. diff --git a/src/data/roadmaps/docker/content/110-docker-cli/100-images.md b/src/data/roadmaps/docker/content/110-docker-cli/100-images.md index da3e40fcb..6595bae73 100644 --- a/src/data/roadmaps/docker/content/110-docker-cli/100-images.md +++ b/src/data/roadmaps/docker/content/110-docker-cli/100-images.md @@ -1,56 +1,46 @@ # Docker Images -In this section, we'll explore the concept of Docker images and how they are useful in the Docker ecosystem. - -### What are Docker Images? - Docker images are lightweight, standalone, and executable packages that include everything needed to run an application. These images contain all necessary dependencies, libraries, runtime, system tools, and code to enable the application to run consistently across different environments. Docker images are built and managed using Dockerfiles. A Dockerfile is a script that consists of instructions to create a Docker image, providing a step-by-step guide for setting up the application environment. -### Key Benefits of Docker Images -- **Consistent**: Docker images enable applications to run with the same behavior across various platforms and environments, reducing the impact of the "it works on my machine" issue. -- **Version control**: You can version your Docker images, making it easier to rollback and track changes. -- **Reusability**: Docker images can be shared and reused for creating new containers, enhancing productivity and collaboration. -- **Isolation**: Each Docker image is isolated from the host system and other containers, eliminating conflicts and improving security. - ### Working with Docker Images Docker CLI provides several commands to manage and work with Docker images. Some essential commands include: -- `docker images`: List all available images on your local system. +- `docker image ls`: List all available images on your local system. - `docker build`: Build an image from a Dockerfile. -- `docker rmi`: Remove one or more images. +- `docker image rm`: Remove one or more images. - `docker pull`: Pull an image from a registry (e.g., Docker Hub) to your local system. - `docker push`: Push an image to a repository. For example, to pull the official Ubuntu image from Docker Hub, you can run the following command: -``` +```bash docker pull ubuntu:latest ``` After pulling the image, you can create and run a container using that image with the `docker run` command: -``` +```bash docker run -it ubuntu:latest /bin/bash ``` This command creates a new container and starts an interactive session inside the container using the `/bin/bash` shell. -### Sharing Images +## Sharing Images Docker images can be shared and distributed using container registries, such as Docker Hub, Google Container Registry, or Amazon Elastic Container Registry (ECR). Once your images are pushed to a registry, others can easily access and utilize them. To share your image, you first need to tag it with a proper naming format: -``` +```bash docker tag /: ``` Then, you can push the tagged image to a registry using: -``` +```bash docker push /: ``` diff --git a/src/data/roadmaps/docker/content/110-docker-cli/101-containers.md b/src/data/roadmaps/docker/content/110-docker-cli/101-containers.md index 885f50462..672c700a5 100644 --- a/src/data/roadmaps/docker/content/110-docker-cli/101-containers.md +++ b/src/data/roadmaps/docker/content/110-docker-cli/101-containers.md @@ -1,8 +1,4 @@ -# Containers - -In this section, we'll explore the concept of containers and their significance in the Docker ecosystem. - -## What are Containers? +## Containers? Containers can be thought of as lightweight, stand-alone, and executable software packages that include everything needed to run a piece of software, including the code, runtime, libraries, environment variables, and config files. Containers isolate software from its surroundings, ensuring that it works uniformly across different environments. @@ -24,16 +20,12 @@ Docker CLI offers several commands to help you create, manage, and interact with - `docker run`: Used to create and start a new container. -- `docker ps`: Lists running containers. +- `docker container ls`: Lists running containers. -- `docker stop`: Stops a running container. +- `docker container stop`: Stops a running container. -- `docker rm`: Removes a stopped container. +- `docker container rm`: Removes a stopped container. - `docker exec`: Executes a command inside a running container. -- `docker logs`: Fetches the logs of a container, useful for debugging issues. - -In the following sections, we'll dive deeper into these commands and explore how to efficiently use containers in your application's development and deployment process. - -Remember, containers are at the core of Docker, and understanding them thoroughly will be crucial as you continue utilizing Docker to enhance your application's reliability, scalability, and maintainability. \ No newline at end of file +- `docker logs`: Fetches the logs of a container, useful for debugging issues. \ No newline at end of file diff --git a/src/data/roadmaps/docker/content/110-docker-cli/102-networks.md b/src/data/roadmaps/docker/content/110-docker-cli/102-networks.md index aa9c7aa95..0a603d6a3 100644 --- a/src/data/roadmaps/docker/content/110-docker-cli/102-networks.md +++ b/src/data/roadmaps/docker/content/110-docker-cli/102-networks.md @@ -1,9 +1,5 @@ # Docker Networks -In this section, we will discuss Docker networks, which play a crucial role in enabling communication between containers and ensuring the isolation of applications as per their requirements. - -### Overview - Docker networks provide an essential way of managing container communication. It allows containers to talk to each other and to the host machine using various network drivers. By understanding and utilizing different types of network drivers, you can design container networks to accommodate specific scenarios or application requirements. ### Network Drivers @@ -15,7 +11,7 @@ There are several network drivers available in Docker. Here, we will cover four - **none**: This network driver disables container networking. Containers using this driver run in an isolated environment without any network access. - **overlay**: This network driver enables containers deployed on different hosts to communicate with each other. It is designed to work with Docker Swarm and is perfect for multi-host or cluster-based container deployments. -### Managing Docker Networks +## Managing Docker Networks Docker CLI provides various commands to manage the networks. Here are a few useful commands: @@ -24,8 +20,4 @@ Docker CLI provides various commands to manage the networks. Here are a few usef - Create a new network: `docker network create --driver ` - Connect containers to a network: `docker network connect ` - Disconnect containers from a network: `docker network disconnect ` -- Remove a network: `docker network rm ` - -### Conclusion - -In conclusion, Docker provides a flexible and robust way to handle container networking. By leveraging network drivers, you can create various network setups that cater to distinct application needs or requirements. Understanding these concepts will enable you to design efficient and secure container environments. \ No newline at end of file +- Remove a network: `docker network rm ` \ No newline at end of file diff --git a/src/data/roadmaps/docker/content/110-docker-cli/102-volumes.md b/src/data/roadmaps/docker/content/110-docker-cli/102-volumes.md index 705d22dba..f6118102d 100644 --- a/src/data/roadmaps/docker/content/110-docker-cli/102-volumes.md +++ b/src/data/roadmaps/docker/content/110-docker-cli/102-volumes.md @@ -2,16 +2,11 @@ Docker volumes are a mechanism for persisting data generated by and used by Docker containers. They allow you to separate the data from the container itself, making it easy to backup, migrate, and manage your persistent data. -In this section, we will cover the following topics: -- Why volumes are important -- Types of volumes -- Volume management with Docker CLI - -### Why Volumes are Important +## Why Volumes are Important Docker containers are ephemeral by nature, meaning they can be stopped, deleted, or replaced easily. While this is great for application development and deployment, it poses a challenge when dealing with persistent data. That's where volumes come in. They provide a way to store and manage the data separately from the container's lifecycle. -### Types of Volumes +## Types of Volumes There are three types of volumes in Docker: - **Host Volumes**: They are stored on the host machine's filesystem, usually in the `/var/lib/docker/volumes` directory. These can be easily accessed, but can pose issues with portability or file system compatibility. @@ -20,7 +15,7 @@ There are three types of volumes in Docker: - **Named Volumes**: Similar to anonymous volumes, named volumes are stored on the host machine's filesystem. However, you can provide a custom name, making it easy to reference in other containers or for backups. -### Volume Management with Docker CLI +## Volume Management with Docker CLI Docker CLI provides various commands to manage volumes: @@ -36,6 +31,4 @@ To use a volume in a container, you can use the `-v` or `--volume` flag during t docker run -d --name my-container -v my-named-volume:/var/lib/data my-image ``` -This command creates a new container named "my-container" using the "my-image" image and mounts the "my-named-volume" volume at the `/var/lib/data` path inside the container. - -That's it! Now you know the basics of Docker volumes and how to manage them using the Docker CLI. They are essential for ensuring data persistence and improving the overall workflow of containerized applications. \ No newline at end of file +This command creates a new container named "my-container" using the "my-image" image and mounts the "my-named-volume" volume at the `/var/lib/data` path inside the container. \ No newline at end of file diff --git a/src/data/roadmaps/docker/content/110-docker-cli/index.md b/src/data/roadmaps/docker/content/110-docker-cli/index.md index 6d9cceaae..2527758dc 100644 --- a/src/data/roadmaps/docker/content/110-docker-cli/index.md +++ b/src/data/roadmaps/docker/content/110-docker-cli/index.md @@ -4,27 +4,24 @@ The Docker CLI (Command Line Interface) is a powerful tool that allows you to in In this topic, we'll dive into some key aspects of Docker CLI, covering the following: -### 1. Installation +## 1. Installation To get started with Docker CLI, you need to have Docker installed on your machine. You can follow the official installation guide for your respective operating system from the [Docker documentation](https://docs.docker.com/get-docker/). -### 2. Basic Commands +## 2. Basic Commands Here are some essential Docker CLI commands to familiarize yourself with: - `docker run`: Create and start a container from a Docker image -- `docker ps`: List running containers -- `docker stop`: Stop a running container -- `docker rm`: Remove a stopped container -- `docker images`: List all available images on your system -- `docker rmi`: Remove an image from your system +- `docker container`: List running containers +- `docker image`: List all available images on your system - `docker pull`: Pull an image from Docker Hub or another registry - `docker push`: Push an image to Docker Hub or another registry - `docker build`: Build an image from a Dockerfile - `docker exec`: Run a command in a running container - `docker logs`: Show logs of a container -### 3. Docker Run Options +## 3. Docker Run Options `docker run` is one of the most important commands in the Docker CLI. You can customize the behavior of a container using various options, such as: @@ -36,13 +33,13 @@ Here are some essential Docker CLI commands to familiarize yourself with: - `--restart`: Specify the container's restart policy - `--rm`: Automatically remove the container when it exits -### 4. Dockerfile +## 4. Dockerfile A Dockerfile is a script containing instructions to build a Docker image. You can use the Docker CLI to build, update, and manage Docker images using a Dockerfile. Here is a simple example of a Dockerfile: -```dockerfile +```Dockerfile # Set the base image to use FROM alpine:3.7 @@ -65,7 +62,7 @@ To build the image, use the command: docker build -t my-image . ``` -### 5. Docker Compose +## 5. Docker Compose Docker Compose is a CLI tool for defining and managing multi-container Docker applications using YAML files. It works together with the Docker CLI, offering a consistent way to manage multiple containers and their dependencies. diff --git a/src/data/roadmaps/docker/content/111-developer-experience/100-hot-reloading.md b/src/data/roadmaps/docker/content/111-developer-experience/100-hot-reloading.md index 65d7e8c47..8aa283ffb 100644 --- a/src/data/roadmaps/docker/content/111-developer-experience/100-hot-reloading.md +++ b/src/data/roadmaps/docker/content/111-developer-experience/100-hot-reloading.md @@ -1,37 +1,7 @@ # Hot Reloading in Docker -Hot reloading is a powerful feature that can significantly improve the developer experience. It allows the application to automatically reload or refresh upon changes in its source code without the developer having to manually restart the application or the development server. This not only streamlines the development process but also saves time and increases productivity. +Even though we can speed up the image building with layer caching enable, we don't want to have to rebuild our container image with every code change. Instead, we want the state of our application in the container to reflect changes immediately. We can achieve this through a combination of bind mounts and hot reloading utilities! -In the context of Docker, hot reloading can be achieved using volumes, which are a way to store data and share it between containers, or between a container and the host machine. By mounting your application's source code as a volume, you can ensure that any changes made to the source code are detected by the running container and the application inside it is refreshed accordingly. +Have a look at the following resources for sample implementations: -Here's how you can enable hot reloading in your Docker-based development environment: - -### 1. Configuring the Application - -First, make sure that your application supports live reloading. This can usually be done using built-in features or libraries, depending on the programming language and framework you are using. For example, in a React application, you can use the `react-scripts` package to enable hot reloading. Similarly, in a Node.js application, tools like `nodemon` can be used for the same purpose. - -### 2. Updating the Docker Compose File - -Next, you need to set up a Docker Compose file that defines your services and their configurations. Within this file, add the necessary settings to enable volumes for your application, so that they are shared between your host machine and the running container. Here's an example of how it could look like: - -```yaml -version: '3' -services: - app: - build: . - image: myapp - volumes: - - .:/usr/src/app - ports: - - 3000:3000 - environment: - - NODE_ENV=development -``` - -In this example, the current directory (`.`, where the source code is located) is being mapped to the `/usr/src/app` directory inside the Docker container. This ensures that any changes made to the source code on the host machine will be detected by the container and trigger a reload or refresh of the application. - -### 3. Running the Application with Hot Reloading - -With the application and Docker Compose file configured, you can now start your services with `docker-compose up`. This will launch the containers and automatically enable hot reloading. Now, whenever you make changes to your application's source code, the running container will detect those changes and refresh the app as necessary. - -By leveraging hot reloading in your Docker-based development environment, you can create a seamless and efficient workflow, allowing you to focus on writing code and delivering results faster. \ No newline at end of file +- [Hot Reloading - Docker](https://courses.devopsdirective.com/docker-beginner-to-pro/lessons/11-development-workflow/01-hot-reloading) \ No newline at end of file diff --git a/src/data/roadmaps/docker/content/111-developer-experience/101-debuggers.md b/src/data/roadmaps/docker/content/111-developer-experience/101-debuggers.md index 79b24df20..a8c3ab30e 100644 --- a/src/data/roadmaps/docker/content/111-developer-experience/101-debuggers.md +++ b/src/data/roadmaps/docker/content/111-developer-experience/101-debuggers.md @@ -1,68 +1,5 @@ # Debuggers in Docker -Debuggers are essential tools that allow developers to track down issues and identify the root cause of problems within their applications. In the context of Docker, using debuggers can be a bit more challenging due to the isolated container environment. However, with proper configuration and setup, debuggers can be used effectively and efficiently in Docker projects. +In order to make developing with containers competitive with developing locally, we need the ability to run and attach to debuggers inside the container. -This guide will cover the essentials of using debuggers for Docker-based applications, explaining how you can configure and utilize them for an improved developer experience. - -## Prerequisites - -Before diving into debuggers, make sure you're familiar with the following: - -- Basic Docker concepts and how to write Dockerfiles -- Creating and managing containers -- Docker Compose (optional, but helpful for multi-container setup) - -## Configuring your Debugger - -In order to use a debugger with your Docker-based application, you'll need to do some initial setup. Here are some high-level steps for setting up debugging in your Docker projects: - -- **Choose a Debugger**: First, select a debugger appropriate for your application's programming language (e.g. gdb for C/C++, pdb for Python, or Visual Studio Debugger for .NET applications). - -- **Modify your Dockerfile**: Your Dockerfile should be updated to include the necessary debugger tools or packages. Additionally, you may need to adjust your application's build configuration to include debug symbols which will be helpful when examining your code at runtime. - -Example: -```Dockerfile -FROM python:3.8 AS debug - -RUN apt-get update && apt-get install -y gdb - -COPY requirements.txt ./ - -RUN pip install --no-cache-dir -r requirements.txt - -COPY . . - -CMD ["gdb", "-ex", "run", "-ex", "bt", "--args", "python", "app.py"] -``` - -- **Expose a Debugging Port**: Most debuggers require a dedicated port for remote connections. Update your Dockerfile and `docker-compose.yml` (if applicable) to expose this port, and forward it to your host when running your container. - -Example: -```yml -services: - your_service: - build: . - volumes: - - .:/app - ports: - - "8080:8080" - - "DebuggingPort:DebuggingPort" - environment: - # Configure Env Variables -``` - -- **Configure the Debugger**: Depending on the debugger you're using, you may need to configure it within your application's code, with a configuration file, or by setting environment variables. - -## Debugging Workflow - -Once your debugger is configured, your debugging workflow will involve the following steps: - -- Set breakpoints within your application's code, to specify the locations where you want the debugger to pause. -- Start your Docker container, ensuring that it's running in debug mode and that the debugging port is properly exposed. -- Attach the debugger to the running container using the exposed debugging port. -- Interact with your application and use your debugger to step through your code, examine variables, and debug any issues that arise. -- Once the issue is resolved, update your code accordingly and restart your Docker container to test your changes. - -## Wrap Up - -Using debuggers with Docker-based applications can greatly improve the developer experience by providing better insights into application behavior and potential issues. By configuring your debugger correctly and following the steps outlined above, you can harness the power of debugging within your Docker projects to ensure a more stable and robust application. \ No newline at end of file +- [Debuggers in Docker](https://courses.devopsdirective.com/docker-beginner-to-pro/lessons/11-development-workflow/02-debug-and-test) \ No newline at end of file diff --git a/src/data/roadmaps/docker/content/111-developer-experience/102-tests.md b/src/data/roadmaps/docker/content/111-developer-experience/102-tests.md index 76158de39..6a350f5c3 100644 --- a/src/data/roadmaps/docker/content/111-developer-experience/102-tests.md +++ b/src/data/roadmaps/docker/content/111-developer-experience/102-tests.md @@ -1,52 +1,5 @@ # Tests -### Benefits of Running Tests in Docker +We want to run tests in an environment as similar as possible to production, so it only makes sense to do so inside of our containers! -There are several benefits of running tests in Docker: - -- **Isolation:** Test environments can be isolated from one another, preventing conflicts or inconsistencies between test runs. -- **Consistency:** Docker containers ensure that tests are run under the same conditions every time, reducing variability in test results. -- **Reproducibility:** Tests are quickly and easily reproducible, allowing you to share test environments and results with colleagues. -- **Ease of Use:** Docker makes it easy to set up and tear down test environments, resulting in a quicker development cycle. - -### Writing Tests - -When it comes to writing tests, you typically want to use a testing framework or library that is suited for the programming language and framework of your application. Examples include Jest for JavaScript, pytest for Python, or JUnit for Java. Follow best practices for your application's language and framework when writing tests. - -### Running Tests with Docker - -To run tests within a Docker container, there are a few steps you need to follow: - -- **Create a Test Dockerfile:** Create a separate Dockerfile for running tests. This file should be based on the same image as your application's Dockerfile, and may include additional dependencies or libraries needed for testing. - -``` -# Test Dockerfile -FROM node:12 - -# Set the working directory -WORKDIR /app - -# Copy your package.json and install dependencies -COPY package.json ./ -RUN npm install - -# Copy your source code -COPY . . - -# Run tests -CMD ["npm", "test"] -``` - -- **Build the Test Image:** Build the Docker image for your tests using the test Dockerfile. - -``` -docker build -t myapp-test -f Test.Dockerfile . -``` - -- **Run the Test Container:** Run a Docker container using the test image, which will execute your tests. - -``` -docker run --name myapp-test-container myapp-test -``` - -Running tests in Docker can help you create a more consistent and reliable testing process, which ultimately leads to a smoother development experience and more stable applications. \ No newline at end of file +- [Running Tests - Docker](https://courses.devopsdirective.com/docker-beginner-to-pro/lessons/11-development-workflow/03-tests) \ No newline at end of file diff --git a/src/data/roadmaps/docker/content/111-developer-experience/103-continuous-integration.md b/src/data/roadmaps/docker/content/111-developer-experience/103-continuous-integration.md index 9eeeeef19..a0a8852ea 100644 --- a/src/data/roadmaps/docker/content/111-developer-experience/103-continuous-integration.md +++ b/src/data/roadmaps/docker/content/111-developer-experience/103-continuous-integration.md @@ -1,35 +1,15 @@ # Continuous Integration (CI) -Continuous Integration (CI) is an essential practice in modern software development. CI automates the process of building, testing, and integrating code changes from multiple contributors. By employing CI, you can catch and fix potential issues early in the development lifecycle, improve code quality, and shorten the time it takes to deliver the final product. +Continuous integration is the idea of executing some actions (for example build, test, etc...) automatically as you push code to your version control system. -### CI and Docker +For containers, there are a number of things we may want to do: -Docker can significantly enhance the CI process by allowing developers to create lightweight and portable containers that can run applications and their dependencies. These containers can be easily shared, tested, and deployed without worrying about environment inconsistencies or conflicts. +- Build the container images +- Eecute tests +- Scan container images for vulnerabilities +- Tag images with useful metadata +- Push to a container registry -### Key Benefits of CI with Docker +Learn more from the following: -- **Consistency:** Docker helps maintain consistency across development, testing, and production environments. Docker containers can be versioned and shared among team members, reducing the risk of discrepancies or out-of-date dependencies. - -- **Isolation:** Docker containers can run multiple services or applications in isolation. This allows for better separation of concerns and the ability to test individual components without affecting the entire application stack. - -- **Reproducibility:** Creating a Docker container for your application ensures that it can be reliably reproduced and tested across different environments or platforms. - -- **Scalability:** Docker enables you to run multiple instances of your application or its components on a single host or cluster. This makes it easy to scale your CI environment to handle more complex builds or tests. - -- **Speed:** By leveraging the Docker cache, builds and tests can be run much faster as Docker reuses existing layers that haven't changed since the last build. - -### Implementing CI with Docker - -To implement continuous integration with Docker, you need to follow these basic steps: - -- **Create a Dockerfile**: Write a Dockerfile for your application, including all dependencies and configurations required to build and run the application. - -- **Build Docker Images**: Use Docker to build an image of your application from the Dockerfile. - -- **Run Tests**: Execute tests in a Docker container using the built image. This ensures that the testing environment is consistent with the production environment. - -- **Push Images**: If tests pass, push the Docker image to a container registry/repository such as Docker Hub or a private registry. - -- **Deploy**: Deploy your application to a production environment using the Docker image from the container registry. - -By incorporating Docker into your CI pipeline, you can streamline the process of building, testing, and deploying software while reducing inconsistencies and improving overall code quality. \ No newline at end of file +- [Continuous Integration - Docker](https://courses.devopsdirective.com/docker-beginner-to-pro/lessons/11-development-workflow/04-continuous-integration-github-actions) \ No newline at end of file diff --git a/src/data/roadmaps/docker/content/111-developer-experience/index.md b/src/data/roadmaps/docker/content/111-developer-experience/index.md index 07a12c847..6afb7be99 100644 --- a/src/data/roadmaps/docker/content/111-developer-experience/index.md +++ b/src/data/roadmaps/docker/content/111-developer-experience/index.md @@ -1,31 +1,15 @@ # Developer Experience -In the context of Docker, DX revolves around simplifying the process of creating, deploying, and running applications using containers. This can be achieved by leveraging features and tools provided by Docker. +So far we have only discussed using docker for deploying applications. However, docker is also a great tool for developing applications. There are a few different recommendations that you can adopt to improve your development experience. -This guide covers the following aspects of the Docker Developer Experience: +- Use `docker-compose` in your application for ease of development. +- Use bind mounts to mount the code from your local into the container filesystem to avoid having to rebuild the container image with every single change. +- For auto-reloading, you can use tools like [vite](https://vitejs.dev/) for client side, [nodemon](https://nodemon.io/) for nodejs or [air](https://github.com/cosmtrek/air) for golang. +- You should also provide a way to debug your applications. For example, look into [delve](https://github.com/go-delve/delve) for Go, enable debugging in node.js using --inspect flag etc. It doesn't matter what you use, but the point is that you should have a way to debug your application running inside the container. +- You should have a way to run tests inside the container. For example, you could have a separate docker-compose file for running tests. +- You should have a CI pipeline for production images. +- Ephemeral environment for each pull request -### 1. Writing Dockerfiles +For more details and practical examples: -A fundamental aspect of the DX in Docker is writing effective Dockerfiles. Learn best practices for creating minimal, efficient, and maintainable Dockerfiles – the foundation of your containerized environments. - -### 2. Multi-stage builds - -Optimize your build process through multi-stage builds, which help you create lean and clean images. This improves the development speed and sharing of images. - -### 3. Local development - -Explore how to efficiently set up your local development environment using Docker Compose, which allows you to define and run multi-container applications. This section covers best practices, tips, and common pitfalls to avoid. - -### 4. Debugging - -Get practical advice on how to debug issues in your Docker containers, both during development and after deployment. This includes docker-specific debugging strategies, as well as integrating with other debugging tools. - -### 5. Continuous Integration and Deployment - -Learn how to incorporate Docker into your CI/CD pipelines to automate building, testing, and deploying your applications. Discover how to use the Docker registry to store images, set up automated build triggers, and integrate with popular CI/CD tools. - -### 6. Sharing your work - -Dive into the world of Docker Hub and other container registries. Learn the advantages of sharing your images with others, both in terms of collaborating on your own projects and contributing to the broader Docker community. - -By following this guide, you'll gain a deep understanding of the Docker Developer Experience, and learn how to make the most of its features and best practices to enhance your software development process. \ No newline at end of file +- [Developer Experience Wishlist - Docker](https://courses.devopsdirective.com/docker-beginner-to-pro/lessons/11-development-workflow/00-devx-wishlist#key-devx-features) \ No newline at end of file diff --git a/src/data/roadmaps/docker/content/112-deploying-containers/100-paas-options.md b/src/data/roadmaps/docker/content/112-deploying-containers/100-paas-options.md index 3f4f620d1..cdf706580 100644 --- a/src/data/roadmaps/docker/content/112-deploying-containers/100-paas-options.md +++ b/src/data/roadmaps/docker/content/112-deploying-containers/100-paas-options.md @@ -1,10 +1,17 @@ # PaaS Options for Deploying Containers -Platform as a Service (PaaS) is a cloud computing model that simplifies the deployment and management of containers. It abstracts away the underlying infrastructure allowing developers to focus on creating and running their applications. +Platform as a Service (PaaS) is a cloud computing model that simplifies the deployment and management of containers. It abstracts away the underlying infrastructure allowing developers to focus on creating and running their applications. Given below are some of the popular PaaS options for deploying containers: -In this section, we will discuss popular PaaS options for deploying containers: +## Amazon Elastic Container Service -### 1. Google Cloud Run +[Amazon Elastic Container Service](https://aws.amazon.com/ecs/) is a fully managed container orchestration service offered by Amazon Web Services. It allows you to run containers without having to manage servers or clusters. It integrates with other AWS services such as IAM, CloudWatch, and CloudFormation. + +- Supports Docker containers and Amazon ECR +- Offers a free tier for new users +- Supports multiple deployment options +- Pay for what you use, with no upfront costs + +## Google Cloud Run [Google Cloud Run](https://cloud.google.com/run) is a fully-managed compute platform by Google that allows you to run stateless containers. It is designed for running applications that can scale automatically, enabling you to pay only for the resources you actually use. @@ -13,16 +20,7 @@ In this section, we will discuss popular PaaS options for deploying containers: - Integrates with other Google Cloud services - Offers a generous free tier -### 2. Heroku Container Registry - -[Heroku Container Registry](https://devcenter.heroku.com/articles/container-registry-and-runtime) allows you to deploy containers on the Heroku Platform. With Heroku, you can quickly deploy, manage, and scale your applications using a variety of popular languages and frameworks. - -- Simple and straightforward deployment process -- Add-ons and integrations for popular databases, caching, data processing, etc. -- Built-in CI/CD and support for GitHub integration -- Free tier with limitations on resources and 550-1,000 dyno hours per month - -### 3. AWS Elastic Beanstalk +## AWS Elastic Beanstalk [AWS Elastic Beanstalk](https://aws.amazon.com/elasticbeanstalk/) is an orchestration service offered by Amazon Web Services that allows you to deploy, manage, and scale applications using containers, without worrying about the underlying infrastructure. @@ -31,7 +29,7 @@ In this section, we will discuss popular PaaS options for deploying containers: - Offers monitoring and logging capabilities - Pay for what you use, with no upfront costs -### 4. Microsoft Azure Container Instances +## Microsoft Azure Container Instances [Azure Container Instances](https://azure.microsoft.com/en-us/services/container-instances/) is a service offered by Microsoft Azure that simplifies the deployment of containers using a serverless model. You can run containers without managing the underlying hosting infrastructure or container orchestration. @@ -40,7 +38,7 @@ In this section, we will discuss popular PaaS options for deploying containers: - Integration with Azure services and Azure Kubernetes Service - Pay-per-second billing model -### 5. IBM Cloud Code Engine +## IBM Cloud Code Engine [IBM Cloud Code Engine](https://www.ibm.com/cloud/code-engine) is a fully managed, serverless platform by IBM that runs your containerized applications and source code. It supports deploying, running, and auto-scaling applications on Kubernetes. diff --git a/src/data/roadmaps/docker/content/112-deploying-containers/101-kubernetes.md b/src/data/roadmaps/docker/content/112-deploying-containers/101-kubernetes.md index c79fc748c..1b11357e8 100644 --- a/src/data/roadmaps/docker/content/112-deploying-containers/101-kubernetes.md +++ b/src/data/roadmaps/docker/content/112-deploying-containers/101-kubernetes.md @@ -2,7 +2,7 @@ Kubernetes (K8s) is an open-source orchestration platform used for automating the deployment, scaling, and management of containerized applications. While Docker provides the container runtime environment, Kubernetes extends that functionality with a powerful and flexible management framework. -#### Key Concepts +## Key Concepts - **Cluster**: A set of machines, called nodes, that run containerized applications in Kubernetes. A cluster can have multiple nodes for load balancing and fault tolerance. @@ -14,7 +14,7 @@ Kubernetes (K8s) is an open-source orchestration platform used for automating th - **Deployment**: A high-level object that describes the desired state of a containerized application. Deployments manage the process of creating, updating, and scaling pods based on a specified container image. -#### Why Use Kubernetes? +## Why Use Kubernetes? Kubernetes plays a crucial role in managing containerized applications at scale, offering several advantages over traditional deployment mechanisms: @@ -23,7 +23,7 @@ Kubernetes plays a crucial role in managing containerized applications at scale, - **Rolling updates & rollbacks**: Kubernetes makes it easy to update your applications by incrementally rolling out new versions of container images, without any downtime. - **Load balancing**: Services in Kubernetes distribute network traffic among container instances, offering a load balancing solution for your applications. -#### Kubernetes vs. Docker Swarm +## Kubernetes vs. Docker Swarm While both Kubernetes and Docker Swarm are orchestration platforms, they differ in terms of complexity, scalability, and ease of use. Kubernetes provides more advanced features, better scalability, and higher fault tolerance, but has a steeper learning curve. Docker Swarm, on the other hand, is simpler and more straightforward but lacks some advanced functionality. diff --git a/src/data/roadmaps/docker/content/112-deploying-containers/102-docker-swarm.md b/src/data/roadmaps/docker/content/112-deploying-containers/102-docker-swarm.md index 3d4269536..3b68cc1a2 100644 --- a/src/data/roadmaps/docker/content/112-deploying-containers/102-docker-swarm.md +++ b/src/data/roadmaps/docker/content/112-deploying-containers/102-docker-swarm.md @@ -2,7 +2,7 @@ Docker Swarm is a container orchestration tool that enables users to manage multiple Docker nodes and deploy services across them. It is a native clustering and orchestration feature built into the Docker Engine, which allows you to create and manage a swarm of Docker nodes, referred to as a _Swarm_. -### Key concepts +## Key concepts - **Node**: A Docker node is an instance of the Docker Engine that participates in the swarm. Nodes can either be a _worker_ or a _manager_. Worker nodes are responsible for running containers whereas manager nodes control the swarm and store the necessary metadata. @@ -10,7 +10,7 @@ Docker Swarm is a container orchestration tool that enables users to manage mult - **Tasks**: A task carries a Docker container and the commands required to run it. Swarm manager nodes assign tasks to worker nodes based on the available resources. -### Main advantages +## Main advantages - **Scalability**: Docker Swarm allows you to scale services horizontally by easily increasing or decreasing the number of replicas. @@ -20,53 +20,4 @@ Docker Swarm is a container orchestration tool that enables users to manage mult - **Rolling updates**: Swarm enables you to perform rolling updates with near-zero downtime, easing the process of deploying new versions of your applications. -### Setting up a Docker Swarm - -To set up a Docker Swarm, follow these simple steps: - -- Install Docker on each node you want to add to the swarm. - -- On the first node, initialize the swarm by running the following command: - - ``` - docker swarm init --advertise-addr - ``` - - Replace `` with the IP address of the manager node. - -- The previous command will output a token that you'll need to use to join additional nodes to the swarm. Run the following command on each of the worker nodes: - - ``` - docker swarm join --token :2377 - ``` - - Replace `` with the token provided in step 2, and `` with the IP address of the manager node. - -### Deploying Services in Docker Swarm - -To deploy a service in Docker Swarm, follow these steps: - -- Create a `docker-compose.yml` file with the desired services. For example: - - ```yaml - version: '3' - services: - web: - image: nginx - ports: - - "80:80" - networks: - - mynet - networks: - mynet: - ``` - -- Use the `docker stack deploy` command to deploy the services defined in the `docker-compose.yml` file: - - ``` - docker stack deploy --compose-file docker-compose.yml mystack - ``` - -Swarm will distribute the services across the nodes based on the provided configuration. - Visit the official [Docker Swarm documentation](https://docs.docker.com/engine/swarm/) to learn more about its features and best practices. \ No newline at end of file diff --git a/src/data/roadmaps/docker/content/112-deploying-containers/103-nomad.md b/src/data/roadmaps/docker/content/112-deploying-containers/103-nomad.md index ba8db052a..92502983f 100644 --- a/src/data/roadmaps/docker/content/112-deploying-containers/103-nomad.md +++ b/src/data/roadmaps/docker/content/112-deploying-containers/103-nomad.md @@ -1,89 +1,5 @@ # Nomad: Deploying Containers -[Nomad](https://www.nomadproject.io/) is a powerful and flexible tool for deploying containers. It is designed by HashiCorp, the creators of other popular DevOps tools such as Terraform and Vault. In this section, we'll cover the basics of Nomad and explore how you can use it to easily deploy and manage your containerized applications. - -### What is Nomad? - Nomad is a cluster manager and scheduler that enables you to deploy, manage and scale your containerized applications. It automatically handles node failures, resource allocation, and container orchestration. Nomad supports running Docker containers as well as other container runtimes and non-containerized applications. -### Key Features - -- **Flexible Deployment**: Nomad supports multiple container runtimes, including Docker, as well as non-containerized applications. -- **Highly Scalable**: Nomad is designed to scale from a single machine to thousands of nodes, promoting efficient resource utilization. -- **Resilient**: Nomad automatically handles node failures, maintaining the desired application state and count. -- **Simple to Use**: Nomad features a single binary and a single configuration file, making it easy to get started. -- **HashiCorp Ecosystem Integration**: Nomad works seamlessly with other HashiCorp tools such as Consul for service discovery and Vault for secrets management. - -### Getting Started with Nomad - -To start using Nomad, you'll need to install the Nomad binary on your system. You can download it from the [official website](https://www.nomadproject.io/downloads). Once installed, you can start using Nomad to deploy and manage your containers. - -#### Step 1: Set up a Nomad cluster - -A Nomad cluster consists of one or more client nodes and one or more server nodes. You'll need to configure and start the server(s) and client(s), specifying their roles and communication settings. - -Server configuration example: - -```hcl -data_dir = "/path/to/data-dir" - -server { - enabled = true - bootstrap_expect = 3 -} -``` - -Client configuration example: - -```hcl -data_dir = "/path/to/data-dir" - -client { - enabled = true - servers = ["server1:4647", "server2:4647", "server3:4647"] -} -``` - -#### Step 2: Define your job specification - -Jobs are the unit of work in Nomad, and they are defined using HashiCorp Configuration Language (HCL). You'll create a job specification file for your container deployment. - -Example job specification for a Docker container: - -```hcl -job "example" { - datacenters = ["dc1"] - - group "web" { - task "app" { - driver = "docker" - - config { - image = "your-docker-image" - ports = ["http"] - } - - resources { - cpu = 500 - memory = 256 - network { - mbits = 10 - port "http" {} - } - } - } - } -} -``` - -#### Step 3: Deploy your job - -To deploy your job, you'll submit the job specification to Nomad using the `nomad run` command. Nomad will schedule and deploy the containers on the available nodes, handling failures and scaling as needed. - -```shell -$ nomad run example-job.hcl -``` - -### Next Steps - -We've covered the basics of Nomad and deploying containers with it. You can now experiment with more advanced features like integrating with Consul and Vault, or explore different deployment strategies like Canary or Blue/Green. To dive deeper into Nomad, check out the [official documentation](https://www.nomadproject.io/docs). \ No newline at end of file +To dive deeper into Nomad, check out the [official documentation](https://www.nomadproject.io/docs). \ No newline at end of file