<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Vedran Mihočinec</title>
    <description>The latest articles on DEV Community by Vedran Mihočinec (@vedran).</description>
    <link>https://dev.to/vedran</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F727649%2F128b578d-8395-4f85-bf98-ecca4eef0a62.png</url>
      <title>DEV Community: Vedran Mihočinec</title>
      <link>https://dev.to/vedran</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vedran"/>
    <language>en</language>
    <item>
      <title>The Easiest Way to Dockerize PHP Applications</title>
      <dc:creator>Vedran Mihočinec</dc:creator>
      <pubDate>Mon, 29 Nov 2021 21:06:29 +0000</pubDate>
      <link>https://dev.to/vedran/the-easiest-way-to-dockerize-a-php-application-4jne</link>
      <guid>https://dev.to/vedran/the-easiest-way-to-dockerize-a-php-application-4jne</guid>
      <description>&lt;p&gt;What is the easiest way to dockerize PHP applications? Let's find out with the GitHub repository example.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;

&lt;p&gt;In order to create scalable architecture, we will dockerize two apps that will use the same reverse proxy. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vrBofJh_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4574gyems9fhri1b7d96.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vrBofJh_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4574gyems9fhri1b7d96.png" alt="Network" width="880" height="431"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Services can only communicate with other services on networks they share, so we will have three networks:&lt;/p&gt;

&lt;p&gt;1) Proxy Network which contains Reverse Proxy (Nginx), Best App (Apache/PHP), and Awesome App (Apache/PHP);&lt;br&gt;
2) Best Network which contains Best App and Best DB (MySQL);&lt;br&gt;
3) Awesome Network which contains only Awesome App.&lt;/p&gt;

&lt;h2&gt;
  
  
  Requirements
&lt;/h2&gt;

&lt;p&gt;Requirements for our architecture are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;There are no permission issues;&lt;/li&gt;
&lt;li&gt;Xdebug works out-of-the-box;&lt;/li&gt;
&lt;li&gt;Every application has a unique domain;&lt;/li&gt;
&lt;li&gt;We use HTTPS;&lt;/li&gt;
&lt;li&gt;Setup supports multiple applications.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Permission Issues and Xdebug
&lt;/h2&gt;

&lt;p&gt;To prevent permission issues and have package availability out-of-the-box, we will use &lt;a href="https://github.com/thecodingmachine"&gt;thecodingmachine/php&lt;/a&gt; for PHP applications, a general-purpose PHP image for Docker. &lt;/p&gt;

&lt;p&gt;We will use its &lt;a href="https://github.com/thecodingmachine/docker-images-php#fat-image"&gt;fat image&lt;/a&gt;, as it comes with &lt;a href="https://httpd.apache.org/"&gt;Apache&lt;/a&gt;, &lt;a href="https://github.com/aptible/supercronic/"&gt;Superconic&lt;/a&gt;, and &lt;a href="https://getcomposer.org/"&gt;Composer&lt;/a&gt; and it already has common PHP extensions enabled.&lt;/p&gt;

&lt;h2&gt;
  
  
  Unique Domains, HTTPS and Multiple Applications
&lt;/h2&gt;

&lt;p&gt;In order to have unique domains, HTTPS and multiple applications support out-of-the-box, we will use &lt;a href="https://github.com/nginx-proxy/nginx-proxy"&gt;nginx-proxy&lt;/a&gt;, as it supports everything mentioned above.&lt;/p&gt;

&lt;h2&gt;
  
  
  GitHub Repository
&lt;/h2&gt;

&lt;p&gt;As we have defined the architecture and tools we will use, this is the part where you should visit &lt;a href="https://github.com/v-m-i/simple-php-app-dockerization"&gt;https://github.com/v-m-i/simple-php-app-dockerization&lt;/a&gt; and see how to configure and run everything mentioned so far.&lt;/p&gt;

&lt;h2&gt;
  
  
  Outro
&lt;/h2&gt;

&lt;p&gt;This post could have been a lot longer, but I've kept it as short as possible because everything should be explained in the example repository.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is the Easiest Way the Best Way?
&lt;/h3&gt;

&lt;p&gt;It depends on what our goal is. If our goal is to create an optimized, clean and precise docker environment, then it's not the best way, as it's a fat setup. But if we want to dockerize our app for our local development in the fastest and hassle-free way, then it might be the best way to do it.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>php</category>
      <category>webdev</category>
      <category>devops</category>
    </item>
    <item>
      <title>Debugging Mindset</title>
      <dc:creator>Vedran Mihočinec</dc:creator>
      <pubDate>Sat, 16 Oct 2021 20:36:24 +0000</pubDate>
      <link>https://dev.to/vedran/debugging-mindset-3n77</link>
      <guid>https://dev.to/vedran/debugging-mindset-3n77</guid>
      <description>&lt;p&gt;Bugs here, bugs there, bugs everywhere. Some are easy to fix, some are complex and obscure. So, is there a generic approach to fixing every bug? Probably not.&lt;/p&gt;

&lt;p&gt;Anyway, there are four parts of fixing a bug:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Understanding a bug;&lt;/li&gt;
&lt;li&gt;Identifying the cause of a bug;&lt;/li&gt;
&lt;li&gt;Planning a bug fix;&lt;/li&gt;
&lt;li&gt;Applying a bug fix.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Understanding a bug
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What are the steps to reproduce a bug?
&lt;/h3&gt;

&lt;p&gt;It is crucial to have as much information as possible about a bug, even if some of that information ends up irrelevant. For example, knowing at what time which user on which platform with which input got which output. You should almost always have all the required information already written in the bug report and if you constantly end up asking this question, then consider writing a list of required information for reporting a bug.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the expected flow?
&lt;/h3&gt;

&lt;p&gt;Sometimes features end up reported as bugs. And that's okay, as developers don't know every part of the application code the same way bug reporters might not know about some feature. So it's important to have the expected flow explained in the bug report.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is your bug a bug and is expected flow an expected flow?
&lt;/h3&gt;

&lt;p&gt;As mentioned above, not everyone knows everything and features might end up reported as bugs. So, if you think a bug needs to be challenged, challenge it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Identifying the cause of a bug
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What does the log say?
&lt;/h3&gt;

&lt;p&gt;If you know when a bug happened, are there any logs that might help you? Remember to consider all log types: system logs (example: OOM happened), application logs (example: required third party service was unavailable), third party logs (example: unoptimized database query resulted in slow query execution), etc.&lt;/p&gt;

&lt;h3&gt;
  
  
  How does the flow behave in your local environment?
&lt;/h3&gt;

&lt;p&gt;Try to reproduce the bug in your local environment. After you reproduce it, turn on a debugger and try to figure out where the bug is in the code. If needed, write down suspicious points and ponder over them until you figure out where the bug is.&lt;/p&gt;

&lt;h3&gt;
  
  
  How does the flow behave in the production environment?
&lt;/h3&gt;

&lt;p&gt;If you can't reproduce the bug in your local environment, then it might be time to try the production environment. Based on identified suspicious points, use remote debugging or write the information you need in the application logs (example: "If logged user is me, then the log information I need (input data, execution time, etc.)"). After you have that production information, try to reproduce it locally again. And finally, if you didn't use remote debugging, remove added temporary logging code from production.&lt;/p&gt;

&lt;h3&gt;
  
  
  What if we can't identify the cause of the bug after all the steps mentioned above?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Talk to a duck&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Explain the bug and all the steps and findings to a non-person. Just by explaining, some ideas might pop up.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Talk to other developers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Explain the bug and all the steps and findings to other developers. Maybe you will get some advice or tips on what to check.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Give up (temporarily)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Add detailed logging to all identified suspicious points (be careful not to impact the application performance), write down all your findings, deploy code with detailed logging to production and wait for the bug to occur again.&lt;/p&gt;

&lt;p&gt;Explain to your client that you are unable to reproduce the bug and that you have added detailed logging so you will know when the bug occurs next time and that you will try to fix it again at that time, with new information you will have.&lt;/p&gt;

&lt;h2&gt;
  
  
  Planning a bug fix
&lt;/h2&gt;

&lt;h3&gt;
  
  
  "Is your bug a bug and is expected flow an expected flow" vol 2
&lt;/h3&gt;

&lt;p&gt;With new information, ask yourself if there is a need to challenge the requested flow. Maybe there is a reason the flow behaves the way it behaves. Maybe the problem is wrong communication to the end-user. Maybe there are security, performance, or some other kind of issues that might occur if that flow is changed. Always check code history where the bug occurs, maybe there are some linked feature requests or explanations for it.&lt;/p&gt;

&lt;h3&gt;
  
  
  How many entities are affected by this bug?
&lt;/h3&gt;

&lt;p&gt;It's good practice to check how many entities were affected by a bug. It might lead to different bug solutions or maybe the client might want to know that information.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can you reproduce a bug with a test?
&lt;/h3&gt;

&lt;p&gt;If you can reproduce a bug with a test, plan to write the test.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do you need a hotfix?
&lt;/h3&gt;

&lt;p&gt;If you need to fix a bug ASAP, then plan to create a hotfix.&lt;/p&gt;

&lt;h3&gt;
  
  
  Did the bug cause some data corruption?
&lt;/h3&gt;

&lt;p&gt;If some data is corrupted because of the bug, analyze the impact and plan the solution for data corruption. For example, you might have to create a background process that will fix all corrupted data, or maybe you might need some manual intervention to fix corrupted data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do you need to remove added logging?
&lt;/h3&gt;

&lt;p&gt;If you have added some detailed logging to better identify the bug, maybe you need to remove it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Applying a bug fix
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;If needed, create and deploy a hotfix. A hotfix can be ugly, but, ideally, it should be accompanied by a test that confirms that hotfix works.&lt;/li&gt;
&lt;li&gt;Fix the bug according to your application coding standards and, if possible, write some tests for it. If you added some logging that is not needed anymore, remove it.&lt;/li&gt;
&lt;li&gt;If corrupted data exists, fix corrupted data.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Outro
&lt;/h2&gt;

&lt;p&gt;These are the steps I often go through when I work on solving bugs. Most of the time there is no need to go through all these steps, but hey, here they are.&lt;br&gt;
And there is still one important thing to mention:&lt;/p&gt;

&lt;h3&gt;
  
  
  How to estimate bug fixing?
&lt;/h3&gt;

&lt;p&gt;When you have all the information about the bug, somebody might need an estimate on how long it takes to solve that bug. That's easy when the bug is obvious and (probably) easy to solve, but how about when it isn't? Here are my rule-of-thumb rules:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a task for identifying the cause of the bug and estimate it to a maximum of one day. If you can't reproduce a bug in one day, give up (temporarily) and create a follow-up ticket for a time when the bug is detected again.&lt;/li&gt;
&lt;li&gt;If you identify the cause of the bug within one day and you can fix it in the remaining part of the day, fix that bug.&lt;/li&gt;
&lt;li&gt;If you can't easily fix the bug, create follow-up tasks based on your plan for a bug fix.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And that's it, I hope this article helps you in your future bug fixing ventures.&lt;/p&gt;

&lt;p&gt;Have fun!&lt;/p&gt;

</description>
      <category>career</category>
      <category>programming</category>
      <category>productivity</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
