<?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>Forem: ritwikmath</title>
    <description>The latest articles on Forem by ritwikmath (@ritwikmath).</description>
    <link>https://forem.com/ritwikmath</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%2F1066140%2F3083356d-576a-42c9-86c4-064607c3226a.jpg</url>
      <title>Forem: ritwikmath</title>
      <link>https://forem.com/ritwikmath</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/ritwikmath"/>
    <language>en</language>
    <item>
      <title>Python Design Patterns Cookbook: Recipes for Clean and Reusable Code (Facade)</title>
      <dc:creator>ritwikmath</dc:creator>
      <pubDate>Tue, 13 Jun 2023 17:27:49 +0000</pubDate>
      <link>https://forem.com/ritwikmath/python-design-patterns-cookbook-recipes-for-clean-and-reusable-code-facade-16hm</link>
      <guid>https://forem.com/ritwikmath/python-design-patterns-cookbook-recipes-for-clean-and-reusable-code-facade-16hm</guid>
      <description>&lt;h1&gt;
  
  
  Design Patterns: An Introduction and Explanation
&lt;/h1&gt;

&lt;p&gt;Design patterns are like recipes that software developers use to solve common problems that come up when building complex software. Like how different chefs might use slightly different ingredients or techniques to make the same dish, developers can use different approaches to implement the same design pattern. Design patterns are not strict rules that apply to every situation, but rather a blueprint that can be customized to fit the specific problem at hand. They can be used with any programming language and it's important to choose the correct design pattern for each situation.&lt;/p&gt;

&lt;h1&gt;
  
  
  Facade Design Pattern
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;As software systems grow in size and complexity over time, they can become increasingly difficult to maintain and modify. This can be especially challenging when trying to add new features or make changes to existing functionality, as exposing the complex inner workings of the system can lead to unwanted side effects and unpredictable behavior. Additionally, developers may find themselves duplicating the same code in multiple parts of the system, leading to redundant and hard-to-maintain code.&lt;/p&gt;

&lt;p&gt;To address these challenges, the Facade design pattern provides a way to hide the complexity of a system behind a simple interface, allowing developers to execute a set of operations in one place without exposing the inner workings of the system. This approach can greatly simplify the development process, reduce duplication of code, and make it easier to maintain and modify the system over time. In this way, the Facade pattern is a powerful tool for improving the maintainability and scalability of software systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Issue You May Face
&lt;/h2&gt;

&lt;p&gt;As a developer, you have been assigned building a key component of our multimedia player software that can support a wide range of audio file formats, including MP3, WAV, and FLAC. The main objective is to design a system that allows users to seamlessly play audio files of different formats, eliminating the need for them to worry about the underlying complexities involved in handling diverse file formats.&lt;/p&gt;

&lt;p&gt;Your responsibility is to create robust software that ensures users can enjoy a smooth and uninterrupted playback experience, regardless of the audio file format they choose. It is essential to develop a solution that abstracts the intricacies associated with decoding and playback, providing users with a simple and intuitive interface to initiate and control audio playback effortlessly.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Logical Solution
&lt;/h2&gt;

&lt;p&gt;In the given scenario, we have a multimedia player system that supports various file formats, including MP3, WAV, and FLAC. To simplify the interaction with the player and hide the complexity of handling different file formats, we can apply the Facade design pattern. The MultimediaFacade class serves as the facade, providing a simplified interface for the client code to interact with the multimedia player. It encapsulates the interactions with the MP3Codec, WAVCodec, and FLACCodec subsystems responsible for decoding the respective file formats.&lt;/p&gt;

&lt;p&gt;When the client code calls the play() method of the MultimediaFacade, it passes the filename of the audio file to be played. The facade internally determines the file format based on its extension and delegates the decoding process to the appropriate codec subsystem. Once decoded, the facade initiates the playback of the file, abstracting the details of decoding and playback from the client.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Facade Design Pattern
&lt;/h2&gt;

&lt;p&gt;So, here's the deal! You can create three cool classes for handling different types of audio files. We have the MP3Codec class, the WAVCodec class, and the FLACCodec class. Each of these classes knows how to decode its specific type of audio file. For example, the MP3Codec can decode MP3 files, the WAVCodec can handle WAV files, and the FLACCodec can work with FLAC files.&lt;/p&gt;

&lt;p&gt;But wait, there's more! We also have this awesome MultimediaFacade class. It acts as the mastermind behind the scenes, making your life easier. Inside this class, we create instances of the codec classes, like mp3_codec, wav_codec, and flac_codec.&lt;/p&gt;

&lt;p&gt;Now, here's the magic. The MultimediaFacade class has a nifty play() method that takes the name of a file as input. It's smart enough to figure out the file format based on its extension (you know, like .mp3, .wav, or .flac).&lt;/p&gt;

&lt;p&gt;When you call the play() method with a file name, the MultimediaFacade class does all the heavy lifting. If it's an MP3 file, it uses the mp3_codec to decode it and then proudly announces that it's playing an MP3 file. If it's a WAV file, it delegates the decoding to the wav_codec and says it's playing a WAV file. And of course, if it's a FLAC file, it uses the flac_codec and lets you know that it's playing a FLAC file.&lt;/p&gt;

&lt;p&gt;Oh, and if it encounters a file format it doesn't support, it kindly informs you that it's an unsupported format. But let's hope we only throw in some cool MP3s, WAVs, and FLACs, right?&lt;/p&gt;

&lt;p&gt;To get this party started, you just need to create an instance of the MultimediaFacade class and call its play() method with the file names you want to groove to. So grab your favorite music.mp3, audio.wav, or audio.flac, and let the multimedia player do its thing!&lt;/p&gt;

&lt;h2&gt;
  
  
  Code Example
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MP3Codec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Decoding MP3 file:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WAVCodec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Decoding WAV file:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FLACCodec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Decoding FLAC file:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MultimediaFacade&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mp3_codec&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MP3Codec&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wav_codec&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;WAVCodec&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;flac_codec&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FLACCodec&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;play&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;endswith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;".mp3"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mp3_codec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Playing MP3 file..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;endswith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;".wav"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wav_codec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Playing WAV file..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;endswith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;".flac"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;flac_codec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Playing FLAC file..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Unsupported file format."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Client code
&lt;/span&gt;&lt;span class="n"&gt;multimedia&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MultimediaFacade&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;multimedia&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;play&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"music.mp3"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;multimedia&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;play&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"audio.wav"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;multimedia&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;play&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"audio.flac"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KWBmQ4sx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gj4ftmwvkef6yzwjiwnw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KWBmQ4sx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gj4ftmwvkef6yzwjiwnw.png" alt="Bash" width="382" height="112"&gt;&lt;/a&gt;&lt;br&gt;
With the current implementation of the Facade pattern, you can simplify the process of repairing electronic devices by providing a unified interface that hides the complexities of handling different device types. This means that you can seamlessly add new devices to the system without modifying any existing code.&lt;/p&gt;

&lt;p&gt;Let's say you have a system that guides users through repairing mobile phones and laptops. Each device may have unique repair requirements, such as different components or repair procedures. However, by utilizing the Facade pattern, you can create a streamlined interface that abstracts away these differences and provides a consistent user experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Differences with Factory Design Pattern
&lt;/h2&gt;

&lt;p&gt;The Facade pattern is a structural design pattern that provides a simplified interface to a complex subsystem or set of classes. The Factory Method pattern is a creational design pattern that provides an interface for creating objects, but allows subclasses to decide which class to instantiate.&lt;/p&gt;

&lt;p&gt;The primary goal of the Facade pattern is to simplify the usage of a complex system by providing a high-level, user-friendly interface. The factory method, on the other hand, encapsulates the object creation logic, providing flexibility in choosing the appropriate class to instantiate based on the specific requirements or conditions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Factors Should be Taken into Consideration
&lt;/h2&gt;

&lt;p&gt;While the Facade pattern can be beneficial in many cases, there are situations where it may not be the best choice. Here are some scenarios in which using the Facade pattern may not be recommended:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;If your system is relatively simple and does not involve a complex arrangement of classes or subsystems, introducing a Facade may add unnecessary complexity.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In systems where components and their interactions change frequently, applying a Facade pattern may lead to increased maintenance efforts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If clients require fine-grained control and access to individual components or subsystems, using a Facade may limit their flexibility.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In performance-critical systems where every millisecond counts, the additional abstraction layer introduced by the Facade pattern may impact performance.&lt;/p&gt;
&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In conclusion, the Facade design pattern offers a powerful solution for simplifying complex systems and providing a user-friendly interface to clients. By encapsulating the complexities of the underlying subsystems, the Facade pattern promotes code readability, maintainability, and ease of use. It allows clients to interact with a unified interface, shielding them from the intricate details of the system's internal workings.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;However, it's essential to carefully consider when to use the Facade pattern. Simple systems, highly dynamic systems, cases requiring fine-grained control, performance-critical systems, and situations where the Facade does not significantly reduce complexity may not be the ideal fit for this pattern. It's crucial to evaluate the specific requirements and trade-offs of each scenario to determine whether the benefits of using a Facade outweigh the potential drawbacks.&lt;/p&gt;

</description>
      <category>designpatterns</category>
      <category>python</category>
      <category>programming</category>
      <category>10xdeveloper</category>
    </item>
    <item>
      <title>Python Design Patterns Cookbook: Recipes for Clean and Reusable Code (Factory Method)</title>
      <dc:creator>ritwikmath</dc:creator>
      <pubDate>Sat, 29 Apr 2023 12:35:05 +0000</pubDate>
      <link>https://forem.com/ritwikmath/python-design-patterns-cookbook-recipes-for-clean-and-reusable-code-factory-method-2n2c</link>
      <guid>https://forem.com/ritwikmath/python-design-patterns-cookbook-recipes-for-clean-and-reusable-code-factory-method-2n2c</guid>
      <description>&lt;h1&gt;
  
  
  Design Patterns: An Introduction and Explanation
&lt;/h1&gt;

&lt;p&gt;Design patterns are like recipes that software developers use to solve common problems that come up when building complex software. Like how different chefs might use slightly different ingredients or techniques to make the same dish, developers can use different approaches to implement the same design pattern. Design patterns are not strict rules that apply to every situation, but rather a blueprint that can be customized to fit the specific problem at hand. They can be used with any programming language and it's important to choose the correct design pattern for each situation.&lt;/p&gt;

&lt;h1&gt;
  
  
  Factory Design Pattern
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;When a software program has multiple components that share similarities but have different implementations for general operations, a junior developer may use conditionals like if-else or switch-case to handle the differences. However, as the number of components grows, the code becomes difficult to manage and maintain. For example, imagine a program that handles different types of shapes, such as circles and squares. A junior developer may write a method that handles the calculation of area for each shape separated by if-else, but as new shapes are added, the code becomes longer and harder to manage.&lt;/p&gt;

&lt;p&gt;To avoid the problems that come with using conditionals for handling multiple components' behavior, a better approach is to use the Factory Method pattern. The Factory Method pattern involves creating an interface or abstract class that represents the category, such as the "Shape" interface in the previous example. Each shape, such as a "Circle" or "Square," then implements this interface and defines its behavior for calculating area. This approach simplifies the code because each new shape can simply implement the "Shape" interface that will enforce the new shape to implement a method for calculating area without affecting the existing code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Issue You May Face
&lt;/h2&gt;

&lt;p&gt;You've been tasked with creating software that guides users through repairing electronic devices, starting with mobile phones and laptops. However, the process for repairing different components, such as screens, batteries, and ports, is unique to each device, and not all repairs are possible in both. Additionally, the company plans to add seven more devices to the system within the next three months, and the repair instructions may need to be updated as technology evolves. To ensure scalability and ease of modification, the system needs to be designed accordingly.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;To simplify matters, it is often assumed that all models of a particular mobile phone or laptop can be repaired using the same process.&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  A Logical Solution
&lt;/h2&gt;

&lt;p&gt;One way to solve this problem is by categorizing the devices based on their common characteristics, such as whether or not they have a SIM slot or a HDD. You could then create separate sets of instructions for each category, which would allow you to provide device-specific instructions while still keeping the instructions organized and easy to manage. This would also make it easier to add new devices to the system in the future, since you could simply categorize them based on their characteristics and create a new set of instructions for that category.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Factory Method
&lt;/h2&gt;

&lt;p&gt;To implement the Factory method, you can start by creating an abstract class called RepairGuide. This class will define the interface for all the repair guides and should include abstract methods for repairing the screen, RAM, and SIM slot. Then, you can create two concrete classes, MobileRepairGuide and LaptopRepairGuide, that implement the RepairGuide interface and provide device-specific repair instructions.&lt;/p&gt;

&lt;p&gt;Next, you can create a RepairGuideFactory class that will create the appropriate RepairGuide object based on the device type passed to it. In your main program, you can create a RepairGuide object for a mobile device using the RepairGuideFactory. Then, you can display a list of available repair options to the user by getting the list of subclasses of the RepairGuide class using the subclasses() method.&lt;/p&gt;

&lt;p&gt;Once the user selects a device, you can create the appropriate RepairGuide object using the RepairGuideFactory. Then, you can display a list of available repair options for the selected device by getting a list of all the non-private methods of the object using the inspect.getmembers() function.&lt;/p&gt;

&lt;p&gt;You can iterate through this list and display the name of each method, which corresponds to a repair option. Then, prompt the user to select a repair option. Once the user selects a repair option, you can call the corresponding method on the RepairGuide object. This will execute the device-specific repair instructions for the selected repair option.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code Example
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;inspect&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;abc&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ABC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;abstractmethod&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RepairGuide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ABC&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;abstractmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;repair_screen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;

    &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;abstractmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;repair_ram&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;

    &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;abstractmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;repair_sim_slot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MobileRepairGuide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RepairGuide&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;repair_screen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Mobile screen repair instructions."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;repair_ram&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"RAM repair is not possible on mobile phones.."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;repair_sim_slot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Mobile SIM slot repair instructions."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LaptopRepairGuide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RepairGuide&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;repair_screen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Laptop screen repair instructions."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;repair_ram&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Laptop RAM repair instructions."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;repair_sim_slot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SIM slot repair is not possible on laptops."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RepairGuideFactory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;staticmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_repair_guide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;device_type&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;device_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"mobile"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;MobileRepairGuide&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;device_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"laptop"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;LaptopRepairGuide&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;

    &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;staticmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;sub_class_list&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;RepairGuide&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__subclasses__&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;sub_class&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;RepairGuideFactory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sub_class_list&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;': '&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;sub_class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="n"&gt;sub_class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'R'&lt;/span&gt;&lt;span class="p"&gt;)])&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sub_class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="n"&gt;sub_class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'R'&lt;/span&gt;&lt;span class="p"&gt;)].&lt;/span&gt;&lt;span class="n"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="n"&gt;selected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Which device you want to repair? &lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RepairGuideFactory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_repair_guide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;selected&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;repair_options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="n"&gt;functions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;inspect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getmembers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;predicate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;inspect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isfunction&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;functions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;startswith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'__'&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;': '&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;capitalize&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'_'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="n"&gt;repair_options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;getattr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
        &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="n"&gt;selected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Which part you want to repair? &lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;repair_options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;selected&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]()&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5TtbyyQW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jghluazcqy258ifinncl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5TtbyyQW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jghluazcqy258ifinncl.png" alt="Screenshot" width="455" height="376"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With the current implementation of the Factory Method, you can add as many new device types as you want without having to modify any of the existing code. Additionally, if you need to add repair instructions for a new device type, you can do so with confidence because any new child class that you create must implement all the abstract methods that are defined in the superclass.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why not Simple if-else?
&lt;/h2&gt;

&lt;p&gt;As previously demonstrated, the Factory Method pattern can provide a high degree of flexibility to your code. Although this level of dynamic implementation may not always be necessary, using the Factory Method approach offers additional benefits. By avoiding the use of conditional statements like if-else for object creation, the code becomes easier to maintain. Additionally, the Factory Method pattern increases testability by allowing for the entire method to be mocked during testing.&lt;/p&gt;

&lt;p&gt;Furthermore, the Factory Method pattern strongly supports four fundamental Object-Oriented Programming principles: encapsulation, abstraction, polymorphism, and the Open/Closed principle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Factors Should be Taken into Consideration
&lt;/h2&gt;

&lt;p&gt;By considering following factors, you can determine whether the Factory Method pattern is the right solution for your specific situation.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The number of products or object types: The Factory Method pattern is most useful when you have a large number of related objects that need to be created.&lt;/li&gt;
&lt;li&gt;The complexity of object creation: If creating an object is a complex process that involves multiple steps, it makes sense to use a Factory Method to encapsulate that complexity.&lt;/li&gt;
&lt;li&gt;Dependency injection: If you need to create objects that depend on other objects, you can use the Factory Method to inject those dependencies into the objects being created.&lt;/li&gt;
&lt;li&gt;Testability: Using the Factory Method can make your code more testable by allowing you to easily create mock objects for testing.&lt;/li&gt;
&lt;li&gt;Extensibility: The Factory Method pattern can make your code more extensible by allowing you to add new products or object types without changing the existing code.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The Factory Method is a design pattern that has many benefits and can make your code more dynamic, flexible, and maintainable. The pattern allows you to create objects without having to know the exact class of the object that will be created. This level of abstraction provides many benefits, including better encapsulation, abstraction, polymorphism, and adherence to the open/closed principle.&lt;/p&gt;

&lt;p&gt;When creating a Factory Method, there are several factors that you should take into consideration. These include the complexity of the objects being created, the need for flexibility and extensibility, and the maintainability of the code. By carefully considering these factors, you can create a Factory Method that provides maximum benefits and reduces the risk of errors and maintenance problems.&lt;/p&gt;

&lt;p&gt;In conclusion, the Factory Method is a powerful design pattern that can help you create more dynamic, flexible, and maintainable code. By following best practices and considering the key factors, you can create a Factory Method that provides many benefits and improves the overall quality of your code. Whether you are a beginner or an experienced developer, the Factory Method is a pattern that you should consider adding to your design toolbox.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>designpatterns</category>
      <category>python</category>
      <category>factorymethod</category>
    </item>
    <item>
      <title>Nginx Reverse Proxy in Localhost and Docker: A Comprehensive Setup Guide</title>
      <dc:creator>ritwikmath</dc:creator>
      <pubDate>Tue, 18 Apr 2023 04:09:55 +0000</pubDate>
      <link>https://forem.com/ritwikmath/nginx-reverse-proxy-in-localhost-and-docker-a-comprehensive-setup-guide-3d1o</link>
      <guid>https://forem.com/ritwikmath/nginx-reverse-proxy-in-localhost-and-docker-a-comprehensive-setup-guide-3d1o</guid>
      <description>&lt;h1&gt;
  
  
  Introduction:
&lt;/h1&gt;

&lt;p&gt;Creating a web application that is accessible to users from different locations while keeping their data secure is essential in today's digital world. In this blog post, we will guide you through the process of setting up a Nginx reverse proxy in Docker, with the frontend built using React and the backend using Node.js. We will provide a step-by-step guide to creating an &lt;code&gt;Nginx reverse proxy&lt;/code&gt; that only allows access to the &lt;code&gt;client and server&lt;/code&gt; through Nginx, without exposing any ports from Docker, making the application more secure. By the end of this blog post, you will have a comprehensive understanding of how to create a secure and robust web application that can handle traffic from all over the world, ensuring your users' data remains safe. So let's dive in and get started!&lt;/p&gt;

&lt;h1&gt;
  
  
  Prerequisites
&lt;/h1&gt;

&lt;p&gt;Before getting started with the setup, there are a few prerequisites that need to be in place. Firstly, you will need to have &lt;strong&gt;Node.js and npm installed&lt;/strong&gt; on your system to install and run the React and Node.js applications. Additionally, you will need to &lt;strong&gt;install Docker and Docker Compose&lt;/strong&gt;, which will be used to set up the Nginx reverse proxy.&lt;br&gt;
If you are unfamiliar with Nginx, it is a popular open-source web server that is used for serving web content, reverse proxying, and more. In this setup, we will use Nginx as a reverse proxy to manage incoming requests to the web application.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;To begin, you need to create a directory that will serve as the root directory for the web application.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Setting up the Frontend with React:
&lt;/h1&gt;

&lt;p&gt;To create a new React application, you can use the &lt;code&gt;create-react-app CLI&lt;/code&gt; tool. Here's how you can run the command to create a new React app named client:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open a terminal window in the root directory of your project.&lt;/li&gt;
&lt;li&gt;Run the command &lt;code&gt;npx create-react-app client&lt;/code&gt;. This will create a new React app in a directory named client.&lt;/li&gt;
&lt;li&gt;Wait for the command to finish running. This may take a few minutes, depending on your internet speed and computer performance.&lt;/li&gt;
&lt;li&gt;Once the command has finished running, you can navigate into the client directory by running the command cd client.&lt;/li&gt;
&lt;li&gt;From here, you can start the development server by running the command npm start. This will open the app in your default web browser at &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Note that the name client is used in this example for the React app, but you can choose any other name that does not include the word &lt;strong&gt;react&lt;/strong&gt;. This is because &lt;strong&gt;react is a reserved name&lt;/strong&gt; and may cause conflicts with other packages.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2mmrfvgvo3vl3vqcufgm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2mmrfvgvo3vl3vqcufgm.png" alt="Create react app" width="635" height="288"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Change directory to &lt;code&gt;/client/src&lt;/code&gt;. Open your preferred code editor and load the file "App.js".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fec8evqmurzt8urenb00t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fec8evqmurzt8urenb00t.png" alt="React folder structure" width="594" height="325"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Final Client Code&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./App.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setUsers&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;([]);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fetchData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/users/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nf"&gt;setUsers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;App&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Fetch&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="nx"&gt;Data&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ul&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/li&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="p"&gt;))}&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ul&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;)}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The provided code is an example of a React functional component that displays a button to fetch user data from a Node.js backend API. When the button is clicked, the component triggers the fetchData function using async/await syntax. The function makes a request to the /api/users endpoint of the Node.js backend, extracts the "users" property from the JSON response, and updates the "users" state variable using the setUsers function.&lt;/p&gt;

&lt;h1&gt;
  
  
  Setting up the Backend with Node.js:
&lt;/h1&gt;

&lt;p&gt;To set up the backend of the web application, you need to create a folder named &lt;code&gt;server&lt;/code&gt; and navigate to it using the command line. Next, you can run the command &lt;code&gt;npm init -y&lt;/code&gt; to create a package.json file in the folder, which will be used to manage the project dependencies.&lt;/p&gt;

&lt;p&gt;Afterwards, you will need to create two files in the &lt;code&gt;server&lt;/code&gt; folder: &lt;code&gt;server.Dockerfile&lt;/code&gt; and &lt;code&gt;server.js&lt;/code&gt;. The &lt;code&gt;server.js&lt;/code&gt; file contains the backend code that will be executed when you run the command &lt;code&gt;npm start&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To add necessary functionality to the backend of the web application, you will need to install two Node.js modules, &lt;code&gt;express&lt;/code&gt; and &lt;code&gt;cors&lt;/code&gt;. &lt;code&gt;Express&lt;/code&gt; is a popular web framework that simplifies the creation of server-side applications, while &lt;code&gt;cors&lt;/code&gt; is a middleware that enables cross-origin resource sharing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuzsb97lp66ek4rvbhywb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuzsb97lp66ek4rvbhywb.png" alt="Bash commands to create server" width="594" height="923"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also run, &lt;code&gt;npm install --save-dev nodemon&lt;/code&gt; to install nodemon package as development dependency. Once nodemon is installed, you can use it to automatically restart your Node.js application whenever changes are made to the code. To start your application with nodemon, simply replace the &lt;code&gt;node&lt;/code&gt; command with &lt;code&gt;nodemon&lt;/code&gt; in your start script in package.json.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"server"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"server.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"module"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"nodemon server.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"prod"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node server.js"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"keywords"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"author"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"license"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ISC"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"dependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"cors"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^2.8.5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"express"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^4.18.2"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"devDependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"nodemon"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^2.0.22"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Package.json has been modified to prevent the server from failing due to configuration errors.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Final Server Code&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Router&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;cors&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cors&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;urlencoded&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;extended&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}));&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;cors&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;_id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Ritwik Math&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;},{&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;_id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;John Doe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;},{&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;_id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Jane Doe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;promise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;route&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Router&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;route&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Fetched successfully&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;route&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`App is running on http://localhost:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This code creates a new Promise that resolves with an array of users after a 3-second delay. Then, an HTTP route is defined using the Express.js Router. This route listens for GET requests to the /users endpoint and uses async/await syntax to fetch the users data from the Promise and return it as a JSON response. When a user makes a GET request to the /users endpoint, the async function defined for this route is executed. This function waits for the Promise to resolve using await, and then returns a JSON response with the fetched data. If the Promise is rejected for any reason, the catch block will execute and log the error message to the console. This code demonstrates how Promises can be used to handle asynchronous operations in JavaScript, and how async/await syntax can make it easier to write asynchronous code that looks and behaves more like synchronous code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Test result&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the App.js file of your React app in a code editor.&lt;/li&gt;
&lt;li&gt;Find the part of the code where the URL for the API endpoint &lt;code&gt;/api/users&lt;/code&gt; is defined.&lt;/li&gt;
&lt;li&gt;Change the URL in this code to &lt;a href="http://localhost:8000/users" rel="noopener noreferrer"&gt;http://localhost:8000/users&lt;/a&gt;. Make sure you save the file after making the change.&lt;/li&gt;
&lt;li&gt;Start your React app by running the command npm start in your terminal.&lt;/li&gt;
&lt;li&gt;Open your web browser and navigate to &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt; (or the URL your app is running on).&lt;/li&gt;
&lt;li&gt;If everything is working properly, you should see a list of users displayed in the browser that is fetched from the &lt;a href="http://localhost:8000/users" rel="noopener noreferrer"&gt;http://localhost:8000/users&lt;/a&gt; endpoint. If you see the list, congratulations! You've successfully setup the backend and front end.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Change the url back to &lt;code&gt;/api/users&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6tnj3vw5jw8xqkk5u40h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6tnj3vw5jw8xqkk5u40h.png" alt="Proof" width="800" height="58"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Setting up the Nginx Reverse Proxy in Localhost:
&lt;/h1&gt;

&lt;p&gt;This example requires setting up nginx configuration using port 80. Ensure that port 80 is available on your system, or choose a different port. If you use a different port, remember to include it in the URL, for instance, &lt;code&gt;/api/users:81&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjnj34sdrxiqqztz8rw2p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjnj34sdrxiqqztz8rw2p.png" alt="Image description" width="800" height="186"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To implement reverse proxy using nginx container, create a directory named &lt;code&gt;nginx&lt;/code&gt; and within it, create a file named &lt;code&gt;nginx.conf&lt;/code&gt;. This file will be active in the nginx container.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;

&lt;span class="k"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_pass&lt;/span&gt; &lt;span class="s"&gt;http://127.0.0.1:3000/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;Host&lt;/span&gt; &lt;span class="nv"&gt;$host&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Real-IP&lt;/span&gt; &lt;span class="nv"&gt;$remote_addr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Forwarded-For&lt;/span&gt; &lt;span class="nv"&gt;$proxy_add_x_forwarded_for&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/api/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_pass&lt;/span&gt; &lt;span class="s"&gt;http://127.0.0.1:8000/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;Host&lt;/span&gt; &lt;span class="nv"&gt;$host&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Real-IP&lt;/span&gt; &lt;span class="nv"&gt;$remote_addr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Forwarded-For&lt;/span&gt; &lt;span class="nv"&gt;$proxy_add_x_forwarded_for&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;To load the Nginx configuration from the appropriate directory, you need to copy the nginx.conf file to &lt;strong&gt;/etc/nginx/conf.d&lt;/strong&gt;. To do this, run the following command with sudo privileges: &lt;code&gt;sudo cp nginx/nginx.conf /etc/nginx/conf.d/&lt;/code&gt;. Default &lt;strong&gt;.conf&lt;/strong&gt; file of nginx loads configirations from this directory.&lt;br&gt;
The setup acts as a reverse proxy on the local host, enabling access to the client side via &lt;a href="http://localhost" rel="noopener noreferrer"&gt;http://localhost&lt;/a&gt; and the server side via &lt;a href="http://localhost/api" rel="noopener noreferrer"&gt;http://localhost/api&lt;/a&gt;. The client and server upstream are designated as &lt;a href="http://127.0.0.1:3000/" rel="noopener noreferrer"&gt;http://127.0.0.1:3000/&lt;/a&gt; and &lt;a href="http://127.0.0.1:8000/" rel="noopener noreferrer"&gt;http://127.0.0.1:8000/&lt;/a&gt; respectively.&lt;/p&gt;

&lt;h1&gt;
  
  
  Docker Environment Setup
&lt;/h1&gt;

&lt;p&gt;Create &lt;strong&gt;client.Dockerfile&lt;/strong&gt; and &lt;strong&gt;server.Dockerfile&lt;/strong&gt; in client and server directory respectively. To establish the necessary Docker environment, we've taken a few important steps. First, we've configured the &lt;strong&gt;Dockerfile&lt;/strong&gt; for both the &lt;strong&gt;client and server components&lt;/strong&gt;. Additionally, we've crafted a customized docker-compose file that will orchestrate the deployment and operation of the entire application stack. By leveraging these foundational components of Docker's infrastructure, we can ensure a streamlined, efficient and scalable approach to our software deployment process.&lt;br&gt;
&lt;br&gt;&lt;br&gt;
&lt;strong&gt;client.Dockerfile&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;

&lt;span class="s"&gt;FROM node:18&lt;/span&gt;

&lt;span class="s"&gt;WORKDIR /app&lt;/span&gt;

&lt;span class="s"&gt;COPY ./ ./&lt;/span&gt;

&lt;span class="s"&gt;RUN npm install&lt;/span&gt;

&lt;span class="s"&gt;EXPOSE &lt;/span&gt;&lt;span class="m"&gt;3000&lt;/span&gt;

&lt;span class="s"&gt;CMD ["npm", "run", "start"]&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;server.Dockerfile&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;

&lt;span class="s"&gt;FROM node:18&lt;/span&gt;

&lt;span class="s"&gt;WORKDIR /app&lt;/span&gt;

&lt;span class="s"&gt;COPY ./  ./&lt;/span&gt;

&lt;span class="s"&gt;RUN npm install&lt;/span&gt;

&lt;span class="s"&gt;EXPOSE &lt;/span&gt;&lt;span class="m"&gt;8000&lt;/span&gt;

&lt;span class="s"&gt;CMD ["npm", "run", "start"]&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Above two Dockerfiles used to build a Docker image for a React and Node.js applications respectively.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;FROM node:18 specifies the base image to use for this application. In this case, it uses the official Node.js Docker image with version 18.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;WORKDIR **/app**&lt;/code&gt; sets the working directory of the container to /app. This is where the application code and files will be stored.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;COPY ./ ./&lt;/code&gt; copies the contents of the current directory (where the Dockerfile is located) to the container's working directory. This includes the application code and files.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;RUN npm install&lt;/code&gt; runs the npm install command in the container. This installs all the dependencies required by the application.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;EXPOSE 8000&lt;/code&gt; exposes port 8000 of the container to the docker network. This means that the application running in the container can be accessed through this port in &lt;strong&gt;Docker network&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;CMD ["npm", "run", "start"]&lt;/code&gt; specifies the command to run when the container is started. In this case, it runs the npm run start command, which starts the application. This command will be executed automatically when the container is launched.

Create &lt;strong&gt;docker-compose.yml&lt;/strong&gt; in root directory. The purpose of docker-compose.yml is to define and orchestrate the deployment and operation of multiple Docker containers that work together to make up a complete application stack. It enables developers to define and configure the various services required by the application, including their dependencies and networking, in a single file. This makes it easier to manage and deploy complex applications in a consistent and repeatable manner.

```yaml
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;networks:&lt;br&gt;
  dev:&lt;br&gt;
    driver: bridge&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Above markup creates a docker network dev. Now add all the applicaions (services) under `services` block.
```yaml


services:
  server:
    build:
      context: ./server
      dockerfile: server.Dockerfile
    image: dev-server
    container_name: dev_server
    tty: true
    restart: unless-stopped
    working_dir: /app
    volumes:
      - ./server:/app
      - /app/node_modules
    networks:
      - dev


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Above configuration shows a "server" service defined within a &lt;code&gt;docker-compose.yml&lt;/code&gt; file. Let's take a closer look at each configuration option:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;build&lt;/code&gt;: Specifies how the container image will be built. In this case, it references a Dockerfile located in the &lt;code&gt;./server&lt;/code&gt; directory.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;image&lt;/code&gt;: Specifies the name for the resulting image that will be created from the &lt;code&gt;Dockerfile&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;container_name&lt;/code&gt;: Sets the name for the running container. In this case, it's set to "dev_server".&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;tty&lt;/code&gt;: Allocates a pseudo-TTY for the container, which is necessary for certain interactive processes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;restart&lt;/code&gt;: Defines the restart policy for the container. In this example, the container will be automatically restarted unless it is explicitly stopped.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;working_dir&lt;/code&gt;: Sets the working directory for the container. In this case, it's set to "/app".&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;volumes&lt;/code&gt;: Defines the volumes to be mounted in the container. In this example, the &lt;code&gt;server&lt;/code&gt; directory is mapped to the &lt;code&gt;/app&lt;/code&gt; directory in the container, and the &lt;code&gt;/app/node_modules&lt;/code&gt; directory is mounted as a named volume.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;networks&lt;/code&gt;: Specifies the network to which the container will be connected. In this example, it's connected to the "dev" network.&lt;br&gt;
&lt;br&gt;&lt;br&gt;
&lt;strong&gt;docker-compose.yml&lt;/strong&gt;&lt;/p&gt;

&lt;pre class="highlight yaml"&gt;&lt;code&gt;

&lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;dev&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;driver&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bridge&lt;/span&gt;

&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;nginx&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx:stable-alpine&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;always&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;80:80"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./nginx:/etc/nginx/conf.d/&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;dev&lt;/span&gt;

  &lt;span class="na"&gt;server&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;context&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./server&lt;/span&gt;
      &lt;span class="na"&gt;dockerfile&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;server.Dockerfile&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dev-server&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dev_server&lt;/span&gt;
    &lt;span class="na"&gt;tty&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
    &lt;span class="na"&gt;working_dir&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/app&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./server:/app&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/app/node_modules&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;dev&lt;/span&gt;

  &lt;span class="na"&gt;client&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;context&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./client&lt;/span&gt;
      &lt;span class="na"&gt;dockerfile&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;client.Dockerfile&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dev-client&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dev_client&lt;/span&gt;
    &lt;span class="na"&gt;tty&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
    &lt;span class="na"&gt;working_dir&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/app&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./client:/app&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/app/node_modules&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;dev&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;
Change the &lt;strong&gt;nginx.conf&lt;/strong&gt; within nginx directory to following.&lt;br&gt;
&lt;strong&gt;nginx.conf&lt;/strong&gt;&lt;/p&gt;

&lt;pre class="highlight yaml"&gt;&lt;code&gt;

&lt;span class="s"&gt;upstream client {&lt;/span&gt;
  &lt;span class="s"&gt;server client:3000;&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;

&lt;span class="s"&gt;upstream server {&lt;/span&gt;
  &lt;span class="s"&gt;server server:8000;&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;

&lt;span class="s"&gt;server {&lt;/span&gt;
    &lt;span class="s"&gt;listen 80;&lt;/span&gt;

    &lt;span class="s"&gt;location / {&lt;/span&gt;
        &lt;span class="s"&gt;proxy_pass http://client/;&lt;/span&gt;
        &lt;span class="s"&gt;proxy_set_header Host $host;&lt;/span&gt;
        &lt;span class="s"&gt;proxy_set_header X-Real-IP $remote_addr;&lt;/span&gt;
        &lt;span class="s"&gt;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;&lt;/span&gt;
    &lt;span class="s"&gt;}&lt;/span&gt;

    &lt;span class="s"&gt;location /api/ {&lt;/span&gt;
        &lt;span class="s"&gt;proxy_pass http://server/;&lt;/span&gt;
        &lt;span class="s"&gt;proxy_set_header Host $host;&lt;/span&gt;
        &lt;span class="s"&gt;proxy_set_header X-Real-IP $remote_addr;&lt;/span&gt;
        &lt;span class="s"&gt;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;&lt;/span&gt;
    &lt;span class="s"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In a Docker network, containers can &lt;strong&gt;communicate&lt;/strong&gt; with each other by their &lt;strong&gt;container names&lt;/strong&gt; as if they were &lt;strong&gt;hostnames&lt;/strong&gt;. When you define a service in a Docker Compose file, a network is automatically created and all the containers for that service are connected to that network.&lt;br&gt;
In the context of Nginx, an upstream block defines a group of servers that can be used as a proxy for client requests. It is typically used when you want to distribute incoming traffic across multiple servers or when you want to implement a load balancer.&lt;br&gt;
&lt;br&gt;&lt;br&gt;
Run &lt;code&gt;sudo docker compose up -d&lt;/code&gt; where docker-compose.yaml is located. The docker-compose up -d command is used to start Docker containers defined in a Docker Compose file in the background and detach the terminal from the container's console output. Access the client side through &lt;a href="http://localhost/" rel="noopener noreferrer"&gt;http://localhost/&lt;/a&gt;&lt;br&gt;
&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Docker Stats&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo68w4jn5wp9g4v3pyk3d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo68w4jn5wp9g4v3pyk3d.png" alt="Image description" width="800" height="90"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Resources:
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/engine/install/ubuntu/" rel="noopener noreferrer"&gt;Insall Docker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/compose/install/linux/#install-using-the-repository" rel="noopener noreferrer"&gt;Install Docker Compose&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-ubuntu-20-04" rel="noopener noreferrer"&gt;Install latest Nodejs Ubuntu&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nodejs.org/en/download" rel="noopener noreferrer"&gt;Install latest Nodejs Windows &lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;/ul&gt;

</description>
      <category>nginx</category>
      <category>webdev</category>
      <category>reverseproxy</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
