<?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: Ahaiwe Emmanuel</title>
    <description>The latest articles on DEV Community by Ahaiwe Emmanuel (@emmygozi).</description>
    <link>https://dev.to/emmygozi</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%2F289776%2F2574040f-1473-4b04-96d9-08c6232e4916.png</url>
      <title>DEV Community: Ahaiwe Emmanuel</title>
      <link>https://dev.to/emmygozi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/emmygozi"/>
    <language>en</language>
    <item>
      <title>Integrate Docker Image Signing in CI Pipeline</title>
      <dc:creator>Ahaiwe Emmanuel</dc:creator>
      <pubDate>Tue, 23 May 2023 21:02:22 +0000</pubDate>
      <link>https://dev.to/emmygozi/stop-hackers-from-altering-your-app-by-signing-your-docker-image-in-circleci-2nhb</link>
      <guid>https://dev.to/emmygozi/stop-hackers-from-altering-your-app-by-signing-your-docker-image-in-circleci-2nhb</guid>
      <description>&lt;p&gt;&lt;strong&gt;Why Bother with Docker Image Signing?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;a. Supply chain security: Ensures that the image is vetted before deployment to a production environment.&lt;/p&gt;

&lt;p&gt;b. To pass vulnerability tests and checks: Vulnerability assessment tools used by QA engineers and other testers analyze the integrity of images to ensure it is unmodified and original. It verifies that the image is from the expected source.&lt;/p&gt;

&lt;p&gt;c. Customer Trust: Customers and consumers of the image can have confidence in its originality and integrity.&lt;/p&gt;

&lt;p&gt;d. Image Integrity: If anyone without access to the source tries to modify it, the signature verification would fail. Hence only you can sign your image with your chosen password or key. &lt;/p&gt;

&lt;p&gt;As an engineer, you want to maintain the integrity of the applications you are deploying to the production environment, even when there are attacks by shady internet characters. For Docker, there is a manual way to do this by doing &lt;code&gt;docker sign trust image:tag&lt;/code&gt; before pushing the image to your repository and subsequently, deployment. Automating this process on your continuous integration is what this article focuses on. Our tools of choice are Github and CircleCI and cosign.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisite&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Integrate CircleCI with GitHub as seen &lt;a href="https://circleci.com/docs/getting-started/"&gt;here&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Container &lt;a href="https://docs.docker.com/docker-hub/quickstart/"&gt;repository&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A Dockerfile to build your &lt;a href="https://nodejs.org/en/docs/guides/nodejs-docker-webapp"&gt;image&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Let's Dive Right In&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Create CircleCI Folder&lt;/em&gt;
Create a CircleCI job with Docker and Nodejs preinstalled into the workflow. To do this, create a &lt;strong&gt;.circleci&lt;/strong&gt;  folder at the root of your project. In that folder, create a &lt;strong&gt;config.yml&lt;/strong&gt; file with the given configurations:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: 2.1
jobs:
  deploy-sign-images-to-production:
    docker:
      - image: wecs/circle-ci-gcloud-node:0.1.0
    working_directory: ~/signed-images
      - run:
          name: Build and Deploy Signed Images
          command: |
            chmod u+x ./deployment.sh
            if [ "${CIRCLE_BRANCH}" == "main" ]; then
              ./deploy.sh
            fi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Create Bash Script&lt;/em&gt;
Create a bash file called &lt;strong&gt;deploy.sh&lt;/strong&gt; still in the root of your project. This will help install cosign to sign the docker image.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# !/bin/sh
set -e
set -o pipefail

# login to docker hub
echo “$DOCKERHUB_PASSWORD” | docker login -u “$DOCKERHUB_USERNAME” — password-stdin
docker build -t dockerhuburl/imagename:$CIRCLE_SHA1 .

# download cosign
curl -LO https://github.com/sigstore/cosign/releases/latest/download/cosign-linux-amd64

# give cosign executable access
chmod +x cosign-linux-amd64

# move cosign to your CI machine bin folder
mv cosign-linux-amd64 /usr/local/bin/cosign

# check cosign version and that it installed successfully
cosign version

# generate key pair using set $COSIGN_PASSWORD
cosign generate-key-pair

# push to docker hub
docker -- push dockerhuburl/imagename:$CIRCLE_SHA1

# sign image
cosign sign --key cosign.key dockerhuburl/imagename:tag:$CIRCLE_SHA1 -y

# verify image
cosign verify --key cosign.pub dockerhuburl/imagename:tag:$CIRCLE_SHA1:$CIRCLE_SHA1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Explaining Environmental Variables Created&lt;/em&gt;&lt;br&gt;
First, we set need to set CircleCI environment variables. Read this article &lt;a href="https://circleci.com/docs/env-vars/"&gt;https://circleci.com/docs/env-vars/&lt;/a&gt; for more insight. Set &lt;strong&gt;$DOCKERHUB_PASSWORD&lt;/strong&gt; and &lt;strong&gt;$DOCKERHUB_USERNAME&lt;/strong&gt;  to your docker hub login details. You do not need to set &lt;strong&gt;$CIRCLE_SHA1&lt;/strong&gt; as it is a unique variable generated by CircleCI you can take advantage of in your pipeline. Then finally &lt;strong&gt;create an environment variable called $COSIGN_PASSWORD&lt;/strong&gt; and pass any value you want to it. For this tutorial, I use &lt;strong&gt;1234&lt;/strong&gt; as the password. This would be the password to help generate the cosign.key and cosign.pub files.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Final Review&lt;/em&gt;&lt;br&gt;
Very importantly, we need to note that we need the image to first exist in the docker repository so we can be able to sign it. Hence, why we push the image first before signing and verifying it, don't forget to have a Dockerfile in your environment. Create a pull request and merge it to your main branch on GitHub. Switch to your project dashboard on CircleCI to monitor your build. You should have your signed image pushed to docker hub. Hurray!!!&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The sequel article would touch on how to create a policy that allows only signed images to be deployed in your Kubernetes cluster. &lt;/p&gt;

</description>
    </item>
    <item>
      <title>TESTING DOCKER CONTAINER STRUCTURE</title>
      <dc:creator>Ahaiwe Emmanuel</dc:creator>
      <pubDate>Fri, 20 May 2022 17:08:45 +0000</pubDate>
      <link>https://dev.to/emmygozi/testing-docker-container-structure-na9</link>
      <guid>https://dev.to/emmygozi/testing-docker-container-structure-na9</guid>
      <description>&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%2Fozzgn5s7ksa14irgj8wo.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%2Fozzgn5s7ksa14irgj8wo.png" alt="Docker container structure"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  A Brief History of Docker Containers
&lt;/h3&gt;

&lt;p&gt;In the early days of software development, developers ran their applications on their local machines during testing and deployed them to a production virtual machine. &lt;/p&gt;

&lt;p&gt;The problem with this approach is that some dependencies which might work in the development environment might not work in production. Hence the famous line by engineers, "it is working on my local machine but not working in production!" Or worse, it could be working on the local machine of some engineers but not working for others. Docker addressed this problem.&lt;/p&gt;

&lt;p&gt;Docker containers provide applications with all it needs to run in a containerized environment. Therefore, eliminating the need for applications to depend on environment-specific system requirements. As long as it runs in a development environment, it would certainly work in a production environment.&lt;/p&gt;

&lt;p&gt;Containers in Docker are spun up from images. Images provide a convenient way to package applications with the preconfigured server environment. So, Docker images are the package and containers are the package in current use.&lt;/p&gt;

&lt;h3&gt;
  
  
  Testing Docker Container Structure
&lt;/h3&gt;

&lt;p&gt;What if there is a way to make sure that our Docker images have all the required files and directory to run correctly, execute commands correctly and generally reduce the rate of deploying a problematic image to production? &lt;/p&gt;

&lt;p&gt;There is a way! Google's container structure test is the answer. &lt;a href="https://github.com/GoogleContainerTools/container-structure-test" rel="noopener noreferrer"&gt;container-structure-test&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let's say you have folders called src and test at the root of your application and a Dockerfile for your Node js application with these commands:&lt;/p&gt;

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

FROM node:14-alpine

# Create app directory

WORKDIR /usr/node-app

ENV PORT=3000

COPY . .

RUN npm install


EXPOSE 3000

ENTRYPOINT ["npm", "run", "start" ]


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

&lt;/div&gt;

&lt;p&gt;Build the Docker image with this command:&lt;/p&gt;

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

docker build -t my-container-name .


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

&lt;/div&gt;

&lt;p&gt;Follow these commands to install Container Structure Tests on MacOs or Linux:&lt;/p&gt;

&lt;h4&gt;
  
  
  OS X
&lt;/h4&gt;

&lt;p&gt;Install via brew:&lt;/p&gt;

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

$ brew install container-structure-test

curl -LO https://storage.googleapis.com/container-structure-test/latest/container-structure-test-darwin-amd64 &amp;amp;&amp;amp; chmod +x container-structure-test-darwin-amd64 &amp;amp;&amp;amp; sudo mv container-structure-test-darwin-amd64 /usr/local/bin/container-structure-test


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

&lt;/div&gt;
&lt;h4&gt;
  
  
  Linux
&lt;/h4&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

curl -LO https://storage.googleapis.com/container-structure-test/latest/container-structure-test-linux-amd64 &amp;amp;&amp;amp; chmod +x container-structure-test-linux-amd64 &amp;amp;&amp;amp; sudo mv container-structure-test-linux-amd64 /usr/local/bin/container-structure-test


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

&lt;/div&gt;

&lt;p&gt;If you want to avoid using sudo:&lt;/p&gt;

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

curl -LO https://storage.googleapis.com/container-structure-test/latest/container-structure-test-linux-amd64 &amp;amp;&amp;amp; chmod +x container-structure-test-linux-amd64 &amp;amp;&amp;amp; mkdir -p $HOME/bin &amp;amp;&amp;amp; export PATH=$PATH:$HOME/bin &amp;amp;&amp;amp; mv container-structure-test-linux-amd64 $HOME/bin/container-structure-test


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

&lt;/div&gt;

&lt;p&gt;Create a file called config.yaml at the root of your project. Write the following in that file:&lt;/p&gt;

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

schemaVersion: 2.0.0
metadataTest:
  env:
    - key: PORT
      value: 3000
  exposedPorts: ["3000"]
  # volumes: ["/test"]
  entrypoint: ["npm", "run", "start" ]
  # cmd: ["/bin/bash"]
  workdir: "/usr/node-app"
  # user: "luke"

fileExistenceTests:
  - name: 'src directory exists'
    path: '/usr/node-app/src'
    shouldExist: true
  - name: 'data directory exists'
    path: '/usr/node-app/test'
    shouldExist: true


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

&lt;/div&gt;

&lt;p&gt;Save the file and run this command:&lt;/p&gt;

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

container-structure-test test --image my-container-name \
--config config.yaml


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

&lt;/div&gt;

&lt;p&gt;This should give a successful test output.&lt;/p&gt;

&lt;p&gt;Congratulations! You just tested your first docker container structure! You can research further ways to add it to a deployment pipeline or automate the process of testing. Thanks for your time.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>javascript</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>An easy Approach to Algorithms (Part 1)</title>
      <dc:creator>Ahaiwe Emmanuel</dc:creator>
      <pubDate>Tue, 07 Dec 2021 16:30:14 +0000</pubDate>
      <link>https://dev.to/emmygozi/an-easy-approach-to-algorithms-part-1-3c55</link>
      <guid>https://dev.to/emmygozi/an-easy-approach-to-algorithms-part-1-3c55</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe7d0zdqhprr0usapgqvo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe7d0zdqhprr0usapgqvo.png" alt="two pointer technique" width="701" height="148"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Two Pointer Technique
&lt;/h2&gt;

&lt;p&gt;Top companies typically would hire you for your demonstrated problem-solving abilities. A less experienced engineer is chosen over one who is more experienced. What skill makes one stand out? How well you can solve a problem and not how many problems you have solved. Algorithms are what big tech companies like Google use to test problem-solving proficiency. You can show your world-class abilities by learning about the &lt;strong&gt;Two Pointer Technique&lt;/strong&gt;, the first in a series of algorithm fundamentals. We discuss saving time and space using an optimized algorithm with the best performant big-O notation. &lt;br&gt;
Two pointer technique involves using two array indexes in a sorted array. The aim is to save time and space. Typically placed at the two ends of an array, it finds pairings in optimized time. A typical question would look like this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: In an unsorted array, find if a pair exists with a given sum targetSum.&lt;/strong&gt;&lt;br&gt;
A typical brute force approach would be to create a function and have a nested for loop where we compare pairs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pairExists(array, targetSum) { 
for(let i = 0; i &amp;lt; array.length -1; i++){
        let firstNumber = array[i];

        for(let j = i + 1; j &amp;lt; array.length; j++){
            let secondNumber = array[j];

            if(firstNumber + secondNumber === targetSum){
                return [firstNumber, secondNumber];
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above nested for loop approach would lead to an &lt;strong&gt;O(n^2)&lt;/strong&gt; time complexity because we iterate twice in our algorithm. And while this might work, it is not optimal when we increase the size of the array to a million.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Two Pointer Technique examples&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Two Number Sum:
&lt;/h2&gt;

&lt;p&gt;Write a function that takes an unsorted array of distinct integers and an integer representing a target sum. If any two numbers sum up to the target sum, they are returned in an array. If no two integers sum up to the target sum, an empty array is returned.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key points:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;unsorted array&lt;/li&gt;
&lt;li&gt;distinct integer&lt;/li&gt;
&lt;li&gt;target sum
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// o(nlog(n)) | o(1) space
function twoNumberSum(array, targetSum) {
    array.sort((a, b) =&amp;gt; a - b);
    let left = 0;
    let right = array.length - 1;

    while(array[left] &amp;lt; array[right]){
        const currentValue = array[left] + array[right];
        if (currentValue === targetSum ){
            return [array[left], array[right]]
        }
        else if (currentValue &amp;lt; targetSum){
            left++;
        }
        else if (currentValue &amp;gt; targetSum){
            right--;
        }
    }
    return [];
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First, we sort the array in &lt;strong&gt;O(N*log(N))&lt;/strong&gt;, which is far better than O(n^2) in the brute force approach. Refer to &lt;a href="https://stackoverflow.com/questions/23329234/which-is-better-on-log-n-or-on2"&gt;this&lt;/a&gt; article for more information.&lt;br&gt;
Then we set our pointer variables and call them &lt;strong&gt;left&lt;/strong&gt; and &lt;strong&gt;right&lt;/strong&gt;. We iterate from the beginning of the array at &lt;strong&gt;index 0&lt;/strong&gt; and the end of the array at &lt;strong&gt;array.length -1&lt;/strong&gt; and move the left pointer forward if we get a value lesser than the target sum and the right pointer if we get a value greater than the target sum.&lt;br&gt;
&lt;strong&gt;Two pointer algorithm typically uses just a loop to iterate and compare values&lt;/strong&gt;! Compared to the brute force approach of nested loops, this is quite optimal.&lt;br&gt;
The while loop iterates in an &lt;strong&gt;O(n)&lt;/strong&gt; time and &lt;strong&gt;O(1) space complexity&lt;/strong&gt; (it doesn't create another array to check values).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Complexity&lt;/strong&gt;&lt;br&gt;
Finally, we can say our two number sum algorithm runs in &lt;strong&gt;O(N*log(N)) time and O(1) space algorithm&lt;/strong&gt; because the array sort function is the highest time complexity our algorithm performs.&lt;/p&gt;
&lt;h2&gt;
  
  
  Three-Number Sum:
&lt;/h2&gt;

&lt;p&gt;Write a function that takes an unsorted array of distinct integers and an integer representing a target sum. The function should find three numbers in the array whose sum equals the target sum. It should return a two-dimensional array sorted in ascending order per array. It should return an empty array if no three numbers that equal the target sum is found.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key points:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;unsorted array&lt;/li&gt;
&lt;li&gt;distinct integer&lt;/li&gt;
&lt;li&gt;target sum&lt;/li&gt;
&lt;li&gt;return two-dimensional arrays sorted in ascending order&lt;/li&gt;
&lt;li&gt;return empty numbers do not sum up to the target sum
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// o(n^2) time | o(n) space
function threeNumberSum(array, targetSum) {
    array.sort((a,b) =&amp;gt; a - b);
    let tripleValueArray = [];
    for (let i = 0; i &amp;lt; array.length - 2; i++) {
        let leftNumber = i + 1;
        let rightNumber = array.length - 1;

        while (leftNumber &amp;lt; rightNumber) {
            let currentNumber = array[i] + array[leftNumber] +       array[rightNumber];

            if (currentNumber === targetSum) {
                tripleValueArray.push([ array[i], array[leftNumber], array[rightNumber] ]);
                leftNumber++;
                rightNumber--;
            } else if (currentNumber &amp;lt; targetSum) {
                leftNumber++;
            } else if (currentNumber &amp;gt; targetSum) {
                rightNumber--;
            }
        }
    }
    return tripleValueArray;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;First, we sort the array in &lt;strong&gt;O(N*log(N))&lt;/strong&gt;, which is far better than O(n^3) in a brute force approach of three for loops nested in themselves. &lt;br&gt;
Next, we use &lt;strong&gt;for (let i=0; i &amp;lt; array.length - 2; i++)&lt;/strong&gt; in our loop because we always want two extra values to check with and not iterate over. Remember pointer position for a three number sum would look like this:&lt;br&gt;
[&lt;strong&gt;-8, -6&lt;/strong&gt;, 1, 2, 3, 5, 6, &lt;strong&gt;12&lt;/strong&gt;]&lt;br&gt;
Where &lt;strong&gt;-8&lt;/strong&gt; would be the starting current number, &lt;strong&gt;-6&lt;/strong&gt; the starting left number and &lt;strong&gt;12&lt;/strong&gt; the starting right number. We move the &lt;strong&gt;left pointer&lt;/strong&gt; if the addition of all three values is less than the target sum and the &lt;strong&gt;right pointer&lt;/strong&gt; to the right if it is greater than the target sum.&lt;/p&gt;

&lt;p&gt;Remember, the array is sorted so moving from left to right or right to left increases or decreases sum value respectively. The sum of  &lt;strong&gt;-8+(-6)+12 = -2&lt;/strong&gt;. But if we move the left pointer from &lt;strong&gt;-6 to 1&lt;/strong&gt; and sum &lt;strong&gt;-8+1+12 = 5&lt;/strong&gt;. A bigger number! Similarly, moving the right pointer from &lt;strong&gt;-12&lt;/strong&gt; would result in &lt;strong&gt;-8+(-6)+6 = -8&lt;/strong&gt;. A much smaller number.&lt;/p&gt;

&lt;p&gt;The only condition when we move both pointers towards the middle is if the sum of all three values equals the target sum &lt;strong&gt;if (currentNumber === targetSum)&lt;/strong&gt;. We use the conditions:&lt;br&gt;
&lt;strong&gt;leftNumber++;&lt;/strong&gt; and &lt;strong&gt;rightNumber--;&lt;/strong&gt; to break out of the while loop. We then return whatever is pushed into &lt;strong&gt;tripleValueArray&lt;/strong&gt;. If nothing is pushed, we return it because it is declared as an empty array.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Complexity&lt;/strong&gt;&lt;br&gt;
The &lt;strong&gt;time complexity&lt;/strong&gt; for our three number sum is &lt;strong&gt;O(N^2)&lt;/strong&gt; because we have two loops, an outer for loop and inner while loop in the algorithm.&lt;br&gt;
The &lt;strong&gt;space complexity&lt;/strong&gt; is &lt;strong&gt;O(N)&lt;/strong&gt; because it is created in constant time. Although, we cannot tell the size of our &lt;strong&gt;tripleValueArray.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Four-Number Sum
&lt;/h2&gt;

&lt;p&gt;Write a function that takes an unsorted array of distinct integers and an integer representing a target sum. The function should find four numbers in the array whose sum equals the target sum. It should return a two-dimensional array in no particular order. It should return an empty array if no four numbers that equal the target sum is found.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// o(n^2) time | o(n^2) space
function fourNumberSum(array, targetSum) {
    const temporaryPairSum = {};
    const quadruplet = [];

    for (let i=1; i &amp;lt; array.length - 1; i++){
        for(let j = i+1; j &amp;lt; array.length; j++){
            let currentSum = array[i] + array[j];
            let difference = targetSum - currentSum;

            if ( difference in temporaryPairSum){
                for (const arrayPair of temporaryPairSum[difference]){
                    quadruplet.push(arrayPair.concat([array[i], array[j]]))
                }
            }
        }
        for (let k=0; k &amp;lt; i; k++){
            let currentSum = array[k] + array[i];
            if(!(currentSum in temporaryPairSum)){
                temporaryPairSum[currentSum] = [[array[k], array[i]]];
            } else {
                temporaryPairSum[currentSum].push([array[k], array[i]]);
            }
        }
    }
    return quadruplet;

}

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

&lt;/div&gt;



&lt;p&gt;We use a hash table to store pair values. For this algorithm, we start our outer for loop from &lt;strong&gt;index 1&lt;/strong&gt; and iterate to &lt;strong&gt;array.length - 1&lt;/strong&gt; index. The inner for loop of the equation also start from &lt;strong&gt;index 1 + 1 position&lt;/strong&gt;. But why do we do this? &lt;/p&gt;

&lt;p&gt;We want to prevent duplication of values so we skip saving anything in our hash table &lt;strong&gt;temporaryPairSum&lt;/strong&gt; during the first iteration. We only save values when we iterate the second time from &lt;strong&gt;index 0&lt;/strong&gt; while comparing the values with whatever is currently in the &lt;strong&gt;array index "i"&lt;/strong&gt; as shown in this part of the equation &lt;br&gt;
&lt;strong&gt;for (let k=0; k &amp;lt; i; k++).&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Remember we skipped the first value in our outer for loop by starting at &lt;strong&gt;array index 1&lt;/strong&gt; here &lt;strong&gt;for (let i=1; i &amp;lt; array.length - 1; i++)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Next, we solve for the additional two arrays in the multidimensional array and subtract them from the target sum. We then &lt;strong&gt;check if the difference already exists&lt;/strong&gt; in the hash table&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const difference = targetSum - currentSum;
 if ( difference in temporaryPairSum)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If it does, then congratulation! We push the two array values, add them to our quadruplet multidimensional array.&lt;/p&gt;

&lt;p&gt;The second part of the inner for loop is where the "difference" referred to is added. &lt;strong&gt;Pay close attention here&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;We iterate starting from &lt;strong&gt;index 0&lt;/strong&gt; to where the iteration of the outer for loop is currently &lt;strong&gt;for (let k =0; k &amp;lt; i; k++)&lt;/strong&gt;. Then we check if we have initialized the sum of two array pairs (referred to as difference in the outer for loop. If it is not initialized, we do so here:&lt;br&gt;
&lt;strong&gt;allPairSum[currentSum] = [[array[k], array[i]]];&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Please &lt;strong&gt;note&lt;/strong&gt; that our hash table uses the &lt;strong&gt;sum of two array pairs as key&lt;/strong&gt; and a multidimensional array as value. This helps to track duplicates that can be found in the iteration. For example, our hash table with duplicates would look like this assuming 17 is the target sum difference:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
17: "[ [array[k], array[i]], [array[k], array[i]]  ]"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where duplicates would be a different arrangement of the same values.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; 7 + 10 = 17 and 10 + 7 = 17:
{
17: "[ [10, 7], [7, 10]  ]"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We push the duplicate to the hash table using this line&lt;br&gt;
&lt;strong&gt;allPairSum[currentSum].push([array[k], array[i]]);&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The quadruplet multidimensional array is returned at the end of the algorithm. It can also be an empty array if no quadruplet is found.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Complexity&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;The average time complexity&lt;/strong&gt; analysis for this is &lt;strong&gt;O(2N^2)&lt;/strong&gt; which then &lt;strong&gt;evaluates to O(N^2)&lt;/strong&gt;. This is because, in big-O scaling, the constant of &lt;strong&gt;N&lt;/strong&gt; which in this is 2 is irrelevant. The major complexity comes from the unknown size of N. &lt;strong&gt;The worst-case scenario&lt;/strong&gt; for the algorithm is &lt;strong&gt;O(N^3)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You might also be wondering why we have just &lt;strong&gt;O(N^2)&lt;/strong&gt; complexity after having about 4 for loops? This is because 2 of the inner for loops, starts just before or after the starting index of the outer for loop. If you look closely, the first inner for loop starts an index next to the outer for loop &lt;strong&gt;for(let j = i+1; j &amp;lt; array.length; j++)&lt;/strong&gt; and  the last for loop of the equation &lt;strong&gt;for (let k=0; k &amp;lt; i; k++)&lt;/strong&gt; starts just before the outer for loop. These types of for loops evaluates to &lt;strong&gt;O(2N)&lt;/strong&gt;. We get &lt;strong&gt;O(2N^2) = O(N^2)&lt;/strong&gt; by adding the time complexity of the outer for loop. For the worst-case scenario &lt;strong&gt;O(N^3)&lt;/strong&gt;, it is the time complexity used to iterate through pair duplicates in the hash table &lt;strong&gt;for (const arrayPair of temporaryPairSum[difference])&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The space complexity is O(n^2)&lt;/strong&gt; as you never really know the space the hash table or the quadruplet multidimensional array might take.&lt;/p&gt;

&lt;p&gt;To read up on Big-O notation check out this &lt;a href="https://dev.to/emmygozi/big-o-notation-for-coding-interviews-explained-fast-1po2"&gt;article&lt;/a&gt;. For further reading, please visit this &lt;a href="https://www.algoexpert.io/"&gt;link&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>programming</category>
      <category>javascript</category>
      <category>datastructure</category>
    </item>
    <item>
      <title>Big-O Notation for Coding Interviews Explained Fast</title>
      <dc:creator>Ahaiwe Emmanuel</dc:creator>
      <pubDate>Tue, 23 Nov 2021 16:00:49 +0000</pubDate>
      <link>https://dev.to/emmygozi/big-o-notation-for-coding-interviews-explained-fast-1po2</link>
      <guid>https://dev.to/emmygozi/big-o-notation-for-coding-interviews-explained-fast-1po2</guid>
      <description>&lt;p&gt;This definition from Wikipedia elegantly explains &lt;strong&gt;big-O&lt;/strong&gt; in computer science as a classification of algorithms according to how their run time or space requirements grow as the input size grows.&lt;/p&gt;

&lt;p&gt;It is an asymptotic analysis which implies that it is input bound. It calculates the worst-case scenario of an algorithm based on input, bounded by time and space. &lt;/p&gt;

&lt;p&gt;The calculation for time and space is similar. In this explanation, we calculate the big O notation for time.&lt;/p&gt;

&lt;p&gt;We would explain how to identify &lt;strong&gt;O(1)&lt;/strong&gt;, &lt;strong&gt;O(log(N))&lt;/strong&gt;, &lt;strong&gt;O(N)&lt;/strong&gt;, &lt;strong&gt;O(N^2)&lt;/strong&gt;. It is worthy to note that the algorithms are arranged in terms of their time performance in the previous sentence.&lt;/p&gt;

&lt;p&gt;For example, we calculate the time complexity of 3 algorithms with a given array input below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a = [...] where array size n

We have three algorithms that take 
array 'a' as input and returns values.

F1(a) =&amp;gt; 1 + a[0]; 
algorithm F1 returns 1 plus the first
array value of 'a'

F2(a) =&amp;gt; sum(a); 
algorithm F2 returns the sum of 
array value 'a'

F3(a) =&amp;gt; pair(a); 
algorithm F3 returns the pairing of the 
array values in 'a'.
for example if a = [1,2,3], F3 returns 
1,2  
1,3  
2,1  
2,3...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the size of the array &lt;strong&gt;'n'&lt;/strong&gt; increases &lt;br&gt;
to  10,000,000, we find out that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;F1 algorithm still runs in constant &lt;br&gt;
time as it refers to a pointer to a &lt;br&gt;
memory location like &lt;em&gt;array[0]&lt;/em&gt; is &lt;br&gt;
&lt;strong&gt;O(1)&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;F2 algorithm runs in linear time as &lt;br&gt;
the time taken increases proportionally &lt;br&gt;
to the size of 'n' array. The expression&lt;br&gt;
&lt;em&gt;sum(array)&lt;/em&gt; where array size is an input&lt;br&gt;
that can vary is &lt;strong&gt;O(N)&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;F3 algorithm would most likely have a &lt;br&gt;
nested for loop that would mean it runs &lt;br&gt;
in &lt;strong&gt;O(N^2)&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Logarithms in Big O
&lt;/h2&gt;

&lt;p&gt;The expression &lt;em&gt;log (n) = y&lt;/em&gt; in computer science assumes log is in base 2 and not base 10 like mathematics. This is a very important distinction to make. Therefore the full expression is &lt;em&gt;log2 (n) = y&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;To get 'n' we simply do &lt;strong&gt;2^y = n&lt;/strong&gt;. That means to get 'n' in &lt;strong&gt;log (n)=4&lt;/strong&gt;, we simply do &lt;strong&gt;2^4 = 16&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to Identify O(log(N)) algorithms&lt;/strong&gt;&lt;br&gt;
Remember that in computer science the expression &lt;em&gt;log (n) = y&lt;/em&gt; evaluates to &lt;em&gt;log2 (n) = y&lt;/em&gt;, log is in base 2. Thus an expression  &lt;strong&gt;log (n)=4&lt;/strong&gt; which can be solved as &lt;strong&gt;2^4 = 16&lt;/strong&gt; simply multiplies 2 four times &lt;code&gt;2*2*2*2&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;If we added 1 to 2^4+1 we would get 16*2 which is
2^5=32
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;It means that when the input doubles, you only have to do one more operation. The magic happens here!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To understand if a notation is &lt;strong&gt;O(log(N))&lt;/strong&gt;, if we have an algorithm that keeps cutting an array in half like a binary search as shown below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[0,1,2,3,4,5,6,7,8,9]
[0,1,2,3,4, | 5,6,7,8,9] =&amp;gt; [0,1,2,3,4]
[0,1,2 | ,3,4] =&amp;gt; [0,1,2]
[0,1 | ,2] =&amp;gt; [0,1]
[0 | 1] =&amp;gt; [0]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or if it cuts a tree data structure in half. Read about tree data structure &lt;a href="https://www.geeksforgeeks.org/binary-tree-data-structure/."&gt;here&lt;/a&gt;, it is most likely a &lt;strong&gt;O(log(N))&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For further studies, visit &lt;a href="https://www.algoexpert.io"&gt;https://www.algoexpert.io&lt;/a&gt; &lt;/p&gt;

</description>
      <category>bigonotation</category>
      <category>bigo</category>
      <category>codinginterview</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Data Structure and Endianness in Nodejs</title>
      <dc:creator>Ahaiwe Emmanuel</dc:creator>
      <pubDate>Tue, 23 Nov 2021 09:44:19 +0000</pubDate>
      <link>https://dev.to/emmygozi/data-structure-and-endianess-in-nodejs-1jgp</link>
      <guid>https://dev.to/emmygozi/data-structure-and-endianess-in-nodejs-1jgp</guid>
      <description>&lt;p&gt;&lt;strong&gt;Data structure&lt;/strong&gt; is the collection of data values, the relationship among them and the functions or operations that can be applied to the data according to Wikipedia.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Memory in Data structure&lt;/strong&gt;&lt;br&gt;
The concept of memory is that there are finite memory slots. So it can be exhausted.&lt;br&gt;
The program is always stored in a free memory slot. Memory is stored as bit and byte. 8 bits make a byte.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1 represented as a byte is 0000 0001         
2 represented as a byte is 0000 0010
3 represented as a byte is 0000 0011
4 represented as a byte is 0000 0100
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are represented in base 2. And that gives us a finite amount of numbers we can store because base &lt;code&gt;2^8 = 256&lt;/code&gt;. So to save bigger numbers, we increase the bytes. &lt;/p&gt;

&lt;p&gt;In java for example, "int" is the equivalent of 4 bytes, 32 bits integer. Type "long" represents 8 bytes, a 64 bits integer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Endianness in Data Structure&lt;/strong&gt;&lt;br&gt;
The concept of Endianness in computer memory storage refers to how bytes are read. It could either be the smallest byte value first called Little-endian (read from left to right) or biggest byte value first called big-endian (read from left to right). &lt;br&gt;
For example,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;65,000 decimal number in base 2 is: 0b11111101 11101000.
0b here helps us know it is in base 2 and not 1,111,110,111,101,000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The answer above is in big-endian byte because the byte with the biggest 0b11111101 is written first reading from left to right. We can confirm this by converting the big-endian padded by another byte of zeros "0b1111110100000000 to base 10" on google. The result is 64,768 which is very close to our initial number of 65,000.&lt;/p&gt;

&lt;p&gt;For networks, the standard is Big-endian and for most PCs, the standard is Little-endian. Check this &lt;a href="https://replit.com/@emmygozi/Test-Endianness"&gt;code&lt;/a&gt; snippet online to find out what endian your machine runs. My machine runs on Little-endian.&lt;/p&gt;

&lt;p&gt;Endianness has largely ceased to be a matter of concern because of modern computer languages removing this needless complexity and processors which are Bi-endian and can handle both.&lt;/p&gt;

&lt;p&gt;For further studies, please visit &lt;a href="https://www.algoexpert.io"&gt;https://www.algoexpert.io&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>endianness</category>
      <category>memory</category>
      <category>node</category>
    </item>
    <item>
      <title>Serving Multiple Applications with Nginx</title>
      <dc:creator>Ahaiwe Emmanuel</dc:creator>
      <pubDate>Fri, 01 May 2020 22:28:36 +0000</pubDate>
      <link>https://dev.to/emmygozi/serving-multiple-applications-with-nginx-42l</link>
      <guid>https://dev.to/emmygozi/serving-multiple-applications-with-nginx-42l</guid>
      <description>&lt;p&gt;Imagine this scenario, you just got your dream DevOps job. You are very excited. In no time, you get your first task to host a javascript, python and PHP application on a single Linux centos server. At first, you are confused about how you'll serve multiple applications from a single server. You do a little digging and then you strike gold. Nginx!&lt;/p&gt;

&lt;p&gt;"&lt;strong&gt;NGINX&lt;/strong&gt; is open-source software for web serving, reverse proxying, caching, load balancing, media streaming, and more. It started out as a web server designed for maximum performance and stability. In addition to its HTTP server capabilities, NGINX can also function as a proxy server for email (IMAP, POP3, and SMTP) and a reverse proxy and load balancer for HTTP, TCP, and UDP servers."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisite:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Linux centos server&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  STEP 1
&lt;/h2&gt;

&lt;p&gt;Log in to your server using ssh&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh root@server_ip_address
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll be asked to input your &lt;strong&gt;password&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Installing Nginx on Centos&lt;/strong&gt;&lt;br&gt;
Nginx packages can be gotten from EPEL repositories:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo yum install epel-release
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install Nginx:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo yum install nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output should look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Retrieving key from file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
Importing GPG key 0x352C64E5:
Userid     : "Fedora EPEL (7) &amp;lt;epel@fedoraproject.org&amp;gt;"
Fingerprint: 91e9 7d7c 4a5e 96f1 7f3e 888f 6a2f aea2 352c 64e5
Package    : epel-release-7-9.noarch (@extras)
From       : /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
Is this ok [y/N]:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Press &lt;strong&gt;y&lt;/strong&gt; and &lt;strong&gt;enter&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Upon completion, start Nginx and check it's status using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl enable nginx
sudo systemctl start nginx
sudo systemctl status nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If all goes well, you should see this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;● nginx.service - The nginx HTTP and reverse proxy server
  Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
  Active: active (running) since Mon 2018-03-12 16:12:48 UTC; 2s ago
  Process: 1677 ExecStart=/usr/sbin/nginx (code=exited, status=0/SUCCESS)
  Process: 1675 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=0/SUCCESS)
  Process: 1673 ExecStartPre=/usr/bin/rm -f /run/nginx.pid (code=exited, status=0/SUCCESS)
Main PID: 1680 (nginx)
  CGroup: /system.slice/nginx.service
          ├─1680 nginx: master process /usr/sbin/nginx
          └─1681 nginx: worker process
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open HTTP(&lt;strong&gt;80&lt;/strong&gt;) and HTTPS(&lt;strong&gt;433&lt;/strong&gt;) if you are behind a firewall with these commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo firewall-cmd --permanent --zone=public --add-service=http
sudo firewall-cmd --permanent --zone=public --add-service=https
sudo firewall-cmd --reload
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open &lt;a href="http://YOUR_IP"&gt;http://YOUR_IP&lt;/a&gt; in your browser of choice, you should see an Nginx homepage displayed. Congratulation!!!&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Create a New User Account with &lt;em&gt;sudo&lt;/em&gt; Privileges&lt;/strong&gt;&lt;br&gt;
For security reasons, it is advisable not to use the root user to run commands but to create a new user with &lt;strong&gt;sudo&lt;/strong&gt; privileges:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;useradd username
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Replace &lt;strong&gt;username&lt;/strong&gt; with your username with Sudo privileges.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Set the User Password&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;passwd username
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should get the output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;output
Changing password for user username.
New password:
Retype new password:
passwd: all authentication tokens updated successfully.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Add User to the &lt;em&gt;sudo&lt;/em&gt; Group&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;usermod -aG wheel username
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Switch to Newly Created User&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;su - username
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then list &lt;strong&gt;\root&lt;/strong&gt; directory content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo ls -l /root
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll see a banner message the first time you &lt;strong&gt;sudo&lt;/strong&gt; from this account:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;output
We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:

    #1) Respect the privacy of others.
    #2) Think before you type.
    #3) With great power comes great responsibility.

[sudo] password for username:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Serve Multiple Applications
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Log in to the Server Using Your &lt;em&gt;username&lt;/em&gt; with Root Privileges&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Our directory structure would look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/var/www/
├── javascriptapp.com
│   └── public_html
├── pythonapp.com
│__ └── public_html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's create a directory where your javascript and python application would reside:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo mkdir -p /var/www/javascriptapp.com/public_html
sudo mkdir -p /var/www/pythonapp.com/public_html

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

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Important!&lt;/code&gt;&lt;br&gt;
To avoid any permission issues, let us change ownership to our &lt;strong&gt;username&lt;/strong&gt; with sudo privileges:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo chown -R username: /var/www/javascriptapp.com
sudo chown -R username: /var/www/pythonapp.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;sudo vi /var/www/javascriptapp.com/public_html/index.html&lt;/p&gt;

&lt;p&gt;Copy and paste the following lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;\&amp;lt;!DOCTYPE html&amp;gt;
\&amp;lt;html lang="en" dir="ltr"&amp;gt;
  \&amp;lt;head&amp;gt;
    \&amp;lt;meta charset="utf-8"&amp;gt;
    \&amp;lt;title&amp;gt;Welcome to javascriptapp.com&amp;lt;/title&amp;gt;
  \&amp;lt;/head&amp;gt;
  \&amp;lt;body&amp;gt;
    \&amp;lt;h1&amp;gt;Success! javascriptapp.com home page!&amp;lt;/h1&amp;gt;
  \&amp;lt;/body&amp;gt;
\&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Create a Server Block&lt;/strong&gt;&lt;br&gt;
Server blocks are stored in the &lt;strong&gt;/etc/nginx/conf.d&lt;/strong&gt; directory and must end with &lt;strong&gt;.conf&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo vi /etc/nginx/conf.d/javascriptapp.com.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy and paste the following lines into the file, remember to replace the server name with your value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;server {
    listen 80;
    listen [::]:80;
    root /var/www/javascriptapp.com/public_html;
    index index.html;
    server_name example.com www.javascriptapp.com;
    access_log /var/log/nginx/javascriptapp.com.access.log;
    error_log /var/log/nginx/javascriptapp.com.error.log;
    location / {
        try_files $uri $uri/ =404;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save the file and check that configuration is right:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo nginx -t
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart Nginx:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl restart nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then visit your server name:&lt;br&gt;
&lt;a href="http://javascriptapp.com"&gt;http://javascriptapp.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;NB: This must be a configured DNS to your server else just use the server IP address.&lt;/p&gt;
&lt;h2&gt;
  
  
  Final Step
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Configure Nginx for Node JS Application&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Upload node project to &lt;strong&gt;/var/www/javascriptapp.com/public_html&lt;/strong&gt;, build the application and start node application on a designated port.&lt;/p&gt;

&lt;p&gt;Edit the application &lt;em&gt;.conf&lt;/em&gt; file to look like this:&lt;br&gt;
&lt;code&gt;sudo vi /etc/nginx/conf.d/javascriptapp.com.conf&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;server {
    listen 80;
    listen [::]:80;
    root /var/www/javascriptapp.com/public_html;
    server_name example.com www.javascriptapp.com;
    access_log /var/log/nginx/javascriptapp.com.access.log;
    error_log /var/log/nginx/javascriptapp.com.error.log;
    location / {
        proxy_pass http://internal_server_ip:node_app_PORT;
        try_files $uri $uri/ =404;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;NB: You can get the &lt;strong&gt;internal_server_ip&lt;/strong&gt; by running &lt;code&gt;hostname -I&lt;/code&gt; on the terminal. See &lt;a href="https://www.linuxtrainingacademy.com/determine-public-ip-address-command-line-curl/"&gt;https://www.linuxtrainingacademy.com/determine-public-ip-address-command-line-curl/&lt;/a&gt; for more.&lt;/p&gt;

&lt;p&gt;Restart Nginx:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl restart nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And visit your server name or IP to verify that your application is served.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Congratulation!&lt;/strong&gt; Your javascript app is successfully served!&lt;br&gt;
You can follow a similar process to serve your python application in the created directory.&lt;/p&gt;

&lt;p&gt;This post is inspired by &lt;a href="https://www.linuxtrainingacademy.com/determine-public-ip-address-command-line-curl/"&gt;https://www.linuxtrainingacademy.com/determine-public-ip-address-command-line-curl/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>linux</category>
      <category>centos</category>
      <category>server</category>
      <category>nginx</category>
    </item>
    <item>
      <title>Redis for Caching in Node js</title>
      <dc:creator>Ahaiwe Emmanuel</dc:creator>
      <pubDate>Mon, 06 Jan 2020 01:01:06 +0000</pubDate>
      <link>https://dev.to/emmygozi/redis-for-caching-in-node-js-4en7</link>
      <guid>https://dev.to/emmygozi/redis-for-caching-in-node-js-4en7</guid>
      <description>&lt;p&gt;Why use Redis?&lt;br&gt;
Making database request and persisting data in an application can become costly as an application grows in the number of features and users it has. Think of the load time it takes for your browser to open a new page. We can observe that it can take a while to load, especially if internet connectivity is poor. Imagine your application making these request to services like a database under the hood. One can end up with an application with bad user experience because it might take a long time to load and navigate pages. Redis is the answer to this concern.&lt;/p&gt;

&lt;p&gt;Redis&lt;br&gt;
Is an in-memory data structure store, used as a database, cache or message broker. It is open-source so you can make contributions! Yaay :)&lt;/p&gt;

&lt;p&gt;Downloading and Installing Redis MacOS&lt;br&gt;
Using Homebrew run:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;brew install redis&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Launch Redis on Computer Start&lt;br&gt;
ln -sfv /usr/local/opt/redis/*.plist ~/Library/LaunchAgents&lt;/p&gt;

&lt;p&gt;Test if Redis is Running&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;redis-cli ping&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;If it replies "pong" then bravo! we are good to go.&lt;/p&gt;

&lt;p&gt;Downloading and Installing Redis on Windows&lt;br&gt;
Visit &lt;a href="https://github.com/ServiceStack/redis-windows/tree/master/downloads"&gt;https://github.com/ServiceStack/redis-windows/tree/master/downloads&lt;/a&gt;&lt;br&gt;
and download the latest zip file. Run the executable script called Redis server.&lt;/p&gt;

&lt;p&gt;Add “C:\Program Files\Redis\” to the end of the variable value and click “OK.” if it doesn't already exist.&lt;/p&gt;

&lt;p&gt;Test if Redis is Running&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;redis-cli ping&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;If it replies "pong" then bravo! we are good to go.&lt;/p&gt;

&lt;p&gt;Caching Database Requests with Redis&lt;br&gt;
Assumption - you have node installed on your device.&lt;/p&gt;

&lt;p&gt;Create a folder and call it redis-tut or whatever you like :)&lt;/p&gt;

&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install express node-fetch redis&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;to install the needed packages for this tutorial.&lt;/p&gt;

&lt;p&gt;Create a file called redis.js in that folder. &lt;/p&gt;

&lt;p&gt;Import the packages and instantiate them like this:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const express = require('express');&lt;br&gt;
const fetch = require('node-fetch');&lt;br&gt;
const redis = require('redis');&lt;br&gt;
const PORT = process.env.PORT || 5000;&lt;br&gt;
const REDIS_PORT = process.env.PORT || 6379;&lt;br&gt;
const client = redis.createClient(REDIS_PORT);&lt;br&gt;
const app = express();&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Set response to request&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;function setResponse(username, repos) {&lt;br&gt;
  return `&amp;lt;h2&amp;gt;${username} has ${repos} Github repos&amp;lt;/h2&amp;gt;`;&lt;br&gt;
}&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Make a get request to get all public repositories of a given github username:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;async function getAllPublicRepos(req, res, next) {&lt;br&gt;
  try {&lt;br&gt;
    console.log('Fetching Public Data of Supplied Username...');&lt;br&gt;
    const { username } = req.params;&lt;br&gt;
    const response = await &lt;br&gt;
    fetch(`https://api.github.com/users/${username}`);&lt;br&gt;
    const data = await response.json();&lt;br&gt;
    const repos = data.public_repos;&lt;br&gt;
    // Set data to Redis called username&lt;br&gt;
    client.setex(username, 3600, repos);&lt;br&gt;
    res.send(setResponse(username, repos));&lt;br&gt;
  } catch (err) {&lt;br&gt;
    console.error(err);&lt;br&gt;
    res.status(500);&lt;br&gt;
  }&lt;br&gt;
}&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Create a middleware for data caching&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;function cache(req, res, next) {&lt;br&gt;
  const { username } = req.params;&lt;br&gt;
  client.get(username, (err, data) =&amp;gt; {&lt;br&gt;
    if (err) throw err;&lt;br&gt;
    if (data !== null) {&lt;br&gt;
      res.send(setResponse(username, data));&lt;br&gt;
    } else {&lt;br&gt;
      next();&lt;br&gt;
    }&lt;br&gt;
  });&lt;br&gt;
}&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Initialize API routes for use in the application&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;app.get('/repos/:username', cache, getRepos);&lt;br&gt;
   app.listen(5000, () =&amp;gt; {&lt;br&gt;
   console.log(`App listening on port ${PORT}`);&lt;br&gt;
   });&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Visit&lt;/p&gt;

&lt;p&gt;&lt;a href="http://localhost:5000/repos/%7Bany-github-repo-username%7D"&gt;http://localhost:5000/repos/{any-github-repo-username}&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;to test the application. You should see a summary of the number of public repositories a given user has.&lt;/p&gt;

&lt;p&gt;Inspect the page and switch to the network tab. Refresh the page. You would notice that the page loads immediately because the data values have been cached. Hurray!!!&lt;/p&gt;

&lt;p&gt;If you followed through to this point, congratulations! You have successfully set up Redis for caching in Nodejs.&lt;/p&gt;

&lt;p&gt;Please share your comment and ways this tutorial could be improved. Thank you for your time :)&lt;/p&gt;

&lt;p&gt;Credit: A lot of this tutorial was influenced by Brad Traversy&lt;/p&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>redis</category>
    </item>
  </channel>
</rss>
