<?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: Adnan Latif</title>
    <description>The latest articles on DEV Community by Adnan Latif (@adnanlatif).</description>
    <link>https://dev.to/adnanlatif</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%2F1207995%2Ff1dd6c58-83a2-4e10-8018-2c047fe03bae.jpeg</url>
      <title>DEV Community: Adnan Latif</title>
      <link>https://dev.to/adnanlatif</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/adnanlatif"/>
    <language>en</language>
    <item>
      <title>From 41 Minutes to 8 Minutes: How I Made Our CI/CD Pipeline 5x Faster</title>
      <dc:creator>Adnan Latif</dc:creator>
      <pubDate>Mon, 16 Dec 2024 18:23:11 +0000</pubDate>
      <link>https://dev.to/adnanlatif/from-41-minutes-to-8-minutes-how-i-made-our-cicd-pipeline-5x-faster-49d1</link>
      <guid>https://dev.to/adnanlatif/from-41-minutes-to-8-minutes-how-i-made-our-cicd-pipeline-5x-faster-49d1</guid>
      <description>&lt;h2&gt;
  
  
  From 41 Minutes to 8 Minutes: How I Made Our CI/CD Pipeline 5x Faster
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F647jyd0ew5fptwh325ki.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F647jyd0ew5fptwh325ki.jpeg" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;In the world of software development, time is everything. Continuous Integration/Continuous Deployment pipelines speed the process up, but sometimes it’s the pipeline that makes the process slow down, ironically. This was what brought me to my latest problem when our Jenkins pipeline grew to an unmanageably long 41 minutes per build.&lt;/p&gt;

&lt;p&gt;Determined to eliminate this inefficiency, I analyzed, optimized, and transformed our pipeline from a whopping 41 minutes down to 8 minutes — a 5x improvement! In this article, I’ll walk you through the issues I encountered, the solutions I implemented, and the strategies you can use to supercharge your own pipeline.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Problem&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Our CI/CD pipeline handled the following tasks for both backend and frontend:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Code Checkout&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Static Code Analysis: ESLint, SonarQube&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unit Testing&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Docker Image Build and Push&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Staging Deployment&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Manual Approval and Production Deployment&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At first glance, the pipeline appeared robust, but some issues came into view:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Bloated Docker Build Context&lt;/strong&gt;&lt;br&gt;
The build context — all the files sent into Docker during an image build — had grown to 1.5GB and was taking a really long time to build.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Installing Dependencies Redundantly&lt;/strong&gt;&lt;br&gt;
Every stage in the pipeline had to reinstall the npm dependencies from scratch, thus adding unnecessary delays.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Poor Docker Image Management&lt;/strong&gt;&lt;br&gt;
Docker images were rebuilt and pushed to the registry, even when no changes had occurred.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;No Parallel Execution&lt;/strong&gt;&lt;br&gt;
Similarly, all tasks, such as static code analysis or testing, were run sequentially.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Manual Deployment Steps&lt;/strong&gt;&lt;br&gt;
Since this involved updating AWS ECS task definitions manually, deployment of the backend was time-consuming and prone to human error.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Solutions&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Here’s How I Transformed the Pipeline for a 5x Optimization.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reduce the size of the Docker Build Context
&lt;/h2&gt;

&lt;p&gt;The Docker build context was unnecessarily large due to unfiltered project directories. We can use .dockerignore file to exclude certain files such as node_modules, logs etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key File&lt;/strong&gt;: .dockerignore&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node_modules  
*.log  
dist  
coverage  
test-results
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Impact&lt;/strong&gt;:&lt;br&gt;
Reduced the build context size from 1.5GB to ~10MB, reducing the transfer time from 30 minutes to &amp;lt;1 minute.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Dependency Caching&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Every stage was using npm install. I replaced it with npm ci for reproducibility and activated caching in Jenkins.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Command Update&lt;/strong&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm ci --cache ~/.npm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Impact&lt;/strong&gt;:&lt;br&gt;
Reduced dependency installation time from 3–4 minutes per stage down to &amp;lt;20 seconds.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Improve Docker Image Handling&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Previously, the pipeline would rebuild and push Docker images irrespective of changes. I added the logic to compare the hash of local and remote images, doing a push only if the image changed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Updated Logic&lt;/strong&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def remoteImageHash = sh(returnStdout: true, script: "docker inspect --format='{{.Id}}' $DOCKER_IMAGE:$DOCKER_TAG || echo ''").trim()
def localImageHash = sh(returnStdout: true, script: "docker images --no-trunc -q $DOCKER_IMAGE:$DOCKER_TAG").trim()

if (localImageHash != remoteImageHash) {
    sh 'docker push $DOCKER_IMAGE:$DOCKER_TAG'
} else {
    echo "Image has not changed; skipping push."
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Impact&lt;/strong&gt;:&lt;br&gt;
Avoided unnecessary pushes, saving 3–5 minutes per build.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Run Static Analysis and Testing in Parallel&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;I extended the Jenkins pipeline to make use of the parallel directive so that tasks like ESLint, SonarQube analysis, and unit tests could proceed simultaneously.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Updated Pipeline&lt;/strong&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;stage('Static Code Analysis') {
    parallel {
        stage('Frontend ESLint') {
            steps {
                sh 'npm run lint'
            }
        }
        stage('Backend SonarQube') {
            steps {
                withSonarQubeEnv() {
                    sh 'sonar-scanner'
                }
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Impact&lt;/strong&gt;:&lt;br&gt;
Reduced static analysis and testing time by 50%.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Automatic Backend Deployment&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Manual updates to AWS ECS task definitions were time-consuming and error-prone. I automated this step using the AWS CLI.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Automated Script&lt;/strong&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def taskDefinitionJson = """
{
    "family": "$ECS_TASK_DEFINITION_NAME",
    "containerDefinitions": [
        {
            "name": "backend",
            "image": "$DOCKER_IMAGE:$DOCKER_TAG",
            "memory": 512,
            "cpu": 256,
            "essential": true
        }
    ]
}
"""
sh "echo '${taskDefinitionJson}' &amp;gt; task-definition.json"
sh "aws ecs register-task-definition --cli-input-json file://task-definition.json --region $AWS_REGION"
sh "aws ecs update-service --cluster $ECS_CLUSTER_NAME --service $ECS_SERVICE_NAME --task-definition $ECS_TASK_DEFINITION_NAME --region $AWS_REGION"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Impact&lt;/strong&gt;:&lt;br&gt;
Streamlined deployments, shaving off 5 minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Results&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;After these optimizations, the pipeline time came down from 41 minutes to just 8 minutes — a 5x improvement. Here’s a detailed comparison:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Ffpcsn2ce51ddolbqa7ub.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Ffpcsn2ce51ddolbqa7ub.png" alt="Comparison Table" width="756" height="243"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Lessons Learned&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Logs Are Your Best Friend&lt;/strong&gt;: Analyze logs to pinpoint bottlenecks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Caching Saves the Day&lt;/strong&gt;: Effective use of caching can drastically cut build times.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Run Tasks in Parallel&lt;/strong&gt;: Use parallel execution for immediate time savings.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Exclude Irrelevant Files&lt;/strong&gt;: A .dockerignore file can significantly boost performance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Automate Repetitive Tasks&lt;/strong&gt;: Automation eliminates errors and speeds up workflows.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;Optimizing a CI/CD pipeline was an eye-opening experience. Targeting key bottlenecks and implementing strategic changes transformed a 41-minute chore into an 8-minute powerhouse. The result? Faster deployments, happier developers, and more time to focus on features.&lt;/p&gt;

&lt;p&gt;If you’re struggling with a slow pipeline, start by identifying bottlenecks, leverage caching, parallelize tasks, and automate repetitive steps. Even small tweaks can lead to massive gains.&lt;/p&gt;

&lt;p&gt;How much time have you saved by optimizing your CI/CD pipeline? Share your experiences and tips in the comments below!&lt;/p&gt;

</description>
      <category>devops</category>
      <category>cicd</category>
      <category>jenkins</category>
      <category>docker</category>
    </item>
    <item>
      <title>From Confusion to Clarity: Understanding ‘this’ in JavaScript</title>
      <dc:creator>Adnan Latif</dc:creator>
      <pubDate>Tue, 30 Jan 2024 08:27:28 +0000</pubDate>
      <link>https://dev.to/adnanlatif/from-confusion-to-clarity-understanding-this-in-javascript-59gg</link>
      <guid>https://dev.to/adnanlatif/from-confusion-to-clarity-understanding-this-in-javascript-59gg</guid>
      <description>&lt;h2&gt;
  
  
  From Confusion to Clarity: Understanding ‘this’ in JavaScript
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cZ7kuWzo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2476/1%2AGHA1sOf3WnPtYGdVHW7H4A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cZ7kuWzo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2476/1%2AGHA1sOf3WnPtYGdVHW7H4A.png" alt="Main Image" width="800" height="424"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the world of JavaScript, the this keyword often stands as a mystery, perplexing many new developers. Understanding this is crucial for writing efficient and bug-free code. In this article, we'll embark on a journey to demystify this and unravel its secrets in simple terms that even a novice developer can grasp.&lt;/p&gt;

&lt;p&gt;What is “this”? In JavaScript, this is a special keyword that refers to the context in which a function is called. This context can vary based on how and where a function is invoked. Think of this as a placeholder that dynamically represents different values depending on the situation.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Understanding this in Different Contexts:&lt;br&gt;
 Inside a function body in JavaScript, the behavior of the &lt;em&gt;this&lt;/em&gt; keyword depends on how the function is called.&lt;br&gt;
 &lt;strong&gt;Regular Functions:&lt;/strong&gt;&lt;br&gt;
 In non-arrow functions, &lt;em&gt;this&lt;/em&gt; is determined by the caller of the function.&lt;br&gt;
 If the function is called as a method of an object, &lt;em&gt;this&lt;/em&gt; refers to that object.&lt;br&gt;
 If the function is called without a context, &lt;em&gt;this&lt;/em&gt; defaults to the global object (&lt;em&gt;window&lt;/em&gt; in browsers, &lt;em&gt;global&lt;/em&gt; in Node.js), or &lt;em&gt;undefined&lt;/em&gt; in strict mode.&lt;br&gt;
 &lt;strong&gt;Arrow Functions:&lt;/strong&gt;&lt;br&gt;
 Arrow functions do not have their own &lt;em&gt;this&lt;/em&gt; binding. Instead, they inherit &lt;em&gt;this&lt;/em&gt; from the enclosing lexical scope.&lt;br&gt;
 In other words, &lt;em&gt;this&lt;/em&gt; inside an arrow function refers to the &lt;em&gt;this&lt;/em&gt; value of the enclosing scope where the arrow function was defined.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Global Context:&lt;/strong&gt; When a function is called without any explicit context, this refers to the global object. In web browsers, this is usually the window object.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xlW25sqd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2416/1%2A-8DzXEBYZdxWU2PrYOK07Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xlW25sqd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2416/1%2A-8DzXEBYZdxWU2PrYOK07Q.png" alt="this in global context" width="800" height="421"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Object Method:&lt;/strong&gt; When a function is called as a method of an object, this points to the object that owns the function.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9oI-NhIQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2416/1%2ABoKUGOG5Ircb2_4dsCusig.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9oI-NhIQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2416/1%2ABoKUGOG5Ircb2_4dsCusig.png" alt="this in object" width="800" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Arrow Functions:&lt;/strong&gt; Arrow functions do not have their own this binding and inherit this from the enclosing lexical scope.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yG4ZNHU8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2812/1%2ABV3Cft9MA5lqSmpfHzJNpQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yG4ZNHU8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2812/1%2ABV3Cft9MA5lqSmpfHzJNpQ.png" alt="this in arrow function" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Constructor Function:&lt;/strong&gt; Inside a constructor function, this refers to the specific instance of the object being created.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---CJeo-fF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2208/1%2AHK0gchWVUnu5e94TIAv_-g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---CJeo-fF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2208/1%2AHK0gchWVUnu5e94TIAv_-g.png" alt="this in constructor" width="800" height="514"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Event Handlers:&lt;/strong&gt; In event handler functions, this typically points to the DOM element that triggered the event.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4tN-Xl_P--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2360/1%2ADDvjXXemD8d_AEyyLzAapw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4tN-Xl_P--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2360/1%2ADDvjXXemD8d_AEyyLzAapw.png" alt="this in event handler" width="800" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Node.js Environment:&lt;/strong&gt; In Node.js, this behaves differently compared to the browser environment. In most cases, this in Node.js modules refers to the module.exports object, providing access to the module's exports and scoped variables.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SKSMxbNb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2360/1%2A9eFNy5Cv2dJFs6z6-TBV-A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SKSMxbNb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2360/1%2A9eFNy5Cv2dJFs6z6-TBV-A.png" alt="this in node" width="800" height="607"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Explicit Binding:&lt;/strong&gt; JavaScript provides methods like call, apply, and bind to explicitly set the value of this when calling a function.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oCreU7zC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2360/1%2ANCjKg0ZmTX9zWLK5zDW9nw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oCreU7zC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2360/1%2ANCjKg0ZmTX9zWLK5zDW9nw.png" alt="this in call, apply and bind" width="800" height="532"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Understanding this is essential for writing robust JavaScript code. By grasping the various contexts in which this operates, developers can wield its power effectively. Remember, this is not as daunting as it seems – it's just a pointer that adapts to its surroundings, guiding your functions to interact with the right objects at the right time. Happy coding!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>javascriptinterview</category>
    </item>
    <item>
      <title>JavaScript Tips and Tricks</title>
      <dc:creator>Adnan Latif</dc:creator>
      <pubDate>Sat, 18 Nov 2023 23:15:58 +0000</pubDate>
      <link>https://dev.to/adnanlatif/javascript-tips-and-tricks-49mi</link>
      <guid>https://dev.to/adnanlatif/javascript-tips-and-tricks-49mi</guid>
      <description>&lt;h2&gt;
  
  
  JavaScript Tips and Tricks
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--d2ThMrYZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/4120/1%2A06Q7HHp3ppGAdrIFwNVDVg.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--d2ThMrYZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/4120/1%2A06Q7HHp3ppGAdrIFwNVDVg.jpeg" alt="" width="800" height="423"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you know, JavaScript is the number one programming language in the world, the language of the web, of mobile hybrid apps (like &lt;a href="https://reactnative.dev/"&gt;React Native&lt;/a&gt;), of the server side (like &lt;a href="https://nodejs.org/en/"&gt;NodeJS&lt;/a&gt; ) and has many other implementations. It’s also the starting point for many new developers to the world of programming, as it can be used to display a simple alert in the web browser but also to control a robot (using &lt;a href="https://nodebots.io/"&gt;nodebot&lt;/a&gt;, or nodruino). The developers who master JavaScript and write organized and performant code have become the most sought after in the job market.&lt;/p&gt;

&lt;p&gt;In this article, I’ll share a set of JavaScript tips, tricks and best practices that should be known by all JavaScript developers regardless of their browser/engine or the SSJS (Server Side JavaScript) interpreter.&lt;/p&gt;

&lt;h2&gt;
  
  
  *&lt;em&gt;use *&lt;/em&gt;=== *&lt;em&gt;instead of *&lt;/em&gt;==
&lt;/h2&gt;

&lt;p&gt;The == (or !=) operator performs an automatic type conversion if needed. The === (or !==) operator will not perform any conversion. It compares the value and the type, which could be considered faster than ==.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JbvwQbIb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2312/1%2A5j2S_Ot3LJmeMrISerV0CQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JbvwQbIb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2312/1%2A5j2S_Ot3LJmeMrISerV0CQ.png" alt="" width="800" height="489"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;undefined, null, 0, false, NaN, ‘’(empty string) are all falsy.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Find max and min from an array
&lt;/h2&gt;

&lt;p&gt;The traditional way to find min and max is loop through each element of array and find min and max. Below code snippet is showing to find min and max from array using spread operator.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2jiQRsAe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2AgJ1aYxHa5cjJD5WipPxbLQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2jiQRsAe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2AgJ1aYxHa5cjJD5WipPxbLQ.png" alt="" width="800" height="507"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Merging two arrays
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--l0LPPKah--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2420/1%2AIiNhQA0SQtpnAxqTAIRv8A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--l0LPPKah--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2420/1%2AIiNhQA0SQtpnAxqTAIRv8A.png" alt="" width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Repeating string multiple times
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mb5CEe2w--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2A8iFhY9LwId80tXP6Wqxf0A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mb5CEe2w--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2A8iFhY9LwId80tXP6Wqxf0A.png" alt="" width="681" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  String to Number conversion
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mFpZP_Cz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2A2ENDkJr_JbrmJtYSggZ3Rw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mFpZP_Cz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2A2ENDkJr_JbrmJtYSggZ3Rw.png" alt="" width="800" height="580"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Multiple variable assignments
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KyTjaWvW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2ApolManQb7avrsOb-o-W2Jw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KyTjaWvW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2ApolManQb7avrsOb-o-W2Jw.png" alt="" width="800" height="660"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Multiple condition check
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--X_6jWjzS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3132/1%2AYU67GcqRmuS74MM8HNzDVw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--X_6jWjzS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3132/1%2AYU67GcqRmuS74MM8HNzDVw.png" alt="" width="800" height="399"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Remove duplicates from an array
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LuJjNjxY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2624/1%2A_gEXMCTT80a7GJBCpHmZ1A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LuJjNjxY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2624/1%2A_gEXMCTT80a7GJBCpHmZ1A.png" alt="" width="800" height="567"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Sum the values of an array
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TFxZ7OVu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2136/1%2A0MkwswVNT92WWb8le1HdYg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TFxZ7OVu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2136/1%2A0MkwswVNT92WWb8le1HdYg.png" alt="" width="800" height="616"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Convert a string to an array
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CVbXMnzT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2456/1%2Ai26ZtsiEaVnR4pBdo-N6Dg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CVbXMnzT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2456/1%2Ai26ZtsiEaVnR4pBdo-N6Dg.png" alt="" width="800" height="560"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Remove falsey values from an array
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OxBBC7Rz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3232/1%2A6_qYZQGMWFV2dQnk5FTWVg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OxBBC7Rz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3232/1%2A6_qYZQGMWFV2dQnk5FTWVg.png" alt="" width="800" height="295"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Alternatives of for loop
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HNjYuoG5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2ADBCKNd9VHlKQPt14fxhuPA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HNjYuoG5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2ADBCKNd9VHlKQPt14fxhuPA.png" alt="" width="800" height="787"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  OR Short circuit
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vjBkruMX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2792/1%2AjaRFy9Zi8lSE4uE0brDmRw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vjBkruMX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2792/1%2AjaRFy9Zi8lSE4uE0brDmRw.png" alt="" width="800" height="535"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  AND Short circuit
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--r4e97opK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2928/1%2ATj0La0eChDoLdl7wlDd0QQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--r4e97opK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2928/1%2ATj0La0eChDoLdl7wlDd0QQ.png" alt="" width="800" height="578"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Exponent power
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jeF6MbBx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2AbUPRweugl3OZwskfeoJKhA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jeF6MbBx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2AbUPRweugl3OZwskfeoJKhA.png" alt="" width="800" height="578"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Count function parameters
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--S-ACMFiU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2As_Hu-wHUoEAkUngBgyzDTQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--S-ACMFiU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2As_Hu-wHUoEAkUngBgyzDTQ.png" alt="" width="563" height="392"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Assign default function parameter
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vrqsKwsx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2220/1%2AU03MFq79zxo7rjIUjgBOxA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vrqsKwsx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2220/1%2AU03MFq79zxo7rjIUjgBOxA.png" alt="" width="800" height="431"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Check if key exists in the object&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kK3Dyda2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2604/1%2A56cGx2ErQ0nTHeawQi9Pvw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kK3Dyda2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2604/1%2A56cGx2ErQ0nTHeawQi9Pvw.png" alt="" width="800" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Object property assignment
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eS95TPEl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3636/1%2ATwflyJ8BiQACWznFKKMEig.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eS95TPEl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3636/1%2ATwflyJ8BiQACWznFKKMEig.png" alt="" width="800" height="344"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Assigning object value property to a variable
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hlt1ZwL---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2220/1%2AqeS6GEGANg1uNpz1A6TzjA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hlt1ZwL---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2220/1%2AqeS6GEGANg1uNpz1A6TzjA.png" alt="" width="800" height="644"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Removing multiple properties from an object
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uBBQVf9q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2084/1%2Acjaz3KW-h0cIzxMaVeqq-w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uBBQVf9q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2084/1%2Acjaz3KW-h0cIzxMaVeqq-w.png" alt="" width="800" height="631"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here are my two bits of contribution in JavaScript community. I hope these code snippets will help someone to learn some tips and tricks in JavaScript.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>tips</category>
    </item>
    <item>
      <title>Deep Dive into Docker</title>
      <dc:creator>Adnan Latif</dc:creator>
      <pubDate>Tue, 14 Nov 2023 19:44:26 +0000</pubDate>
      <link>https://dev.to/adnanlatif/deep-dive-into-docker-2if</link>
      <guid>https://dev.to/adnanlatif/deep-dive-into-docker-2if</guid>
      <description>&lt;p&gt;&lt;strong&gt;What is Docker&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Docker is an open-source software platform to create, deploy and manage virtualized application containers on a common operating system (OS), with an ecosystem of allied tools. Docker container technology debuted in 2013; Docker Inc. was formed to support a commercial edition of container management software and be the principal sponsor of an open-source version. Mirantis acquired the Docker Enterprise business in November 2019.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How Docker works&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Docker packages, provisions, and runs containers. Container technology is available through the operating system: A container packages the application service or function with all the libraries, configuration files, dependencies, and other necessary parts and parameters to operate. Each container shares the services of one underlying operating system. Docker images contain all the dependencies needed to execute code inside a container, so containers that move between Docker environments with the same OS work with no changes.&lt;/p&gt;

&lt;p&gt;Docker uses resource isolation in the OS kernel to run multiple containers on the same OS. This is different than virtual machines (VMs), which encapsulate an entire OS with executable code on top of an abstracted layer of physical hardware resources.&lt;/p&gt;

&lt;p&gt;Docker was created to work on the Linux platform, but has extended to offer greater support for non-Linux operating systems, including Microsoft Windows and Apple OS X. Versions of Docker for Amazon Web Services (AWS) and Microsoft Azure are available.&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%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2A0hVg1ePfmVBYGJZsbPmuwA.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%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2A0hVg1ePfmVBYGJZsbPmuwA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why do we need Docker?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Well, Docker is a platform for building, running, and shipping applications in a consistent manner. So, if your application works on your development machine, it can run and function the same way on other machines. If you have been developing software for a while, you’ve probably come across this situation where your application works on your development machine but doesn’t somewhere else. Can you think of three reasons why this happens? Well, this can happen if one or more files are not included as part of your deployment, so your application is not completely deployed. It’s missing something. This can also happen if the target machine is running a different version of some software that your application needs. Let’s say your application needs Node version 14, but the target machine is running Node version 9. This can also happen if the configuration settings like environment variables are different across these machines. And this is where Docker comes to the rescue.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What are Containers in Docker?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;With Docker, we can easily package up our application with everything it needs and run it anywhere on any machine with Docker. So, if your application needs a given version of Node and MongoDB, all of these will be included in your Applications package. Now you can take this package and run it on any machine that runs Docker. So, if it works on your development machine, it’s going to work on your test and production machines. Now there’s more. If someone joins your team, they don’t have to spend half a day or so setting up a new machine to run your application. They don’t have to install and configure all these dependencies. They simply tell Docker to bring up your application, and Docker itself will automatically download and run these dependencies inside an isolated environment called a container and this is the beauty of Docker.&lt;/p&gt;

&lt;p&gt;This isolated environment allows multiple applications to use different versions of some software side by side. So, one application may use Node version 14. Another application may use Node version 9. Both these applications can run side by side on the same machine without messing with each other. So, this is how Docker allows us to consistently run an application on different machines. Now, there is one more benefit here. When we’re done with this application and don’t want to work on it anymore, we can remove the application and all its dependencies in one go without Docker.&lt;/p&gt;

&lt;p&gt;As we work on different projects, our development machine gets cluttered with so many libraries and tools that are used by different applications, and then after a while, we don’t know if we can remove one or more of these tools because we’re always afraid that we would mess up with some application with Docker, we don’t have to worry about this because each application runs with its dependencies inside an isolated environment. We can safely remove an application with all its dependencies to clean up our machine. Isn’t that great? So, in a nutshell. Docker helps us consistently build, run, and ship our applications and that’s why a lot of employers are looking for people with Docker skills these days. So if you’re pursuing a job as a software or DevOps engineer, I highly encourage you to learn Docker and learn it well.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Difference between Containers and Virtual Machines?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So, in the last paragraph, I briefly talked about containers. The container is an isolated environment for running an application. Now. One of the questions that often comes up is how our containers are different from virtual machines or VMS. Do you know the differences Well, a virtual machine as the name implies, is an abstraction of a machine or physical hardware. So, we can run several virtual machines on a real physical machine. For example, we can have a Mac, and on this Mac, we can run two virtual machines, one running Windows, and the other running Linux. How do we do that using a tool called Hyper Visor I know it’s one of those computer science names. In simple terms, the Hyper Visor is a software we use to create and manage virtual machines. There are many hypervisors available out there, like Virtual Box and VMware which are cross-platform. So, they can run on Windows or Mac. OS and Linux and Hyper-V (which is only for Windows). So, with a hyper Visor, we can manage virtual machines. Now, what is the benefit of building virtual machines Well, for us, software developers, we can run an application in isolation inside a virtual machine. So, on the same physical machine, we can have two different virtual machines. Each runs a completely different application and each application has the exact dependencies it needs.&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%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2Af5P2mIOspp5ssTKjwpnGlQ.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%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2Af5P2mIOspp5ssTKjwpnGlQ.png"&gt;&lt;/a&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%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2A5xYZbrOxfFO73f370Ykjxw.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%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2A5xYZbrOxfFO73f370Ykjxw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, application one may use node version 14 and Mongo Db Version 4, and one application may use node version nine and Mongo Db Version 3. All these are running on the same machine but in different isolated environments. That’s one of the benefits of virtual machines. However, there are several problems with this model. Each virtual machine needs a full copy of an operating system that needs to be licensed, patched, and monitored. And that’s why these virtual machines are slow to start because the entire operating system must be loaded just like starting your computer. Another problem is that these virtual machines are resource-intensive because each virtual machine takes a slice of the actual physical hardware resources like CPU memory and disk space. So, if you have eight gigabytes of memory, that memory must be divided between different virtual machines. Of course, we can decide how much memory to allocate to each virtual machine. But at the end of the day, we have a limit in terms of the number of VMS, we can run on a machine, usually a handful, otherwise we’re going to run out of hardware resources. Now let’s talk about containers, containers give us the same kind of isolation, so we can run multiple applications in isolation, but they are more lightweight. They don’t need a full operating system. In fact, all containers on a single machine share the operating system of the host. So that means we need to license, patch, and monitor a single operating system. Also, because the operating system has already started on the host, a container can start up quickly, usually in a second, sometimes less. These containers also don’t need a slice of the hardware resources on the host, so we don’t need to give them a specific number of CPU cores or a slice of memory or disk space. So, on a single host, we can run tens or even hundreds of containers side by side. So, these are the differences between containers and virtual machines.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Docker Architecture&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let’s talk about the architecture of Docker. So, you understand how it works Docker uses a client-server architecture. So, it has a client component that talks to a server component using a restful API the server also called the Docker engine sits in the background and takes care of building and running Docker containers. But technically a container is just a process, like other processes running on your computer. But it’s a special kind of process which we’re going to talk about soon Now, as I told you, unlike virtual machines, containers don’t contain a full-blown operating system. Instead, all containers on a host share the operating system of the host. Now, more accurately, all these containers share the kernel of the host. What’s the kernel? The kernel is the core of an operating system. It’s like the engine of a car. It’s the part that manages all applications as well as hardware resources like memory and CPU every operating system has its own kernel or engine. These kernels have different APIs that’s why we cannot run a Windows application on Linux because under the hood this application needs to talk to the kernel of the underlying operating system. Okay, so that means on a Linux machine, we can only run Linux containers because these containers need Linux On a Windows Machine. However, we can run both Windows and Linux containers because Windows 10 is now shipped with a custom-built Linux kernel. This is in addition to the Windows Kernel, that’s always been in Windows. It’s not a replacement. So, with this Linux kernel now we can run Linux applications natively on Windows, so on Windows, we can run both Linux and Windows containers. Our Windows containers share the Windows kernel and our Linux containers share the Linux kernel. Okay, now, what about Mac OS Well, Mac OS has its own kernel, which is different from Linux and Windows kernels, and this kernel does not have native support for continuous applications. So docker on Mac uses a lightweight Linux virtual machine to run Linux containers. Alright enough about the architecture. Next we’re going to install Docker and that’s where the fun begins.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Now the fun part begins, where we get our hands dirty with Docker&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let’s install the latest version of Docker. If you have an existing version of Docker on your machine, I highly encourage you to upgrade to the latest version because your version might be old and not compatible with the version I’m using this Quest.&lt;/p&gt;

&lt;p&gt;I am using the version at the time of blog is 20.10.13.&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%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AAHWH83lsjhCRvaFwHXg5zg.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%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AAHWH83lsjhCRvaFwHXg5zg.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Go to &lt;a href="https://docs.docker.com/get-docker/" rel="noopener noreferrer"&gt;Docker docs&lt;/a&gt; to get the latest version of docker. Docker desktop is available for Windows, Mac and Linux. We have a Docker desktop which is the combination of the Docker engine, plus a bunch of other tools.&lt;/p&gt;

&lt;p&gt;Let’s look at the instructions for Windows. You can download the latest version from Docker Hub and make sure to read system requirement. What are the things that is really important is enabling hyper-v and containers Windows features just go to the settings where you can turn on or turn off those features.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Docker Daily use Commands&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;docker version&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This command is used to get the currently installed version of docker.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;docker pull&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Usage: docker pull &lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This command is used to pull images from the &lt;strong&gt;docker repository&lt;/strong&gt;(hub.docker.com).&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;docker run&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Usage: docker run -it -d &lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This command is used to create a container from an image.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;-d: To start a container in detached mode, you use -d=true or just -d option. By design, containers started in detached mode exit when the root process used to run the container exits, unless you also specify the --rm option.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;-it: For interactive processes (like a shell), you must use -i -t together in order to allocate a tty for the container process. -i -t is often written -it as you’ll see in later examples. Specifying -t is forbidden when the client is receiving its standard input from a pipe.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;docker ps&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This command is used to list the running containers.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;docker ps -a&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This command is used to show all the running and exited containers.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;docker exec&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Usage: docker exec -it  bash&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This command is used to access the running container.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;docker stop&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Usage: docker stop &lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This command stops a running container.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;docker kill&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Usage: docker kill &lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This command kills the container by stopping its execution immediately. The difference between ‘docker kill’ and ‘docker stop’ is that ‘docker stop’ gives the container time to shutdown gracefully, in situations when it is taking too much time for getting the container to stop, one can opt to kill it.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;docker commit&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Usage: docker commit  &lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This command creates a new image of an edited container on the local system.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;docker login&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This command is used to login to the docker hub repository.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;docker push&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Usage: docker push &lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This command is used to push an image to the docker hub repository.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;docker images&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This command lists all the locally stored docker images.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;docker rm&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Usage: docker rm &lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This command is used to delete a stopped container.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;docker rmi&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Usage: docker rmi &lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This command is used to delete an image from local storage.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;docker build&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Usage: docker build &lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This command is used to build an image from a specified docker file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating Our First Docker Application
&lt;/h2&gt;

&lt;p&gt;Let's say we have a PHP application and want to deploy it to our staging or production server. First, we make sure we have the docker configuration script included in the root directory of the application.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Create a Dockerfile in your application&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Create a file with name Dockerfile at the root of your application and include the code below to tell Docker what to do when running in the production or staging environment&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM node:alpine
COPY . /app
WORKDIR /app
CMD node app.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Above is a sample docker script which configures Node on a staging or production server.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Installing Docker on Staging Or Production Server&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For Mac get docker &lt;a href="https://docs.docker.com/docker-for-mac/install/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For Windows go &lt;a href="https://docs.docker.com/docker-for-windows/install/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For Linux go &lt;a href="https://docs.docker.com/desktop/linux/install/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Running Docker&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;After docker is installed on the staging or production server, &lt;strong&gt;&lt;em&gt;click on the whale icon&lt;/em&gt;&lt;/strong&gt; to run docker&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Deploying Your Application&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Copy the application to the staging or production server and do the following&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Navigate to the project directory on the terminal and create a docker image.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Run the following command in the terminal and it will create a docker image of the application and download all the necessary dependencies needed for the application to run successfully&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker build -t &amp;lt;name to give to your image&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Convert Docker image of the Application into a Running container.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Run the following command in terminal and it will use create a running container with all the needed dependencies and start the application.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run -p 9090:80 &amp;lt;name to give to your container&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The 9090 is the port we want to access our application on. 80 is the port the container is exposing for the host to access.&lt;/p&gt;

&lt;h2&gt;
  
  
  Below are some useful Docker commands
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Stopping a running image&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker stop &amp;lt;id-of-image&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Starting an image which is not running&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker start &amp;lt;id-of-image&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Removing an image from docker&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker rmi &amp;lt;id-of-image&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Removing a container from docker&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker rm &amp;lt;id-of-container&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;For the moment that’s enough to understand what is docker and how we can use it. In my next blog we will write a full React and Node app and run it on Docker by using&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker-compose.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;With docker-compose.yml we don’t need to restart Docker again and again to publish the new changes. When we save the file Docker will automatically publish the new changes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This post was originally posted on &lt;a href="https://medium.com/@alatif.bwp/deep-dive-into-docker-81549b1e6dad" rel="noopener noreferrer"&gt;Medium.com&lt;/a&gt; by me. 😃&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
