<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[DevShift]]></title><description><![CDATA[Learnings on backend engineering, system design, and making the shift into software engineering without a degree.]]></description><link>https://devshift.substack.com</link><image><url>https://substackcdn.com/image/fetch/$s_!q8mp!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fdevshift.substack.com%2Fimg%2Fsubstack.png</url><title>DevShift</title><link>https://devshift.substack.com</link></image><generator>Substack</generator><lastBuildDate>Wed, 19 Aug 2026 22:42:51 GMT</lastBuildDate><atom:link href="https://devshift.substack.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Ben Barten]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[devshift@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[devshift@substack.com]]></itunes:email><itunes:name><![CDATA[Ben Barten - Reader]]></itunes:name></itunes:owner><itunes:author><![CDATA[Ben Barten - Reader]]></itunes:author><googleplay:owner><![CDATA[devshift@substack.com]]></googleplay:owner><googleplay:email><![CDATA[devshift@substack.com]]></googleplay:email><googleplay:author><![CDATA[Ben Barten - Reader]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Reframing Technical Debt]]></title><description><![CDATA[How developers can bridge the communication gap to get their technical debt projects prioritized]]></description><link>https://devshift.substack.com/p/reframing-technical-debt</link><guid isPermaLink="false">https://devshift.substack.com/p/reframing-technical-debt</guid><dc:creator><![CDATA[Ben Barten - Reader]]></dc:creator><pubDate>Fri, 02 May 2025 13:28:31 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Fc3g!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F828c5b11-e746-4086-9e26-25de94a8f303_1400x470.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In fast-moving environments such as startups and scaleups, technical debt is used as a tool for quick wins during development at the cost of future complexity. Due to the latter, its connotation is mostly negative. Developers complain about how technical debt is slowing them down. Business folks fear it because working on technical debt means not working on new features, and whether or not it is necessary is hard to evaluate.</p><p>Technical debt accelerates your growth. As financial debt, it allows you to move faster. It accumulates over time and can cripple your business if not paid back. None of this is news, so why is managing technical debt in practice still hard? The answer is communication.</p><h3>The broken discussion</h3><p>I was fortunate enough to work on multiple greenfield products in my career and could observe how technical debt grows. In all projects, technical debt was necessary to keep moving fast. In all projects, we reached a point where the effects of technical debt started slowing us down. In all projects, getting buy-in to work on technical debt was hard because the business needed to keep moving, and working on technical debt was not seen as a value-add.</p><p>The pattern is usually something like this:</p><blockquote><p>Developers: &#8220;We have so much technical debt, it&#8217;s slowing us down.&#8221;<br>Business: &#8220;Ok, what is the issue?&#8221;<br>Developers: &#8220;We need to migrate A to B and refactor C, because the code is really bad.&#8221;<br>Business: &#8220;I hear you. Unfortunately, we have this deadline for our new feature coming up, and <strong>we really need to deliver this</strong>.&#8221;<br>Developers: &#8220;Ok&#8230;&#8221;</p></blockquote><p>The development goes on, and the feature will be delivered. It took longer than expected, but there could be a variety of reasons for that - who knows? The business feels right about its decision to push back on technical debt projects because, after all, the feature was delivered, and the customer is happy. The next development cycle starts, and the conversation either starts over or stops, because the developers have resigned.</p><h3>Closing the gap</h3><p>The truth is that most development teams have a hard time selling why they need to work on technical debt and how it is hurting the business. Measuring the effects of technical debt is difficult. However, unless you can clearly articulate how working on a technical debt project affects and benefits the business, you force non-technical people to trust you blindly.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Fc3g!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F828c5b11-e746-4086-9e26-25de94a8f303_1400x470.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Fc3g!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F828c5b11-e746-4086-9e26-25de94a8f303_1400x470.png 424w, https://substackcdn.com/image/fetch/$s_!Fc3g!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F828c5b11-e746-4086-9e26-25de94a8f303_1400x470.png 848w, https://substackcdn.com/image/fetch/$s_!Fc3g!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F828c5b11-e746-4086-9e26-25de94a8f303_1400x470.png 1272w, https://substackcdn.com/image/fetch/$s_!Fc3g!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F828c5b11-e746-4086-9e26-25de94a8f303_1400x470.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Fc3g!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F828c5b11-e746-4086-9e26-25de94a8f303_1400x470.png" width="1400" height="470" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/828c5b11-e746-4086-9e26-25de94a8f303_1400x470.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:470,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:694939,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://devshift.substack.com/i/160559925?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F828c5b11-e746-4086-9e26-25de94a8f303_1400x470.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!Fc3g!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F828c5b11-e746-4086-9e26-25de94a8f303_1400x470.png 424w, https://substackcdn.com/image/fetch/$s_!Fc3g!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F828c5b11-e746-4086-9e26-25de94a8f303_1400x470.png 848w, https://substackcdn.com/image/fetch/$s_!Fc3g!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F828c5b11-e746-4086-9e26-25de94a8f303_1400x470.png 1272w, https://substackcdn.com/image/fetch/$s_!Fc3g!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F828c5b11-e746-4086-9e26-25de94a8f303_1400x470.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>I like this Dilbert illustration because it highlights a common pattern in tech companies. The manager does not understand technology enough to evaluate the problem. The <strong>developer is not able to communicate their problem</strong> in a way that helps their manager to make a decision. The result is a communication and knowledge gap that leaves both parties frustrated. </p><p>If we want to solve technical debt and keep our business moving, we need to close this gap. </p><h3>Communicate, showcase, establish trust</h3><p>As developers, we need to put ourselves into the shoes of our managers. Unless a project does not contribute to the company&#8217;s success, there is no economic reason to prioritize it. Only if we can explain and measure the impact of our project will it compare to the new shiny feature that promises to increase conversion rates by 10% or drive &#8364;20k in monthly recurring revenue. So, before proposing a technical debt project, make sure you know <strong>how it negatively impacts the business</strong>, and <strong>how it positively impacts it after delivery</strong>. An example of such an assessment could be:</p><p><em>&#8220;The team has to spend 2-3 hours every week debugging issues related to our outdated data sync service. By modernizing the service, we not only reduce that overhead but also cut our customer support tickets by 15% and unblock future feature development in that area. The ROI becomes clear when you compare the one-time effort against recurring time savings and faster delivery for upcoming roadmap items.&#8221;</em></p><p>Now, compare this to our Dilbert cartoon. While the technical details of the data sync service are hidden, it is immediately clear to <strong>everyone</strong> <strong>how this change impacts the business</strong>. If it would require too much technical expertise to understand the impact, the chances increase that decision makers struggle to assess it. So, it is your job as a developer to translate and help non-technical stakeholders understand the impact.</p><p>Finally, once your project is done, make sure to celebrate your success and showcase how the project improved the situation for the business. Not only is celebrating success important for your team, but it will also establish trust with your colleagues. You will be seen both as a facilitator and a technical expert.</p>]]></content:encoded></item><item><title><![CDATA[A Case for Hiring Junior Engineers in the Age of AI]]></title><description><![CDATA[How GenAI is reshaping teams and why juniors still matter to ensure long-term success.]]></description><link>https://devshift.substack.com/p/a-case-for-hiring-junior-engineers</link><guid isPermaLink="false">https://devshift.substack.com/p/a-case-for-hiring-junior-engineers</guid><dc:creator><![CDATA[Ben Barten - Reader]]></dc:creator><pubDate>Sun, 30 Mar 2025 09:43:33 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/563a5a3e-ef2d-4fe1-9c47-c20d702e6e55_1200x1200.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you work for a mid to large-sized tech company, chances are high that most of your open positions (if you have any) are for senior engineers. After the exponential demand for software developers during the covid crisis, the hiring market for developers has reached its lowest point in the past five years, according to Gergely Orosz&#8217; findings in the Pragmatic Engineer.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self">1</a> While the reasons for this shift have been widely discussed, there is a broader shift in hiring more senior candidates. When talking to people in the industry, three assumptions regularly come up:</p><ul><li><p>Juniors are slowing down senior engineers</p></li><li><p>Senior engineers are more productive due to GenAI </p></li><li><p>A lot of the traditional work juniors do is now done by AI  </p></li></ul><p>Let&#8217;s break these assumptions down.</p><h2>Juniors are slowing down senior engineers</h2><p>There&#8217;s some truth here. Mentoring takes time. Onboarding, reviewing PRs, and explaining architectural decisions all pull senior engineers away from their own deliverables. In high-pressure environments, this can feel like a drag. However, this view ignores the long-term benefits of growing talent internally.</p><p>Juniors bring fresh perspectives. Their questions often surface hidden assumptions. Their eagerness to explore new technologies&#8212;sometimes too early&#8212;can be annoying but occasionally unlocks new perspectives and potential breakthroughs. Additionally, teaching others has a funny way of exposing your own knowledge gaps and reinforcing your expertise. Pair programming, for instance, is not just about mentorship&#8212; it&#8217;s a form of active debugging for your thinking. If used correctly, this can have a compounding effect on your overall team&#8217;s productivity.</p><h2>Seniors are more productive with GenAI</h2><p>Senior engineers can indeed use GenAI tools like LLMs more effectively. They understand how to craft better prompts, set proper context, and&#8212;most importantly&#8212;review the output critically. According to the &#8220;Anthropic Economic Index&#8221;, GenAI has increased productivity across many industries, but especially in software engineering, where the benefits compound with experience.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-2" href="#footnote-2" target="_self">2</a> However, productivity gains don&#8217;t translate into needing fewer people; they usually mean more gets built faster. More features, more iterations, more complexity. More maintenance.</p><p>The bottleneck shifts&#8212;not disappears. We still need experienced engineers to review, debug, and steer the outputs of AI. As the systems we build grow more complex, the demand for judgment, context, and architectural thinking grows with it. In fact, as GenAI becomes more widespread, the need for subject-matter experts increases. Or, as IBM famously stated in the 70s:</p><blockquote><p>A computer can never be held accountable, therefore a computer must never make a <em>management</em> decision.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-3" href="#footnote-3" target="_self">3</a></p></blockquote><h2>The work juniors used to do is now done by AI</h2><p>There is some truth in this. A lot of boilerplate, CRUD logic, or basic scripting can now be generated by AI. But real-world systems aren&#8217;t just code, they&#8217;re living ecosystems that require debugging, tuning, context, and care. AI may handle repetitive tasks, but it doesn&#8217;t replace the need for humans to understand <strong>why</strong> something is built the way it is.</p><p>The real danger here is not that GenAI replaces junior engineers, it&#8217;s that we stop giving people the chance to become senior engineers in the future. If we stop hiring juniors today, who will be our seniors in five years?</p><h2>Conclusion</h2><p>The current market favors senior engineers, but not because juniors have become irrelevant. It&#8217;s a response to short-term pressures and the allure of quick productivity wins. But, organizations that fail to invest in junior talent risk long-term stagnation. Innovation doesn't just come from expertise, it comes from curiosity, naivety, and ambitious people with something to prove.</p><p>GenAI is a tool. A powerful one. But tools don&#8217;t build great software &#8212; teams do, and they need all levels of experience.</p><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-1" href="#footnote-anchor-1" class="footnote-number" contenteditable="false" target="_self">1</a><div class="footnote-content"><p>https://blog.pragmaticengineer.com/software-engineer-jobs-five-year-low/</p></div></div><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-2" href="#footnote-anchor-2" class="footnote-number" contenteditable="false" target="_self">2</a><div class="footnote-content"><p>https://www.anthropic.com/news/the-anthropic-economic-index</p></div></div><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-3" href="#footnote-anchor-3" class="footnote-number" contenteditable="false" target="_self">3</a><div class="footnote-content"><p>https://knowyourmeme.com/memes/a-computer-can-never-be-held-accountable</p><p></p></div></div>]]></content:encoded></item><item><title><![CDATA[Self-taught Engineers' Hidden Advantage]]></title><description><![CDATA[Self-taught engineers have a unique approach to software engineering. If played right, this is can be an advantage over their college graduate peers.]]></description><link>https://devshift.substack.com/p/self-taught-engineers-hidden-advantage</link><guid isPermaLink="false">https://devshift.substack.com/p/self-taught-engineers-hidden-advantage</guid><dc:creator><![CDATA[Ben Barten - Reader]]></dc:creator><pubDate>Sun, 16 Feb 2025 10:19:11 GMT</pubDate><content:encoded><![CDATA[<p>A lot of times I tell people that I am a self-taught developer, they have references to that one self-taught colleague who is among the high performers on their team. They neither lack the knowledge of the software engineering domain nor are they less productive or motivated compared to their peers. Contrarily, they seem to be particularly motivated and engaged in the field. Not only are there <a href="https://medium.com/the-self-taught-programmer/the-ten-greatest-self-taught-programmers-of-all-time-b59b1b3bb9e6">prominent examples</a>, but my personal experience is similar. Among the best and most motivated people I got to work with, a disproportionate amount is autodidacts. This experience led me to a question:</p><p>How do self-taught engineers, without years of formal education, not only catch up but sometimes surpass their traditionally trained peers?</p><h2>Intrinsic vs. extrinsic motivation</h2><p>The effects of intrinsic motivation have been widely discussed. Today, we know that intrinsic motivation is what keeps people excited, happy, and motivated to do whatever they are doing. It&#8217;s easy to argue that self-taught engineers must be intrinsically motivated to study a complex subject such as software engineering on their own. Compared to college students who study computer science for external reasons (financial benefits, status, parents, etc.) they have the motivational upper hand. However, many CS students choose to study this field deliberately as well.</p><p>Recently, I listened to Shankar Vedantam&#8217;s podcast episode &#8220;<a href="https://hiddenbrain.org/podcast/what-do-you-want-to-be/">Hidden Brain: Who do you want to be</a>&#8221; which had Kennon M. Sheldon as his guest. Kennon M. Sheldon is a professor of Psychology at the University of Missouri with a focus on goals, motivation, and psychological well-being. In this episode, they discussed Edward Deci's study &#8220;<a href="http://www.selfdeterminationtheory.org/SDT/documents/1971_Deci.pdf">Effects of externally mediated rewards on intrinsic motivation&#8221;</a> (1971). In this experiment, participants were asked to solve Soma cube puzzles over three sessions. During the second session, one group received monetary rewards for each puzzle solved, while the control group did not receive any compensation. In the final session, neither group received rewards. The findings revealed that participants who had been rewarded in the second session spent less time engaging with the puzzles in the third session compared to those who were never rewarded, indicating a decrease in their intrinsic motivation.</p><blockquote><p><em>"[&#8230;] when money is used as an external reward for some activity, the subjects lose intrinsic motivation for the activity."</em> (Deci, 1971)<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self">1</a></p></blockquote><p>This was counter-intuitive for me. I would expect that adding an external reward to something I already enjoy doing increases my motivation. However, plus times plus does not equal plus in motivational terms. Adding external rewards diminishes intrinsic motivation. The topic you once enjoyed studying, becomes less exciting once someone pays you for it. This is bad news for anyone who made their hobby their job. Now, we need to live off something. Unless you are financially independent, chances are high that doing something you genuinely enjoy is still better than doing something you never enjoyed in the first place. So, let&#8217;s assume the external (de-)motivating factors are the same for both self-taught engineers and their college graduate peers.</p><p>Before we jump to a conclusion, let&#8217;s look at what being self-taught is like in practice.</p><h2>Learning by doing</h2><p>There are many paths for self-taught engineers in the tech industry. Some engineers started with a boot camp, others started personal projects, or their current job required them to do some software development which sparked their interest. All of them unite the fact that they did not get the time to first study the subject in-depth as computer science students, but rather started learning by doing early on.</p><p>To succeed in an environment where everyone around you has a headstart, it is extremely important to become good at learning, prioritizing what to learn, and applying your knowledge. Everyone who starts doing software development can be easily overwhelmed by the breadth of technologies, languages, and topics required for the task. Impostor syndrome is real and can be crippling in this context. <br>So, to catch up with peers, self-taught engineers first need to find a way to be productive and get the job done. Next, they need to find time to dive deep into technical areas that are not immediately related to their job but will allow them to grow in the long term.</p><blockquote><p><em>"activity-based teaching is more effective in enhancing students' academic achievement and motivation as compared to traditional teaching methods." - </em>Anwer, F. (2019)<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-2" href="#footnote-2" target="_self">2</a></p></blockquote><p>Learning is most effective by doing. While your peers have studied the foundational topics of software engineering years before they apply them, self-taught engineers study while (consciously or unconsciously) applying them. This requires a general ability to be comfortable with the unknown because you won&#8217;t be able to study every topic you encounter in-depth. On the other side, having the opportunity to apply what you learn directly is an accelerator to building and retaining knowledge in your long-term memory. </p><h2>The fast lane</h2><p>Self-taught engineers do not go through years of college where your studying is rewarded with grades. Self-taught engineers do not study a topic in depth for years before they apply that knowledge in practice. Self-taught engineers tackle problems as they come their way, they say yes to the challenges in front of them and then get to apply their knowledge in practice immediately. This is exactly what puts them in the fast lane. The level of intrinsic motivation can stay comparably high without years of external rewards diminishing it. At the same time, they benefit from the increased learning effects of learning by doing, resulting in better long-term retention and a deeper understanding of their knowledge.</p><p>As knowledge workers, acquiring and retaining knowledge is the core skill. And yes, going into an industry where everyone else has a headstart is not an easy position. Computer science students develop a strong grasp of theory which can be an advantage in certain domains such as systems programming, compiler theory, and research in general. However, if you stay in the fast lane long enough, you can catch up or even overtake your peers. Focus on learning how to learn. Use play and experimentation without any external rewards to keep your intrinsic motivation high. Be bold in taking on new challenges and build that knowledge while you try to solve them.</p><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-1" href="#footnote-anchor-1" class="footnote-number" contenteditable="false" target="_self">1</a><div class="footnote-content"><p>Deci, E. L. (1971). Effects of externally mediated rewards on intrinsic motivation. <em>Journal of Personality and Social Psychology</em>, <em>18</em>(1), 105&#8211;115. http://www.selfdeterminationtheory.org/SDT/documents/1971_Deci.pdf</p></div></div><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-2" href="#footnote-anchor-2" class="footnote-number" contenteditable="false" target="_self">2</a><div class="footnote-content"><p>Anwer, F. (2019). <em>Activity-Based Teaching, Student Motivation and Academic Achievement</em>. Journal of Education and Educational Development, 6(1), 154-170. <a href="https://files.eric.ed.gov/fulltext/EJ1216784.pdf">https://files.eric.ed.gov/fulltext/EJ1216784.pdf</a></p></div></div>]]></content:encoded></item><item><title><![CDATA[Premature Abstractions]]></title><description><![CDATA[Why keeping it simple beats being clever in software development]]></description><link>https://devshift.substack.com/p/premature-abstractions</link><guid isPermaLink="false">https://devshift.substack.com/p/premature-abstractions</guid><dc:creator><![CDATA[Ben Barten - Reader]]></dc:creator><pubDate>Sat, 11 Jan 2025 09:32:40 GMT</pubDate><content:encoded><![CDATA[<p>At some point in software engineering, we get across the term premature optimization. Premature optimization is the practice of improving your software without an actual need, hence prematurely. In many cases, this happens when clever developers want to optimize their code for performance or create abstractions before they're needed. Over the years, I observed this clever behavior not only when writing code, but also when designing systems and team structures. I think of this phenomenon as a <strong>premature abstraction</strong> and I think it might be one if not the most costly mistake when building software.</p><p>Premature abstraction can happen on different layers of the software development process. On the lowest level, it occurs when developers introduce abstractions such as interfaces or abstract classes without a clear, immediate need. Such an abstraction can lead to overly complex and rigid code structures, hindering maintenance and scalability. In practice, you will find it difficult to modify this code, because you don&#8217;t just need to change the implementation but as well the interface. Oftentimes, such a premature optimization is <strong>justified with common best practices</strong>. e.g. adding an unnecessary interface could be argued with the <a href="https://en.wikipedia.org/wiki/SOLID">open-closed principle (SOLID)</a>.</p><p>One abstraction layer above, premature abstraction can happen when creating a system design. An example is the microservice hype of the 2010s that led to many small companies prematurely applying an architectural pattern that evolved at Big Tech companies like Amazon and Netflix. Microservices are designed for flexibility in environments, where components need to be scaled or maintained by individual teams. Most small to mid-sized companies neither have the scale nor the team size to justify the overhead of this. Yet, when I started building software in 2017, I was <strong>convinced this is what everyone does</strong>, so I also did it. After all, we wanted to be ready for Netflix-like scale. Fast forward a couple of months, my team had made every possible mistake and we learned the hard way what consistency, availability and partition tolerance (<a href="https://en.wikipedia.org/wiki/CAP_theorem">CAP</a>) look like in the presence of networks, NoSQL databases and prematurely defined boundaries. It turns out that what could have been an SQL join, can be made exponentially harder when every microservice has its own database.</p><p>Even before we design a system, we define how the teams that should implement our future design are structured. Many times, this happens before having a clear picture of the architecture of the system to build. <a href="https://en.wikipedia.org/wiki/Sociotechnical_system">Socio-technical systems theory</a> describes how people and technology interact. Within this theory, there is the famous <a href="https://en.wikipedia.org/wiki/Conway%27s_law">Conway&#8217;s law</a> which states that</p><blockquote><p>Organizations which design systems (in the broad sense used here) are constrained to produce designs which are copies of the communication structures of these organizations.</p><p>&#8212;&#8202;Melvin E. Conway, How Do Committees Invent?</p></blockquote><p>So, whatever team design we choose to start out with, will eventually result in an architecture that resembles that team design. In practice, companies tend to split their teams by product domain, function (frontend, backend, platform engineering, etc.), or project. Many times, they once again look at what successful companies have been doing before them. Whether that is the famous Two Pizza Team approach by Amazon, Squads from Spotify or Microsoft&#8217;s F-Crew. No matter the approach, whoever decides how to split teams makes <strong>assumptions about who needs to work together</strong> and which problems/domains they will own. The further those assumptions are from reality / the actual needed solution, the more overhead this design will introduce in terms of communication, planning and alignment.</p><p>In short, <strong>premature abstractions happen when assumptions are made</strong>. The more assumptions we make, the more likely we are to be wrong. Anticipating future requirements is easy and exciting and it gives us an excuse to use the latest cool framework, methodology or team setup. However, it will almost always fail and introduce an overhead in code, system design, or team collaboration. So, if we want to avoid premature abstraction, we want to make as little assumptions as possible and <a href="https://en.wikipedia.org/wiki/KISS_principle">keep things simple</a> for as long as possible. Start with</p><ul><li><p>a single concrete implementation</p></li><li><p>a single monolithic architecture</p></li><li><p>a single team</p></li></ul><p>and iterate. Once you actually need to abstract, the abstraction will emerge naturally and you can refactor. Whether that is the interface in your code, a component of your architecture that can be split out of our monolith, or a new team. Wait for it to evolve instead of trying to fix a problem that does not exist (yet). After all, we do need to abstract to manage complexity, but abstracting prematurely swings the pendulum to the other side.</p>]]></content:encoded></item><item><title><![CDATA[Why Should I Learn Algorithms?]]></title><description><![CDATA[Learning algorithms is often seen as a gatekeeper for technical interviews, but this is only partly true. Data structures and algorithms are the foundation on which software is built.]]></description><link>https://devshift.substack.com/p/why-should-i-learn-algorithms</link><guid isPermaLink="false">https://devshift.substack.com/p/why-should-i-learn-algorithms</guid><dc:creator><![CDATA[Ben Barten - Reader]]></dc:creator><pubDate>Thu, 10 Aug 2023 17:11:28 GMT</pubDate><content:encoded><![CDATA[<p>Many software engineers have a love-hate relationship with algorithms. While they are at the core of programming languages and many libraries, they play only a small role in the day-to-day work of most engineers. However, they are part of many technical interviews and are therefore seen as a gatekeeper for engineering positions. If companies would stop asking algorithmic questions in interviews, engineers would need to ask themselves: Why should I learn algorithms?</p><h2><strong>Becoming a better problem solver</strong></h2><p>Yes, you will most likely never need to perform an in-place reversal of a linked list in your job. However, what you might experience are performance issues in one of your systems, due to inefficient memory allocation. An effective solution to that problem might be very similar to how reversing a linked list works. It might also not. But without having that knowledge and understanding the underlying algorithmic patterns, you will have a hard time to come up with a creative solution. <strong>Data structures and algorithms are the foundation on which we choose technologies</strong> like storage systems. Depending on how related the entities of our application are, we might favor a SQL database over a NoSQL database. In the era of microservices, where one company uses a multitude of technologies among multiple teams, this is more important than ever.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://devshift.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading DevShift! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2><strong>About job interviews</strong></h2><p>Employers often use algorithmic exercises as a way to assess problem solving skills. As developers, we are expected to choose the right tool for the job. In most of my job interviews, I was told that it does not matter if I finish the task in the given time. What was more important was <strong>how I approached the problem</strong>. Practicing coding challenges is a good practice to not only ramp up your algorithmic skills, but also improve the way how you approach problems and work your way to a solution. Good employers will recognize this ability whether or not you found out if these two strings are an anagram or not in the given time. Are there other ways to assess these skills? Maybe. But since many companies use these exercises in their interviews, better get acquainted with it and get your dream job. Solving algorithmic problems can be a lot of fun.</p><h2><strong>Focus on hard problems</strong></h2><p>Software is eating the world. Not only our physical world, but it is also eating software development. According to a <a href="https://www.gartner.com/doc/reprints?ct=190711&amp;id=1-1FKNU1TK">Gartner report</a> the adoption of Low-Code/No-Code tools grew by 22.6% from 2020 to 2021 and will make up for 65% of software development by 2024. This means, some parts of software development will become a commodity. While this might sound scary, it opens up opportunities to <strong>focus on harder problems</strong>. The software industry is huge and so are its problems. We already live in a world where everybody expects software to work in real-time and the growing application of AI in our everyday lives demands not only data but also software engineering expertise. Skilled employees who understand software and algorithms at a deeper level will become even more valuable.</p><h2><strong>How to get started</strong></h2><p>Now that we know, why it why we should learn algorithms, here are some resources to get you started, which I found useful.</p><p>- <a href="https://www.crackingthecodinginterview.com">Cracking the Coding Interview</a></p><p>- <a href="https://www.manning.com/books/grokking-algorithms">Grokking Algorithms</a></p><p>- <a href="https://www.educative.io/courses/grokking-the-coding-interview">Grokking the Coding Interview</a></p><p>And some more famous resources, which I not yet have tried, but are on my list:</p><p>- <a href="https://www.goodreads.com/book/show/108986.Introduction_to_Algorithms">Introduction to Algorithms, by Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein</a></p><p>- <a href="https://www.goodreads.com/en/book/show/10803540-algorithms">Algortihms, by Robert Sedgewick, Kevin Wayne</a></p><p>- <a href="https://www.goodreads.com/book/show/425208.The_Algorithm_Design_Manual">The Algorithm Design Manual, by Steven S. Skiena</a></p><p>Hopefully, this has helped you to understand the value in learning algorithms and the next time you are facing a technical interview, you can motivate yourself more easily to ramp up this skill. Algorithms in technical interviews are a very controversial topic after all.</p><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://devshift.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption"></p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://devshift.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://devshift.substack.com/subscribe?"><span>Subscribe now</span></a></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://devshift.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading DevShift! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Remote Onboarding as a Software Engineer]]></title><description><![CDATA[Remote onboarding of software engineers is not only a challenge for companies but also for us as software engineers.]]></description><link>https://devshift.substack.com/p/remote-onboarding-as-a-software-engineer</link><guid isPermaLink="false">https://devshift.substack.com/p/remote-onboarding-as-a-software-engineer</guid><dc:creator><![CDATA[Ben Barten - Reader]]></dc:creator><pubDate>Thu, 10 Aug 2023 15:44:38 GMT</pubDate><content:encoded><![CDATA[<p>If you are a software developer and you have been working remotely during this pandemic, it might come as no surprise that due to recent studies <a href="https://www.techrepublic.com/article/74-of-software-engineers-abroad-are-not-interested-in-moving-to-the-us-for-work/">over 80% of software engineers want to continue working at least partly remote after the pandemic</a>. While this opens up new possibilities in the way we live and work, it comes with certain difficulties. Not only do companies need to learn how to manage their remote workforce, but also employees need to find new ways to be successful at their job while wearing no pants.</p><h2><strong>Remote onboarding is difficult</strong></h2><p>The most difficult part of working remotely is joining a new company. Companies themselves invest a lot of time and budget to work and improve on their onboarding process. If they manage to onboard their employees quickly, they will be more useful to them and their employees will be happy. But how can we as software engineers make the most of this phase?</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://devshift.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading DevShift! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ts_j!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0da4380-9819-4d77-9712-cdcf90c5fcb9_602x296.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ts_j!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0da4380-9819-4d77-9712-cdcf90c5fcb9_602x296.png 424w, https://substackcdn.com/image/fetch/$s_!ts_j!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0da4380-9819-4d77-9712-cdcf90c5fcb9_602x296.png 848w, https://substackcdn.com/image/fetch/$s_!ts_j!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0da4380-9819-4d77-9712-cdcf90c5fcb9_602x296.png 1272w, https://substackcdn.com/image/fetch/$s_!ts_j!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0da4380-9819-4d77-9712-cdcf90c5fcb9_602x296.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ts_j!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0da4380-9819-4d77-9712-cdcf90c5fcb9_602x296.png" width="602" height="296" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f0da4380-9819-4d77-9712-cdcf90c5fcb9_602x296.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:296,&quot;width&quot;:602,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:35183,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ts_j!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0da4380-9819-4d77-9712-cdcf90c5fcb9_602x296.png 424w, https://substackcdn.com/image/fetch/$s_!ts_j!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0da4380-9819-4d77-9712-cdcf90c5fcb9_602x296.png 848w, https://substackcdn.com/image/fetch/$s_!ts_j!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0da4380-9819-4d77-9712-cdcf90c5fcb9_602x296.png 1272w, https://substackcdn.com/image/fetch/$s_!ts_j!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0da4380-9819-4d77-9712-cdcf90c5fcb9_602x296.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><a href="https://twitter.com/chris_herd/status/1359135080753614854)">https://twitter.com/chris_herd/status/1359135080753614854)</a></p><p>As software engineers, we need to understand the problem we have to solve. Making sure we get this right is essential for our personal success. Moreover, in order to make a good job, we need to understand company dynamics, communication structures and find a way to socialize when there is no way to randomly meet people in the hallway.</p><h2><strong>Lay the groundwork</strong></h2><p>When you start out at a new job, the one thing you want to get right is to understand what your job actually is. Most of the times, it varies quite a lot from what the job description says. Start out and figure out what the company mission is. From there, go a step deeper and figure out what your team or department is responsible for. Ultimately, <strong>make sure you know how you fit into the puzzle</strong> and why you were hired.</p><p>Reading through the company wiki is a good start to get a broader sense of what is out there, what topics are discussed and also how well people document. Aim for broad knowledge gathering in the beginning and focus on the details later. Try to understand as quickly as possible how the development process from a commit on a feature branch to the actual production deployment works, so you yourself can be productive quickly.</p><h2><strong>Be humble and patient</strong></h2><p>Most of us are aware of <a href="https://mikeschinkel.com/2004/developerbias/">developer bias</a> for certain technologies, patterns and frameworks. However, we tend to fall into the same trap of believing our way of writing code is the way it should be done again and again. Even if you have years of experience, when you join a new team and work on a new code base stay humble and be patient. It is easy to criticize a project that evolved over years. Some things won't make sense on the first view, but on the second. Most of the times, <strong>there were good reasons why a team chose to use technology X or design a system a certain way</strong>. Even if these reasons are not viable anymore at this current point in time, try to understand why choices were made in the past. Your coworkers will fell much more respected.</p><h2><strong>Ask</strong></h2><p>Especially in the beginning of a new job, you will have a lot of questions and that is completely normal. While undisturbed, focused time is sacred to developers, you will need to ask questions to your co-workers at some point. Try to get an answer by yourself by looking at the wiki or other internal guides and documentation, but don't hesitate and waste too much time. People are usually friendly and helpful and getting quick answers will prevent bigger misunderstandings in the future.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!rAmr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe89fa602-ce53-4784-840e-80049249ec87_480x270.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!rAmr!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe89fa602-ce53-4784-840e-80049249ec87_480x270.gif 424w, https://substackcdn.com/image/fetch/$s_!rAmr!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe89fa602-ce53-4784-840e-80049249ec87_480x270.gif 848w, https://substackcdn.com/image/fetch/$s_!rAmr!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe89fa602-ce53-4784-840e-80049249ec87_480x270.gif 1272w, https://substackcdn.com/image/fetch/$s_!rAmr!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe89fa602-ce53-4784-840e-80049249ec87_480x270.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!rAmr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe89fa602-ce53-4784-840e-80049249ec87_480x270.gif" width="480" height="270" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e89fa602-ce53-4784-840e-80049249ec87_480x270.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:270,&quot;width&quot;:480,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1840192,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!rAmr!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe89fa602-ce53-4784-840e-80049249ec87_480x270.gif 424w, https://substackcdn.com/image/fetch/$s_!rAmr!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe89fa602-ce53-4784-840e-80049249ec87_480x270.gif 848w, https://substackcdn.com/image/fetch/$s_!rAmr!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe89fa602-ce53-4784-840e-80049249ec87_480x270.gif 1272w, https://substackcdn.com/image/fetch/$s_!rAmr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe89fa602-ce53-4784-840e-80049249ec87_480x270.gif 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>Communicate outside of your team</strong></h2><p>Getting in touch with co-workers outside of your team is difficult. In a remote environment, you cannot randomly meet people in the hallway or kitchen. You need to get out of your comfort zone. Ask your employer if you could join one of the other teams to get to know them and their way of work. Their might even be something like an exchange program between teams in place. Look out for projects and opportunities to work together with other teams. Maybe you have done something in the past or experience in a topic another team is working on? Share your knowledge. Your coworkers will appreciate it and you will boost your impact.</p><h2><strong>1:1s</strong></h2><p>While this also depends on your manager, making use of your personal 1:1s can help immensely with your remote onboarding experience as a software engineer. When you join a new company, you certainly have some expectations and goals in mind. Make the effort and write them down. Share them with your manager and look together if they align with the goals of your manager and the goals of the company. Try to learn what the goals of your manager are to align them with your goals. This way, you guarantee to work in the same direction and both of you share the same expectations.</p><p>After all, we are all in the same boat. Do not forget that if you fit into the job quickly, this also a success for your manager and team. Be open with your expectations and your concerns and raise any issues quickly and your coworkers will most likely repay you.</p><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://devshift.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption"></p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://devshift.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://devshift.substack.com/subscribe?"><span>Subscribe now</span></a></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://devshift.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading DevShift! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Learnings From Three Years Into Software Development Without A Degree]]></title><description><![CDATA[After more than three years into my first job as a software developer without a degree, I put my learnings into some actionable advise for anyone who is considering going this path.]]></description><link>https://devshift.substack.com/p/learnings-from-three-years-into-software</link><guid isPermaLink="false">https://devshift.substack.com/p/learnings-from-three-years-into-software</guid><dc:creator><![CDATA[Ben Barten - Reader]]></dc:creator><pubDate>Thu, 10 Aug 2023 14:24:45 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!I9_a!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42cd3780-e039-489a-9c11-a677d44fcb35_480x400.gif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Three and a half years ago, I got my first job as a software engineering intern at my current employer. At this point in time, I barely knew that Java was not only an island but also a programming language. I was coming from a complete different field of study, originally on my way to become a teacher in Germany. Today, I am leaving my employer, starting my second job as a software developer without a degree.</p><p>These are my learnings and tips for everyone considering going this path (especially in Germany).</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://devshift.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading DevShift! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p><em>Spoiler: I won't advise you to drop out of college and get into tech like so many people advocate. If you are twenty something most likely you should finish your studies or at least join a bootcamp, if this is possible for you.</em></p><h3><strong>Find a sponsor</strong></h3><p>No, not that kind of sponsor that gives you money and baseball caps. A sponsor is a person that believes in you and supports you. In Germany, getting into a company without a degree or anything to show off is near impossible. I was lucky enough to have a friend who offered me an internship position in his startup team, which was originally not even about software development. <strong>You will need someone who believes in you</strong> and supports you to a) get into the job and b) pull you through when you start struggling and questioning yourself. To get off the ground you might want to consider doing some work for little or no money to show off your potential.</p><h3><strong>Work on your social skills and learn to adapt</strong></h3><p>You can only do so much to learn and teach yourself about software development. In my experience, the best software developers were those which were also fit to <strong>work in a team</strong>. You might be surprised, but if you support others and help them reach their goals, chances are high, they will pay you back with their help. There will be many questions and sometimes you simple might not know what search for in Google. Care for your peers and they will care for you.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!I9_a!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42cd3780-e039-489a-9c11-a677d44fcb35_480x400.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!I9_a!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42cd3780-e039-489a-9c11-a677d44fcb35_480x400.gif 424w, https://substackcdn.com/image/fetch/$s_!I9_a!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42cd3780-e039-489a-9c11-a677d44fcb35_480x400.gif 848w, https://substackcdn.com/image/fetch/$s_!I9_a!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42cd3780-e039-489a-9c11-a677d44fcb35_480x400.gif 1272w, https://substackcdn.com/image/fetch/$s_!I9_a!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42cd3780-e039-489a-9c11-a677d44fcb35_480x400.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!I9_a!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42cd3780-e039-489a-9c11-a677d44fcb35_480x400.gif" width="480" height="400" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/42cd3780-e039-489a-9c11-a677d44fcb35_480x400.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:400,&quot;width&quot;:480,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1882541,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!I9_a!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42cd3780-e039-489a-9c11-a677d44fcb35_480x400.gif 424w, https://substackcdn.com/image/fetch/$s_!I9_a!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42cd3780-e039-489a-9c11-a677d44fcb35_480x400.gif 848w, https://substackcdn.com/image/fetch/$s_!I9_a!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42cd3780-e039-489a-9c11-a677d44fcb35_480x400.gif 1272w, https://substackcdn.com/image/fetch/$s_!I9_a!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42cd3780-e039-489a-9c11-a677d44fcb35_480x400.gif 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>At some point, some of your peers will leave the company, you get a new boss or just a new team member. Every time one of those events happen, your personal situation changes with it. You will have a hard time, if you are not able to adapt to new situations, so learn to embrace change and watch out for new opportunities for yourself.</p><h3><strong>Develop a constant learning habit</strong></h3><p>If you take anything from this, it should probably be this. Software developers are knowledge workers. Every developer needs to learn new languages, frameworks or design patterns at some point. If you start with little to no knowledge in a team of peers that have some kind of education in software development, you will need to outrank them in your ability to learn something new. This seems hard (and it is), but if you manage to do it, it has the nice side effect that you will likely keep this habit throughout your career.</p><p>Just to be clear: this does not mean to work 12+ hours a day, but to <strong>improve the way you learn and work</strong>. There is a whole industry around productivity. Look out for ways to improve the quality of your work rather than the pure amount of time you work. Working 40 hours a week in front of a screen is exhausting. I have done the same mistake and I have seen many peers do it: working 60+ hours a week, because you just want to finish that feature or fix that bug. Get some sleep and take breaks and fixing that bug, which would have taken you four hours after a hard working day, might just be fixed in a couple of minutes the next morning.</p><h3><strong>Favour fundamentals over frameworks</strong></h3><p>Especially at the beginning of your journey the amount of frameworks, languages and design patterns seems overwhelming and staggering. While you probably will need to learn some framework for your job, <strong>focus your studies on fundamental concepts of software development</strong>. I was working for a company doing mainly backend web development, so I had to teach myself everything from HTTP over databases to a suitable language like Java. There are many great resources out there, but if you are trying to get into web development, I recommend taking a look at <a href="https://github.com/kamranahmedse/developer-roadmap">these developer roadmaps</a> or your welcome to reach out to <a href="mailto:contact@benbarten.com">me</a>. You will have a much easier time following a structured learning path than I had blindly stumbling from one topic to another and hammering my peers with questions.</p><h3><strong>T-shaped skills</strong></h3><p>As described above, you should pick a niche in software development. It is easy to jump from one broad topic to the other, because there is so much out there in surely a real developer knows everything about them, don't they?</p><p>They don't.</p><p>As developers we all specialise in something and this is important. If you are looking for jobs, you want to differentiate yourself from others and most companies have specific requirements for the people they hire. There is a well-known concept among developers, which is called the <a href="https://medium.com/quick-code/what-it-is-a-t-shaped-developer-and-why-you-should-be-one-e87293e4bb84">T-shaped developer</a>. It is based on the notion to specialise in one topic and then develop broader understanding of other topics around that.</p><h3><strong>Take responsibility and get shit done</strong></h3><p>Even though the mantra of developing a "get things done"-attitude seems kind of obsolete, it is not. If you take responsibility and commit to goals with your team lead, you do not only develop a better feeling to estimate the time of your work, you actually learn to "own" your work. There are only few things more rewarding than working on something that is actually yours. This can lift you through hard days when you may lack motivation and it will show your boss and peers that you actually care and they can rely on you.</p><p>To make this happen you will also need to let some things go and <strong>learn to prioritise.</strong> From my experience, there is no need for a super framework or tool to organise your work. I use very simple and effective methods:</p><ul><li><p>Define your goals for the next six months</p></li><li><p>Choose a simple tool to manage your day to day tasks (I personally prefer KanBan boards)</p></li><li><p>Define your daily tasks on the evening before, starting with the most important to the least important.</p></li><li><p>Every morning, check if your tasks today are in line with your long term goals. Try to eliminate everything that is not.</p></li><li><p>Be consistent with your daily tasks but be flexible with goals, if new opportunities arise.</p></li></ul><p>The hard part here is to really be consistent in prioritising the right tasks and then sticking to them. Defining my tasks on the evening before is probably the most valuable productivity hack. If you start planning your day in the morning, you are tempted to avoid difficult tasks.</p><h3><strong>Promote yourself</strong></h3><p>One thing many people feel uncomfortable with, including me, is promoting themselves. As a software developer without a degree you will need to do this at least to some extent. You do not need to be a Twitter influencer with 100k followers, but you should <strong>make sure to always have an up-to-date <a href="https://linkedin.com">LinkedIn</a> profile</strong> , a <a href="https://github.com">GitHub</a> profile with some projects that showcase your skills and a CV. I do like <a href="https://twitter.com">Twitter</a> as well, since you can easily connect with people from the tech industry, but it has not provided any value in terms of getting a new job or project so far.</p><p>Setting up a small portfolio or blog like this one can also be beneficial. First, you have one platform that you own to link to all your social media accounts and promote yourself. Second, blogging about what you learn and do does not only help with promoting, but also with understanding more deeply what you write about. I am not super consistent with blogging so far, but every time I do, I am surprised by how much value I get out of it for myself. Third, building a blog can be a perfect sample project to showcase your engineering skills.</p><h3><strong>Conclusion</strong></h3><p>As I mentioned in the beginning, I would not advise you to take this path, if you have the possibility, time and money to get a proper education in computer science. Having a degree and something that proves your skills will make your life much easier and less stressful. But if you do not have that for any reason, it can be done and the job as a software developer can be very rewarding one, not just financially.</p><p>If you are considering a career in software development without a degree, I would love to know more about where you are at and I hope my learnings were helpful. Feel free to reach out to me.</p><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://devshift.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption"></p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://devshift.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://devshift.substack.com/subscribe?"><span>Subscribe now</span></a></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://devshift.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading DevShift! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[API Usability Testing in 8 Simple Steps]]></title><description><![CDATA[If you are building an API product, user experience should be on top of your mind as for any other product.]]></description><link>https://devshift.substack.com/p/api-usability-testing-in-8-simple</link><guid isPermaLink="false">https://devshift.substack.com/p/api-usability-testing-in-8-simple</guid><dc:creator><![CDATA[Ben Barten - Reader]]></dc:creator><pubDate>Thu, 10 Aug 2023 14:00:32 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!yp3_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7e9067d-af8e-44de-bf3e-9f5e61d456a0_1438x1184.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you are building an API product, user experience should be at the top of your mind. Testing your APIs for usability is crucial to offer your customers the</p><p>best experience possible. While there are many people who offer usability tests for user-facing products, API usability testing is a bit more tricky, since</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://devshift.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading DevShift! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>your customers are developers.</p><p>In this blog post, I will provide you with a guide on how you can get started with API usability testing without burning through your valuable startup budget. We</p><p>will look at when to test, who to test and <strong>eight simple steps</strong> to organize your testing.</p><h2><strong>The Timing</strong></h2><p>The best time to start usability testing is right at the beginning of your project. If you have not done that, the second best time is now.</p><p>It is true. Do not fall into the trap of testing your APIs for usability shortly before a release. <strong>Make it part of your development process</strong> early on and gather feedback as early as possible, so you can iterate on that feedback and change your product while it is easy to do so.</p><p>If you are working in a somehow agile development process, which I will assume at this point, your development cycle will probably look something like this.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!yp3_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7e9067d-af8e-44de-bf3e-9f5e61d456a0_1438x1184.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!yp3_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7e9067d-af8e-44de-bf3e-9f5e61d456a0_1438x1184.png 424w, https://substackcdn.com/image/fetch/$s_!yp3_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7e9067d-af8e-44de-bf3e-9f5e61d456a0_1438x1184.png 848w, https://substackcdn.com/image/fetch/$s_!yp3_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7e9067d-af8e-44de-bf3e-9f5e61d456a0_1438x1184.png 1272w, https://substackcdn.com/image/fetch/$s_!yp3_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7e9067d-af8e-44de-bf3e-9f5e61d456a0_1438x1184.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!yp3_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7e9067d-af8e-44de-bf3e-9f5e61d456a0_1438x1184.png" width="1438" height="1184" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c7e9067d-af8e-44de-bf3e-9f5e61d456a0_1438x1184.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1184,&quot;width&quot;:1438,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:39535,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!yp3_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7e9067d-af8e-44de-bf3e-9f5e61d456a0_1438x1184.png 424w, https://substackcdn.com/image/fetch/$s_!yp3_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7e9067d-af8e-44de-bf3e-9f5e61d456a0_1438x1184.png 848w, https://substackcdn.com/image/fetch/$s_!yp3_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7e9067d-af8e-44de-bf3e-9f5e61d456a0_1438x1184.png 1272w, https://substackcdn.com/image/fetch/$s_!yp3_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7e9067d-af8e-44de-bf3e-9f5e61d456a0_1438x1184.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The best time to do your usability testing is after you have designed your product or in our case, the API.</p><p>With modern tools like <a href="https://swagger.io">Swagger</a> and the <a href="https://www.openapis.org">OpenAPI</a> standard you can easily generate <a href="https://swagger.io/solutions/mocking-and-virtualization/">Mock APIs</a> which can then be used for usability testing with real users or your team.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!yZvX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c840cbf-3b81-4683-8332-76bae46dd1f9_1440x1184.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!yZvX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c840cbf-3b81-4683-8332-76bae46dd1f9_1440x1184.png 424w, https://substackcdn.com/image/fetch/$s_!yZvX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c840cbf-3b81-4683-8332-76bae46dd1f9_1440x1184.png 848w, https://substackcdn.com/image/fetch/$s_!yZvX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c840cbf-3b81-4683-8332-76bae46dd1f9_1440x1184.png 1272w, https://substackcdn.com/image/fetch/$s_!yZvX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c840cbf-3b81-4683-8332-76bae46dd1f9_1440x1184.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!yZvX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c840cbf-3b81-4683-8332-76bae46dd1f9_1440x1184.png" width="1440" height="1184" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6c840cbf-3b81-4683-8332-76bae46dd1f9_1440x1184.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1184,&quot;width&quot;:1440,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:44552,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!yZvX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c840cbf-3b81-4683-8332-76bae46dd1f9_1440x1184.png 424w, https://substackcdn.com/image/fetch/$s_!yZvX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c840cbf-3b81-4683-8332-76bae46dd1f9_1440x1184.png 848w, https://substackcdn.com/image/fetch/$s_!yZvX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c840cbf-3b81-4683-8332-76bae46dd1f9_1440x1184.png 1272w, https://substackcdn.com/image/fetch/$s_!yZvX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c840cbf-3b81-4683-8332-76bae46dd1f9_1440x1184.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>If you do not have mock APIs and prefer to develop first, usability tests can also be done after the <strong>Development</strong> stage.</p><h2><strong>The Users</strong></h2><p>Developers come in different forms and shapes. They vary in their roles and skill sets, but also in the way they perceive content. If you can, try to determine which roles and skills your customers have and derive <strong>**user personas**</strong> from it. This will help you to view your APIs from your customers perspective and find suitable candidates for a usability test.</p><p>We will not go into detail on how to define user personas, but I recommend watching this short video by <a href="http://pluralsight.com">Pluralsight</a> to get an idea.</p><div id="youtube2-tCAeHfvsjoM)" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;tCAeHfvsjoM)&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/tCAeHfvsjoM)?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><p></p><p>In reality, we often do not know the developers who will integrate our APIs when we start developing a new API. Therefore, it is helpful to assume a broad variety of different skill sets and find users of different backgrounds. As we do not want to hire an agency and spend as little money as possible on usability testing, there are mainly two easy options:</p><ul><li><p><strong>Freelance developer platforms</strong><br><a href="https://www.upwork.com">Upwork</a>, <a href="https://www.fiverr.com">fiverr</a>, etc.. Look out for developers of various backgrounds and hire them for a 30-60 minute usability test. We will go into detail on how to do that in the next section.</p></li><li><p><strong>Onboarding of new developers</strong> <br>When a new developer joins your team, he can be tasked to make a usability test of the API. This has the nice side effect that they get to know the product/API and a unique view of how users perceive it.</p></li></ul><h2><strong>API Usability Testing in 8 Steps</strong></h2><p>To learn as much as possible from our tests, we need a bit of preparation. These are eight simple steps, to get everything out of your usability tests:</p><ol><li><p>Define an explicit task on what your tester is supposed to test.</p></li><li><p>Give as little information as possible, but as much as needed to get started with the assigned task.</p></li><li><p>Find a way to observe the user when using your API. Nowadays, where in-person meetings are less common, you can make use of screen sharing/recording tools.</p></li><li><p>Make sure, the user speaks out loud while testing your product, explaining what he or she is thinking at each step.</p></li><li><p>Provide a possibility for questions, if the user gets stuck at a certain point of the process and does not find any other option than asking for help.</p></li><li><p>Create a detailed report on the observations during the test.</p></li><li><p>Derive learnings and tasks from your observations.</p></li><li><p>Share your learnings and observations with your team.</p></li></ol><p>One other way to get started with usability testing is to do a Hackathon based on your API. This has the positive side effect that you do not only learn about the usability but also potential use cases of your API.</p><h2><strong>Conclusion</strong></h2><p>API usability testing does not have to be an expensive and tedious task. Getting started with it will immediately improve your understanding of your own product and how users perceive it. You will be astonished by how much your personal conceptions may differ from a user's fresh view on your API and your customers will thank you for providing the best user experience.</p><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://devshift.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading DevShift! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://devshift.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://devshift.substack.com/subscribe?"><span>Subscribe now</span></a></p>]]></content:encoded></item><item><title><![CDATA[Exposing microservices with an API gateway and the API composition pattern]]></title><description><![CDATA[Overview of how an API gateway and the API composition pattern can help you make your microservices architecture more accessible.]]></description><link>https://devshift.substack.com/p/exposing-microservices-with-an-api</link><guid isPermaLink="false">https://devshift.substack.com/p/exposing-microservices-with-an-api</guid><dc:creator><![CDATA[Ben Barten - Reader]]></dc:creator><pubDate>Thu, 10 Aug 2023 13:51:42 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!O4N2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f87b117-f1d2-455d-b169-7a88b1f91901_764x585.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Microservices are a widely spread pattern in modern software architectures. Tools like <a href="https://www.docker.com">Docker</a>, <a href="https://kubernetes.io">Kubernetes</a> and modern CI/CD pipelines have enabled software teams to build highly scalable distributed systems in which each microservice can be operated by a small team. In fact, the implicit notion of microservices is to be self-contained and focused on a single purpose. Thus, implemented correctly, microservices enable your system to be highly flexible and your teams to operate independently. While this is a major upside for the development process itself, it comes with certain challenges when you want to expose your system to external users.</p><p>Check out this <a href="https://www.nginx.com/blog/introduction-to-microservices/">well-written blog series of NGINX</a>, if you want to get deeper into microservices architecture.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://devshift.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading DevShift! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h3><strong>Flexibility leads to complexity</strong></h3><p>Don't get me wrong. The microservices pattern takes away a lot of complexity introduced by highly cohesive and monolithic systems, but it introduces a new kind of complexity. The fact that teams are flexible in the way they build their microservices - even if you have certain guidelines in place - makes it more difficult for your clients to access your system. They possibly need to</p><p>- talk with all the different services</p><p>- understand which service provides the data they need</p><p>- communicate via different protocols.</p><p>In terms of user experience, this is not optimal and might lead to frustration on the client side. The <strong>complexity increases the learning curve of your system</strong>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!O4N2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f87b117-f1d2-455d-b169-7a88b1f91901_764x585.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!O4N2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f87b117-f1d2-455d-b169-7a88b1f91901_764x585.png 424w, https://substackcdn.com/image/fetch/$s_!O4N2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f87b117-f1d2-455d-b169-7a88b1f91901_764x585.png 848w, https://substackcdn.com/image/fetch/$s_!O4N2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f87b117-f1d2-455d-b169-7a88b1f91901_764x585.png 1272w, https://substackcdn.com/image/fetch/$s_!O4N2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f87b117-f1d2-455d-b169-7a88b1f91901_764x585.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!O4N2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f87b117-f1d2-455d-b169-7a88b1f91901_764x585.png" width="764" height="585" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9f87b117-f1d2-455d-b169-7a88b1f91901_764x585.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:585,&quot;width&quot;:764,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:45788,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!O4N2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f87b117-f1d2-455d-b169-7a88b1f91901_764x585.png 424w, https://substackcdn.com/image/fetch/$s_!O4N2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f87b117-f1d2-455d-b169-7a88b1f91901_764x585.png 848w, https://substackcdn.com/image/fetch/$s_!O4N2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f87b117-f1d2-455d-b169-7a88b1f91901_764x585.png 1272w, https://substackcdn.com/image/fetch/$s_!O4N2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f87b117-f1d2-455d-b169-7a88b1f91901_764x585.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>A simplified overview of clients A,B and C which require different data from individual services X,Y, and Z of a microservice architecture. All are accessible via different protocols: REST, GraphQL and gRPC.</em></p><p>The picture above illustrates such a microservice architecture. Even if your microservices do not use different communication protocols such as in this example: Talking to multiple hosts might still require multiple ways of authentication, understanding different styles of API design, etc..</p><h3><strong>An API gateway as the single entry point</strong></h3><p>An API gateway might help you with this complexity. As the term "gateway" implies, the main purpose of an API gateway is to be the single entry point for your microservice architecture. It is build on top of your individual services and routes requests of clients to these services. It does <strong>not contain or know of any business or domain logic</strong> of the individual services.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!bKTq!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa833e4be-4b3d-4af7-ba04-0ab45d785eec_1526x1502.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!bKTq!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa833e4be-4b3d-4af7-ba04-0ab45d785eec_1526x1502.png 424w, https://substackcdn.com/image/fetch/$s_!bKTq!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa833e4be-4b3d-4af7-ba04-0ab45d785eec_1526x1502.png 848w, https://substackcdn.com/image/fetch/$s_!bKTq!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa833e4be-4b3d-4af7-ba04-0ab45d785eec_1526x1502.png 1272w, https://substackcdn.com/image/fetch/$s_!bKTq!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa833e4be-4b3d-4af7-ba04-0ab45d785eec_1526x1502.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!bKTq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa833e4be-4b3d-4af7-ba04-0ab45d785eec_1526x1502.png" width="1456" height="1433" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a833e4be-4b3d-4af7-ba04-0ab45d785eec_1526x1502.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1433,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:105762,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!bKTq!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa833e4be-4b3d-4af7-ba04-0ab45d785eec_1526x1502.png 424w, https://substackcdn.com/image/fetch/$s_!bKTq!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa833e4be-4b3d-4af7-ba04-0ab45d785eec_1526x1502.png 848w, https://substackcdn.com/image/fetch/$s_!bKTq!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa833e4be-4b3d-4af7-ba04-0ab45d785eec_1526x1502.png 1272w, https://substackcdn.com/image/fetch/$s_!bKTq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa833e4be-4b3d-4af7-ba04-0ab45d785eec_1526x1502.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>An API gateway sitting between your microservices and the clients who want to access these services. The API gateway provides a unified interface to the clients and hides implementation details of the services X, Y, and Z.</em></p><h3><strong>Upsides of API gateways</strong></h3><p>As the illustration shows, an API gateway makes it possible to easily hide implementation details of our microservice architecture and unify the external interface. This enables clients to have a single point of entry to your system, thus, making it more accessible. Besides these UX improvements, the API gateway can be used to centralize and handle topics such as</p><p>- authentication</p><p>- permission handling</p><p>- API security</p><p>- policies (rate limits, allow-listing, etc.)</p><p>This <strong>enables the individual microservice teams to concentrate on the core business/domain logic</strong> of their service and improves development speed. The API gateway might further support your system by providing extensive (access) logging and collecting performance as well as business related metrics of your clients.</p><h3><strong>Downsides of API gateways</strong></h3><p>Introducing a new part in your architecture always comes with certain challenges and so does an API gateway. The API gateway is another piece of software in our system that has to be developed, deployed and maintained. While this was also one of the upsides listed above, a single point of entry to our application might also become a <strong>bottleneck</strong> in two different ways.</p><p>First, it has to be highly scalable. Since it is another layer between every request of the client and our microservices, it needs to have as little impact on the request latency as possible. Second, it can slow down development, since every microservice has to be exposed via the gateway.</p><h3><strong>The API composition pattern</strong></h3><p>So far, we have introduced the API gateway simply to route each request of a client to a microservice and back. With microservices being self-contained and the owner of their domain and data models, they often fail the expectations of clients on how to consume the data. Clients might want to query data of multiple sub-domains at the same time or just a small portion of the data a single microservice offers. To fit these needs, the API composition pattern can be applied.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!BExt!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99224804-4b87-42ea-8f45-8c96f40bb675_787x762.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!BExt!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99224804-4b87-42ea-8f45-8c96f40bb675_787x762.png 424w, https://substackcdn.com/image/fetch/$s_!BExt!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99224804-4b87-42ea-8f45-8c96f40bb675_787x762.png 848w, https://substackcdn.com/image/fetch/$s_!BExt!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99224804-4b87-42ea-8f45-8c96f40bb675_787x762.png 1272w, https://substackcdn.com/image/fetch/$s_!BExt!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99224804-4b87-42ea-8f45-8c96f40bb675_787x762.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!BExt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99224804-4b87-42ea-8f45-8c96f40bb675_787x762.png" width="787" height="762" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/99224804-4b87-42ea-8f45-8c96f40bb675_787x762.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:762,&quot;width&quot;:787,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:43073,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!BExt!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99224804-4b87-42ea-8f45-8c96f40bb675_787x762.png 424w, https://substackcdn.com/image/fetch/$s_!BExt!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99224804-4b87-42ea-8f45-8c96f40bb675_787x762.png 848w, https://substackcdn.com/image/fetch/$s_!BExt!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99224804-4b87-42ea-8f45-8c96f40bb675_787x762.png 1272w, https://substackcdn.com/image/fetch/$s_!BExt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99224804-4b87-42ea-8f45-8c96f40bb675_787x762.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>Overview of an API gateway with API composition. Composition 1 composes data of service X and Y to a single resource, while Composition 2 composes data of service Y and Z to a single resource.</em></p><p>Even though the API composition now manipulates the payloads of one or multiple microservice(s), an API composition still remains free of any domain or business logic. Each composition could also be defined as an aggregate of the microservices behind the API gateway to <strong>fit the clients need</strong> and improve the developer experience.</p><p>This pattern introduces some more advantages. With API composition in place, we suddenly can</p><p>- make up for bad design decisions and apply a new shiny interface</p><p>- hide legacy systems and replace these whenever we have the time for it</p><p>- enable specialists for API design and developer experience to create a consistent design of the overall API.</p><p>On the other hand, as with the API gateway itself, we introduce another layer in our overall system. Development teams have to be careful that API composition does not evolve to a replacement for good API design of the individual microservices or mixing up the domain logic and models within the API gateway.</p><h3><strong>Conclusion</strong></h3><p>API gateways and API composition are a useful tool to reduce complexity of microservice architectures. They can help with handling access and monitoring of the overall system, as well as enabling clients to request data as they expect it. Nevertheless, one has to be careful when introducing a new layer to a system, since it inevitably leads to more dependencies in the development chain.</p><p>What do you think of this approach? Have you faced similar challenges? If yes, how did you solve them?</p><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://devshift.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading DevShift! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Docker Hands-On Start for Developers]]></title><description><![CDATA[A hands-on guide on how to get started with Docker. Explore containers and images and containerize a simple Node.js app.]]></description><link>https://devshift.substack.com/p/docker-hands-on-start-for-developers</link><guid isPermaLink="false">https://devshift.substack.com/p/docker-hands-on-start-for-developers</guid><dc:creator><![CDATA[Ben Barten - Reader]]></dc:creator><pubDate>Thu, 10 Aug 2023 09:42:10 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!mAK1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a6cc417-0cec-44ae-bf92-98cfd10f324e_1510x636.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you are working as a software developer in 2019, you probably have heard about <a href="https://www.docker.com">Docker</a>. In fact, by now over 20% of all hosts are running <a href="https://www.docker.com">Docker</a> with increasing numbers for the upcoming years.</p><p>If you have no experience and you want to get started with this technology, you have come to the right place. You will get a succinct overview of the topic and some best practices on how to leverage <a href="https://www.docker.com">Docker</a> for your own projects or your projects at work.In this part, we will learn a short definition of the technology and we will dive into more detail on the basic elements of <a href="https://www.docker.com">Docker</a>: images&nbsp;and containers. To get some immediate hands-on experience, we will build our own docker image&nbsp;and spin up containers from it.&nbsp;</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://devshift.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading DevShift! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h3><strong>Contents</strong></h3><ul><li><p>What is Docker?</p></li><li><p>Images</p></li><li><p>Containerizing your application</p></li><li><p>Containers</p></li><li><p>Best Practices</p></li></ul><h3><strong>What is Docker?</strong></h3><p>You probably know about the concept of virtual machines (VMs). VMs are simulating operating systems with system-specific pre-installed software. They are managed by a hypervisor (virtual machine monitor) which manages and shares hardware for multiple VMs on a single physical machine. VMs need a big amount of memory and computing power and therefore are expensive to setup and maintain. Furthermore, moving VM workloads between hypervisors and cloud platforms is not as easy and intuitive as it could be.&nbsp;</p><p>In contrary,<a href="https://www.docker.com">Docker</a> or other containerization technologies are running on the host operating system (OS). Containers contain your application code, dependencies, your runtime system and system libraries, settings and tools. That is it. Nothing more than the bare minimum of what you need to run your application. They do not need a full-blown OS to setup, instead they free up a lot of CPU, RAM and storage for running applications. As long as a host has the <a href="https://www.docker.com">Docker</a> Engine running, you can easily port <a href="https://www.docker.com">Docker</a> containers from one host to another. You will never have to worry, what kind of server your application is running on or how to ship between hypervisors. You simply pick or create your own docker image&nbsp;and focus on developing your software.</p><p>This image visualisation is copied from the <a href="https://www.docker.com">Docker</a> website and illustrates the difference:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!mAK1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a6cc417-0cec-44ae-bf92-98cfd10f324e_1510x636.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mAK1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a6cc417-0cec-44ae-bf92-98cfd10f324e_1510x636.jpeg 424w, https://substackcdn.com/image/fetch/$s_!mAK1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a6cc417-0cec-44ae-bf92-98cfd10f324e_1510x636.jpeg 848w, https://substackcdn.com/image/fetch/$s_!mAK1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a6cc417-0cec-44ae-bf92-98cfd10f324e_1510x636.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!mAK1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a6cc417-0cec-44ae-bf92-98cfd10f324e_1510x636.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!mAK1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a6cc417-0cec-44ae-bf92-98cfd10f324e_1510x636.jpeg" width="1456" height="613" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6a6cc417-0cec-44ae-bf92-98cfd10f324e_1510x636.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:613,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:398386,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!mAK1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a6cc417-0cec-44ae-bf92-98cfd10f324e_1510x636.jpeg 424w, https://substackcdn.com/image/fetch/$s_!mAK1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a6cc417-0cec-44ae-bf92-98cfd10f324e_1510x636.jpeg 848w, https://substackcdn.com/image/fetch/$s_!mAK1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a6cc417-0cec-44ae-bf92-98cfd10f324e_1510x636.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!mAK1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a6cc417-0cec-44ae-bf92-98cfd10f324e_1510x636.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Source:&nbsp;<a href="https://www.docker.com/resources/what-container#/package_software">https://www.docker.com/resources/what-container#/package_software</a></p><h3><strong>Images</strong></h3><p>As a developer, you should be familiar with the concept of object-oriented programming. In a way, you can think of images&nbsp;as classes and containers&nbsp;as objects. Images&nbsp;are your templates to build containers on.</p><p>To start out, you usually pull&nbsp;an image from a docker registry&nbsp;like <a href="https://hub.docker.com">Docker Hub</a>. Images are made of one or multiple stacked read-only layers. The only writable layer is build by the container&nbsp;as the illustration below shows. We will discuss what exactly a layer is in a minute.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!GupQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F004b295a-d484-4384-962c-7a7f9bf7779e_1480x904.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!GupQ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F004b295a-d484-4384-962c-7a7f9bf7779e_1480x904.jpeg 424w, https://substackcdn.com/image/fetch/$s_!GupQ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F004b295a-d484-4384-962c-7a7f9bf7779e_1480x904.jpeg 848w, https://substackcdn.com/image/fetch/$s_!GupQ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F004b295a-d484-4384-962c-7a7f9bf7779e_1480x904.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!GupQ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F004b295a-d484-4384-962c-7a7f9bf7779e_1480x904.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!GupQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F004b295a-d484-4384-962c-7a7f9bf7779e_1480x904.jpeg" width="1456" height="889" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/004b295a-d484-4384-962c-7a7f9bf7779e_1480x904.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:889,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:795879,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!GupQ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F004b295a-d484-4384-962c-7a7f9bf7779e_1480x904.jpeg 424w, https://substackcdn.com/image/fetch/$s_!GupQ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F004b295a-d484-4384-962c-7a7f9bf7779e_1480x904.jpeg 848w, https://substackcdn.com/image/fetch/$s_!GupQ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F004b295a-d484-4384-962c-7a7f9bf7779e_1480x904.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!GupQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F004b295a-d484-4384-962c-7a7f9bf7779e_1480x904.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>Source:&nbsp;<a href="https://docs.docker.com/v17.09/engine/userguide/storagedriver/imagesandcontainers/#container-and-layers">https://docs.docker.com/v17.09/engine/userguide/storagedriver/imagesandcontainers/#container-and-layers</a></p><h4><strong>Getting started</strong></h4><p>So, to dive deeper, let&#8217;s start and play around with <a href="https://www.docker.com">Docker</a>. If you have not done so already, go <a href="https://docs.docker.com/install/">here</a>&nbsp;and install the <a href="https://docs.docker.com/engine/">Docker Engine</a>&nbsp;on your host. When you&#8217;re done, open your command line tool and type:</p><pre><code><code>docker pull node:latest</code></code></pre><p>Congratulations! You have pulled your first <a href="https://www.docker.com">Docker</a> image. Let&#8217;s look at what happened here:</p><p>The <code>docker pull</code> command initiates a call to a Docker registry (the default is&nbsp; <a href="https://hub.docker.com">Docker Hub</a>)&nbsp;to pull an image with the name <code>node</code>&nbsp;and the tag <code>latest</code>. A <a href="https://www.docker.com">Docker</a> registry&nbsp;serves as a storage server for docker images. From the command above, we can deduce the following syntax: </p><pre><code><code>docker pull &lt;name&gt;:&lt;tag&gt;</code>&nbsp;</code></pre><p>The <code>name</code> specifies the name of the image and the <code>tag</code> specifies the version of a particular image. (Attention: Image tags are mutable. To make sure, you can rely on an image version, you might want to consider <a href="https://success.docker.com/article/images-tagging-vs-digests">image digests</a>).&nbsp;</p><p>In this case, we pulled an image with a pre-installed version of Node.js. Your output should look like this</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Mss2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F859d03c2-0b4c-4f52-b5bd-e6fb26bd589f_1516x356.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Mss2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F859d03c2-0b4c-4f52-b5bd-e6fb26bd589f_1516x356.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Mss2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F859d03c2-0b4c-4f52-b5bd-e6fb26bd589f_1516x356.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Mss2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F859d03c2-0b4c-4f52-b5bd-e6fb26bd589f_1516x356.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Mss2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F859d03c2-0b4c-4f52-b5bd-e6fb26bd589f_1516x356.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Mss2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F859d03c2-0b4c-4f52-b5bd-e6fb26bd589f_1516x356.jpeg" width="1456" height="342" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/859d03c2-0b4c-4f52-b5bd-e6fb26bd589f_1516x356.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:342,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:579294,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Mss2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F859d03c2-0b4c-4f52-b5bd-e6fb26bd589f_1516x356.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Mss2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F859d03c2-0b4c-4f52-b5bd-e6fb26bd589f_1516x356.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Mss2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F859d03c2-0b4c-4f52-b5bd-e6fb26bd589f_1516x356.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Mss2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F859d03c2-0b4c-4f52-b5bd-e6fb26bd589f_1516x356.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><h4><strong>Working with images</strong></h4><p>Let&#8217;s have a closer look at the image we just pulled. Execute the following command in your terminal:</p><pre><code>docker images</code></pre><p>This will return a list of all your images like this</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cItz!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb892f82-c06c-4b39-bc13-584fb8276a98_1518x76.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cItz!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb892f82-c06c-4b39-bc13-584fb8276a98_1518x76.jpeg 424w, https://substackcdn.com/image/fetch/$s_!cItz!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb892f82-c06c-4b39-bc13-584fb8276a98_1518x76.jpeg 848w, https://substackcdn.com/image/fetch/$s_!cItz!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb892f82-c06c-4b39-bc13-584fb8276a98_1518x76.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!cItz!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb892f82-c06c-4b39-bc13-584fb8276a98_1518x76.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cItz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb892f82-c06c-4b39-bc13-584fb8276a98_1518x76.jpeg" width="1456" height="73" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/db892f82-c06c-4b39-bc13-584fb8276a98_1518x76.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:73,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:171959,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!cItz!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb892f82-c06c-4b39-bc13-584fb8276a98_1518x76.jpeg 424w, https://substackcdn.com/image/fetch/$s_!cItz!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb892f82-c06c-4b39-bc13-584fb8276a98_1518x76.jpeg 848w, https://substackcdn.com/image/fetch/$s_!cItz!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb892f82-c06c-4b39-bc13-584fb8276a98_1518x76.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!cItz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb892f82-c06c-4b39-bc13-584fb8276a98_1518x76.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>You can see the name of the image, the tag we specified before, a unique image id, a timestamp when it was created and the size of the image. To further inspect the image execute:</p><pre><code>docker inspect node:latest</code></pre><p>Here you can see a lot of metadata for the image like the size of the image, the different layers, the underlying OS and much more. We will come back to the <code>inspect</code> command in the the <strong>Best Practices</strong> section.</p><p>Now, let's remove the image with:</p><pre><code>docker rmi node:latest</code></pre><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!C-pw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61fee0d3-ea78-4550-9a84-9adfafdd4939_1512x328.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!C-pw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61fee0d3-ea78-4550-9a84-9adfafdd4939_1512x328.jpeg 424w, https://substackcdn.com/image/fetch/$s_!C-pw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61fee0d3-ea78-4550-9a84-9adfafdd4939_1512x328.jpeg 848w, https://substackcdn.com/image/fetch/$s_!C-pw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61fee0d3-ea78-4550-9a84-9adfafdd4939_1512x328.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!C-pw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61fee0d3-ea78-4550-9a84-9adfafdd4939_1512x328.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!C-pw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61fee0d3-ea78-4550-9a84-9adfafdd4939_1512x328.jpeg" width="1456" height="316" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/61fee0d3-ea78-4550-9a84-9adfafdd4939_1512x328.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:316,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:865075,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!C-pw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61fee0d3-ea78-4550-9a84-9adfafdd4939_1512x328.jpeg 424w, https://substackcdn.com/image/fetch/$s_!C-pw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61fee0d3-ea78-4550-9a84-9adfafdd4939_1512x328.jpeg 848w, https://substackcdn.com/image/fetch/$s_!C-pw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61fee0d3-ea78-4550-9a84-9adfafdd4939_1512x328.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!C-pw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61fee0d3-ea78-4550-9a84-9adfafdd4939_1512x328.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>This way, we removed the image and the respective layers of the image from our Docker host.</p><p>Note that all these commands can be executed with the image id, but they will only work, as long as no container based on the image is running. To understand how images are built and why they are structured into layers, we will build a simple Node.js server,&nbsp;containerize it and spin up our first containers from it.</p><h3><strong>Containerizing your application</strong></h3><p>To keep things simple, I set up a simple Node.js server. You can find the source code <a href="https://github.com/bbenzo/docker-for-devs-1">here</a>. For this example, you do not need any experience with Node.js. You simply need to have <code>node</code> and the node package manager <code>npm</code> installed and follow along the tutorial. You can install both as described <a href="https://www.npmjs.com/get-npm">here</a>.</p><p>Clone the repository, <code>cd</code> into the repository&#8217;s folder and execute the following commands to build the application and install all dependencies.</p><pre><code>npm install &amp;&amp; npm run build</code></pre><p>Now, let&#8217;s run the server with</p><pre><code>npm start</code></pre><p>Now, our server should be running. If you navigate your browser to <code>http://localhost:8080</code>, you should see a "Hello World of Docker"&nbsp;message.</p><p>Great! Now, let&#8217;s see how we can make an image of this application and spin up a container&nbsp;of it. Remember, our image&nbsp;is our template for all our containers and it should do only one thing: run our application.</p><p>In the project repository, create a new file and name it <code>Dockerfile</code>. In there, copy the following code:</p><pre><code>FROM node:latest
WORKDIR app
COPY . .
RUN npm install &amp;&amp; npm run build
EXPOSE 8080
ENTRYPOINT ["npm", "start"]</code></pre><p>To build your image, execute <code>docker build -t my-first-docker .</code> in the same directory as your <code>Dockerfile</code>. You should see the different steps building. When we execute <code>docker images</code>, we can see our newly created image:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!jsvL!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8914708-7529-4768-8452-95fe0c66665a_1508x116.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!jsvL!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8914708-7529-4768-8452-95fe0c66665a_1508x116.jpeg 424w, https://substackcdn.com/image/fetch/$s_!jsvL!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8914708-7529-4768-8452-95fe0c66665a_1508x116.jpeg 848w, https://substackcdn.com/image/fetch/$s_!jsvL!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8914708-7529-4768-8452-95fe0c66665a_1508x116.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!jsvL!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8914708-7529-4768-8452-95fe0c66665a_1508x116.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!jsvL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8914708-7529-4768-8452-95fe0c66665a_1508x116.jpeg" width="1456" height="112" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d8914708-7529-4768-8452-95fe0c66665a_1508x116.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:112,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:256008,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!jsvL!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8914708-7529-4768-8452-95fe0c66665a_1508x116.jpeg 424w, https://substackcdn.com/image/fetch/$s_!jsvL!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8914708-7529-4768-8452-95fe0c66665a_1508x116.jpeg 848w, https://substackcdn.com/image/fetch/$s_!jsvL!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8914708-7529-4768-8452-95fe0c66665a_1508x116.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!jsvL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8914708-7529-4768-8452-95fe0c66665a_1508x116.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>There are two kind of instructions in a <code>Dockerfile</code>. Those, which add data and therefore create a new layer&nbsp;and those which simply add metadata to the image. I will walk you through those steps and explain in detail what they are doing.</p><p>The <code>FROM</code> command specifies a base image, on which we want to build our image. In our case, we use the latest image from the node repository. This image has Node.js pre-installed since we want to build a Node.js server. In general, it is recommended to use base images from official repositories since you do not have to worry about installing Node.js properly.&nbsp;</p><p><code>WORKDIR</code> creates a working directory for your application. It is seen as best practice, because we avoid unreadable syntax like <code>cd .. &amp;&amp; do foo</code>. The working directory will be your default directory in which the following RUN, COPY, etc. commands will be executed. Our working directory will be <code>app</code>.</p><p><code>COPY</code> copies files from your project directory into the <a href="https://www.docker.com">Docker</a> image. For now, we will just copy all files in our working directory, even though this is not considered best practice. Notice: this is the first time we are adding data to our image. Thus, this instruction creates a new layer&nbsp;in your image. Each instruction of this type creates its own layer.</p><p><code>RUN</code> executes a command in the default shell of the image. Since it adds data, it creates another layer.&nbsp;In our case, we add data by installing all dependencies with <code>npm install</code> and building the compiled files with <code>npm run build</code>.</p><p><code>EXPOSE</code> exposes a specified network port for our container.</p><p><code>ENTRYPOINT</code> sets a default shell command, which will we be executed when we start a container&nbsp;and run it. This command makes the <a href="https://www.docker.com">Docker</a> image an executable when run. We could also use the <code>CMD</code> instruction to achieve this behaviour. Nevertheless, it is recommended to set <code>ENTRYPOINT</code> whenever you want your users to use this image in a specific way. If you want to give your users more flexibility, choose <code>CMD</code>, because it can be overwritten more easily.</p><h3><strong>Containers</strong></h3><p>As explained, containers&nbsp;are the runtime counterpart to images. Containers accept an image and a command as arguments. The image is used to run the container and the command specifies the application, the container should run. Let&#8217;s use our example to elaborate on this. Run:</p><pre><code>docker run -it my-first-docker</code></pre><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!AWjB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b78f9f9-c047-480f-aa58-b084b1291a46_1488x214.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!AWjB!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b78f9f9-c047-480f-aa58-b084b1291a46_1488x214.jpeg 424w, https://substackcdn.com/image/fetch/$s_!AWjB!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b78f9f9-c047-480f-aa58-b084b1291a46_1488x214.jpeg 848w, https://substackcdn.com/image/fetch/$s_!AWjB!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b78f9f9-c047-480f-aa58-b084b1291a46_1488x214.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!AWjB!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b78f9f9-c047-480f-aa58-b084b1291a46_1488x214.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!AWjB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b78f9f9-c047-480f-aa58-b084b1291a46_1488x214.jpeg" width="1456" height="209" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3b78f9f9-c047-480f-aa58-b084b1291a46_1488x214.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:209,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:426740,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!AWjB!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b78f9f9-c047-480f-aa58-b084b1291a46_1488x214.jpeg 424w, https://substackcdn.com/image/fetch/$s_!AWjB!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b78f9f9-c047-480f-aa58-b084b1291a46_1488x214.jpeg 848w, https://substackcdn.com/image/fetch/$s_!AWjB!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b78f9f9-c047-480f-aa58-b084b1291a46_1488x214.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!AWjB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b78f9f9-c047-480f-aa58-b084b1291a46_1488x214.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>And just like that, you have your first docker container running! The <code>run</code> command starts a container. You pass an image as an argument and with the <code>-it</code> flag you will attach your shell to the container&#8217;s shell. To exit the container, you can simply press CRTL-C on Linux/Win or CMD-C on MacOS.</p><p>Now, we do not want to attach our shell every time we build a <a href="https://www.docker.com">Docker</a> container. In these cases, you can add the <code>-d</code> flag to run a daemon of the container. We can try it like this:</p><pre><code>docker run -d -p 8080:8080 my-first-docker</code></pre><p>Your docker container is now started in the background. At the same time, we mapped the exposed port 8080 of the container to our local port 8080. &nbsp;Run:</p><pre><code>docker ps</code></pre><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!8O_l!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3aefd7e7-64df-4cdb-84b4-72a7c216ed07_1480x60.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8O_l!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3aefd7e7-64df-4cdb-84b4-72a7c216ed07_1480x60.jpeg 424w, https://substackcdn.com/image/fetch/$s_!8O_l!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3aefd7e7-64df-4cdb-84b4-72a7c216ed07_1480x60.jpeg 848w, https://substackcdn.com/image/fetch/$s_!8O_l!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3aefd7e7-64df-4cdb-84b4-72a7c216ed07_1480x60.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!8O_l!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3aefd7e7-64df-4cdb-84b4-72a7c216ed07_1480x60.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!8O_l!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3aefd7e7-64df-4cdb-84b4-72a7c216ed07_1480x60.jpeg" width="1456" height="59" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3aefd7e7-64df-4cdb-84b4-72a7c216ed07_1480x60.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:59,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:134568,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!8O_l!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3aefd7e7-64df-4cdb-84b4-72a7c216ed07_1480x60.jpeg 424w, https://substackcdn.com/image/fetch/$s_!8O_l!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3aefd7e7-64df-4cdb-84b4-72a7c216ed07_1480x60.jpeg 848w, https://substackcdn.com/image/fetch/$s_!8O_l!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3aefd7e7-64df-4cdb-84b4-72a7c216ed07_1480x60.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!8O_l!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3aefd7e7-64df-4cdb-84b4-72a7c216ed07_1480x60.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>As you can see, our docker container is running. <a href="https://www.docker.com">Docker</a> assigns a unique <code>CONTAINER ID</code> to every container. We also can see the command, which is executed as specified in our <code>ENTRYPOINT</code> command in the image, the mapped ports and a randomly assigned name for the container (can be specified manually with the <code>&#8212;name</code> flag). If you move back to your browser and navigate to <code>http://localhost:8080</code>, you should see your &#8220;Welcome to Docker World&#8221; message again, since all traffic on our local port 8080 is routed to our running docker container.</p><p>To stop the container, simply use:</p><pre><code>docker stop &lt;CONTAINER ID&gt;</code></pre><p>Now that our container is stopped, we can see the running and stopped containers with:</p><pre><code>docker ps -a</code></pre><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!gL5m!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51eeb0fc-251a-48cf-889a-f8ff0e67b6ad_1508x60.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!gL5m!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51eeb0fc-251a-48cf-889a-f8ff0e67b6ad_1508x60.jpeg 424w, https://substackcdn.com/image/fetch/$s_!gL5m!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51eeb0fc-251a-48cf-889a-f8ff0e67b6ad_1508x60.jpeg 848w, https://substackcdn.com/image/fetch/$s_!gL5m!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51eeb0fc-251a-48cf-889a-f8ff0e67b6ad_1508x60.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!gL5m!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51eeb0fc-251a-48cf-889a-f8ff0e67b6ad_1508x60.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!gL5m!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51eeb0fc-251a-48cf-889a-f8ff0e67b6ad_1508x60.jpeg" width="1456" height="58" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/51eeb0fc-251a-48cf-889a-f8ff0e67b6ad_1508x60.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:58,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:136465,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!gL5m!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51eeb0fc-251a-48cf-889a-f8ff0e67b6ad_1508x60.jpeg 424w, https://substackcdn.com/image/fetch/$s_!gL5m!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51eeb0fc-251a-48cf-889a-f8ff0e67b6ad_1508x60.jpeg 848w, https://substackcdn.com/image/fetch/$s_!gL5m!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51eeb0fc-251a-48cf-889a-f8ff0e67b6ad_1508x60.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!gL5m!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51eeb0fc-251a-48cf-889a-f8ff0e67b6ad_1508x60.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>You can see the container still exists. To remove our container completely, we can use a final:</p><pre><code>docker rm &lt;CONTAINER ID&gt;</code></pre><h3><strong>Conclusion</strong></h3><p>For now, this should be everything to get started with <a href="https://www.docker.com">Docker</a> and experiment a bit on your own. We learned, why <a href="https://www.docker.com">Docker</a> is such a great alternative to VMs, what <strong>images</strong> and <strong>containers</strong> &nbsp;are, how we can <strong>containerize</strong> our own app and how to interact with our running containers. Hopefully, this has helped you to dive into this amazing technology.</p><p>In the next part, we will have a look at some general best practices when working with <a href="https://www.docker.com">Docker</a>, especially on how to build your images and set up your Dockerfiles.</p><p>Stay tuned!</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://devshift.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading DevShift! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://devshift.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading DevShift! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://devshift.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://devshift.substack.com/subscribe?"><span>Subscribe now</span></a></p>]]></content:encoded></item></channel></rss>