<?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: Keme Kenneth</title>
    <description>The latest articles on DEV Community by Keme Kenneth (@zeelz).</description>
    <link>https://dev.to/zeelz</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%2F231463%2F90eee3ad-5b26-42d2-a75c-c92d1da25755.JPG</url>
      <title>DEV Community: Keme Kenneth</title>
      <link>https://dev.to/zeelz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/zeelz"/>
    <language>en</language>
    <item>
      <title>🚀 Deploy to AWS Lambda in Minutes with GitHub Actions</title>
      <dc:creator>Keme Kenneth</dc:creator>
      <pubDate>Thu, 28 Aug 2025 15:41:09 +0000</pubDate>
      <link>https://dev.to/aws-builders/deploy-to-aws-lambda-in-minutes-with-github-actions-45fl</link>
      <guid>https://dev.to/aws-builders/deploy-to-aws-lambda-in-minutes-with-github-actions-45fl</guid>
      <description>&lt;p&gt;Ever deployed your app to AWS Lambda or thought about doing it? Now it’s easier than ever with the new AWS Lambda Deploy GitHub Action.&lt;/p&gt;

&lt;p&gt;In the past, deploying to Lambda meant writing long AWS CLI commands in your workflow or wrestling with complex CloudFormation templates. But now, with just a few lines of YAML, you can ship your code directly to AWS Lambda.&lt;/p&gt;

&lt;p&gt;The AWS Lambda Deploy GitHub Action is an official tool from the AWS team, available right in the GitHub Marketplace. Since GitHub Actions is already one of the most user-friendly CI/CD tools, this new integration makes deploying to Lambda seamless.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How It Works&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To get started, all you need is:&lt;/p&gt;

&lt;p&gt;AWS credentials configured using the configure-aws-credentials action.&lt;/p&gt;

&lt;p&gt;The aws-lambda-deploy action with just a handful of required inputs.&lt;/p&gt;

&lt;p&gt;You can deploy any runtime supported by Lambda - &lt;code&gt;Node.js&lt;/code&gt;, &lt;code&gt;Python&lt;/code&gt;, &lt;code&gt;Java&lt;/code&gt;, &lt;code&gt;.NET&lt;/code&gt;, or &lt;code&gt;Ruby&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example Workflow&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here’s a simple workflow that deploys a Python app to Lambda whenever you push code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: Deploy to AWS Lambda
on: push

permissions:
  contents: read

jobs:
  lambda:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: us-east-1                

      - name: Deploy Lambda Function
        uses: aws-actions/aws-lambda-deploy@v1.1.0
        with:
          function-name: my-moon-app
          code-artifacts-dir: .
          handler: app.handler
          runtime: python3.10
          role: arn:aws:iam::123456789012:role/my-lambda-role

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

&lt;/div&gt;



&lt;p&gt;This workflow runs automatically whenever you push code or commit to your repository.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Parameters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;function-name&lt;/code&gt; – The name of your Lambda function&lt;/p&gt;

&lt;p&gt;&lt;code&gt;code-artifacts-dir&lt;/code&gt; – Directory of your app’s code (use . if it’s in the root)&lt;/p&gt;

&lt;p&gt;&lt;code&gt;handler&lt;/code&gt; – The entry point (&lt;code&gt;fileName.functionName&lt;/code&gt;, e.g., &lt;code&gt;app.handler&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;&lt;code&gt;runtime&lt;/code&gt; – The runtime your app uses (e.g., &lt;code&gt;python3.10&lt;/code&gt;, &lt;code&gt;nodejs18.x&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;role – IAM role ARN for Lambda execution&lt;/p&gt;

&lt;p&gt;The action also supports advanced options like &lt;code&gt;package-type&lt;/code&gt;, &lt;code&gt;image-uri&lt;/code&gt;, &lt;code&gt;memory-size&lt;/code&gt;, &lt;code&gt;timeout&lt;/code&gt;, &lt;code&gt;environment&lt;/code&gt;, and &lt;code&gt;architectures&lt;/code&gt;.&lt;br&gt;
See the full parameter list 👉 &lt;a href="https://github.com/marketplace/actions/aws-lambda-deploy-action" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;br&gt;
.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security Best Practice&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;⚠️ Never hardcode your AWS credentials in your workflow.&lt;br&gt;
Instead, store them as GitHub secrets and reference them 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;aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Closing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;With the AWS Lambda Deploy GitHub Action, deploying serverless apps is now as easy as pushing code. It’s fast, simple, and officially supported by AWS—making it a perfect fit for modern CI/CD pipelines.&lt;/p&gt;

</description>
      <category>awslambda</category>
      <category>githubactions</category>
      <category>serverless</category>
      <category>devops</category>
    </item>
    <item>
      <title>How I made any browser tab my Notepad</title>
      <dc:creator>Keme Kenneth</dc:creator>
      <pubDate>Tue, 21 Nov 2023 12:42:08 +0000</pubDate>
      <link>https://dev.to/zeelz/how-i-made-any-browser-tab-my-notepad-240g</link>
      <guid>https://dev.to/zeelz/how-i-made-any-browser-tab-my-notepad-240g</guid>
      <description>&lt;p&gt;I like speed, and sometimes opening a notetaking app while you're on a page is just too slow for the thoughts going through our fast thinking minds. In that case, a quick browser tab is all you need to start jotting.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;contenteditable&lt;/code&gt; might as well as be the most powerful HTML attribute in this regard.&lt;/p&gt;

&lt;p&gt;All I did was to bookmark a tiny HTML script. I then made sure the bookmark icon (yes, I added an icon 😎) is visible when I hit new tab, and I have a ready cursor take my notes.&lt;/p&gt;

&lt;p&gt;I applied basic styling, and also prevented accidental tab/browser closure.&lt;/p&gt;

&lt;p&gt;_Here's the script. Customize it to your liking ✌️ _&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;data: text/html, &amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;style&amp;gt;body::before{content: "Make great notes today!";color:cornflowerblue; font-size:3rem; margin: 2rem 0px 3rem;position:absolute;top: 0;}&amp;lt;/style&amp;gt;&amp;lt;script&amp;gt;window.onbeforeunload%20=%20e%20=&amp;gt;%20%20(e.returnValue%20=%20"Please,%20stay")&amp;lt;/script&amp;gt;&amp;lt;link%20rel="icon"%20type="image/png"%20href="https://img.icons8.com/color/72/typewriter-with-tablet.png"%20sizes="32x32"&amp;gt;&amp;lt;title&amp;gt;Notr%20by%20Zeelz&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body%20contenteditable%20style="font-family:%20'Monaco',%20sans-serif;font-size:1.1rem;line-height:1.4;max-width:60rem;margin:0%20auto;position: relative;padding:4rem;padding-top: 7rem;background-color:rgb(53,%2054,%2058);color:darkgray"&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  ProductivityTips #Notetaking #HTML
&lt;/h1&gt;

</description>
    </item>
    <item>
      <title>Slot ads in between your articles in Laravel</title>
      <dc:creator>Keme Kenneth</dc:creator>
      <pubDate>Sun, 22 Oct 2023 14:34:37 +0000</pubDate>
      <link>https://dev.to/zeelz/slot-ads-in-between-your-articles-in-laravel-32lm</link>
      <guid>https://dev.to/zeelz/slot-ads-in-between-your-articles-in-laravel-32lm</guid>
      <description>&lt;p&gt;The boss said to me "Mr developer, I want Google ads to show in between my articles. One above and another below an article is just not good enough". In my mind, I held my head with my both hands and thought to myself how the heck am I suppose to do that? An article is one very long string of text saved in a relational database. Anyway, I said I'll figure out a way to do it and continued with other tasks.&lt;/p&gt;

&lt;p&gt;While I was on other things, like every programmer knows, my subconscious was at work trying to figure out a way to achieve that task. Then boom! it dawned on me that I could just break the long string into an array and loop over it slotting the ads in using some kind of condition. Now the question is how do I break an article into an array (pieces). I went looking around the database to see how exactly the articles are stored.&lt;/p&gt;

&lt;p&gt;Turns out each paragraph of an article is stored as an HTML &lt;/p&gt;
&lt;p&gt;. I thought to myself perfect, I'll just use "&lt;/p&gt;" as the delimiter to split the long string to paragraph bits. Since it was Laravel, PHP has this convenient "explode()" method, what a name right? 😆 Also, I've always wondered by the delimiter has to be the first argument, I think it's intuitive to have the string as first arg though.&lt;br&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$content = explore("&amp;lt;/p&amp;gt;", $post-&amp;gt;content);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now, I have a way to break the string. But doing so would remove the closing tags for all "&lt;/p&gt;
&lt;p&gt;"s. The solution is to loop over each array item and add the close tag back, using array_map() function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$content = array_map(function ($c) {
  return $c . "&amp;lt;/p&amp;gt;";
}, $content);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I successfully made each paragraph an array item. Now, how do I slot in the ad? First, some articles are really short so I should make sure not to add ads in those. 5 became the number, if I split (aka explode) an article and the array items are not up to 5, no ad needs be there. Pass $content as a string in that case.&lt;br&gt;
&lt;/p&gt;

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

if (count(explode("&amp;lt;/p&amp;gt;", $post-&amp;gt;content)) &amp;gt;= 5) {
    $content = explode("&amp;lt;/p&amp;gt;", $post-&amp;gt;content);
    $content = array_map(function ($c) {
        return $c . "&amp;lt;/p&amp;gt;";
    }, $content);
} else {
  $content = "";
}

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

&lt;/div&gt;



&lt;p&gt;Alright, this would do for my controller method. Let's pass it down to blade.&lt;br&gt;
&lt;/p&gt;

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

return view('posts.show', [
    'post' =&amp;gt; $post,
    'content' =&amp;gt; $content,
]);

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

&lt;/div&gt;



&lt;p&gt;$post has all the properties of an article - title, categories, tags, author, etc&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enter Blade&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;...

@if (is_array($content))
  @foreach ($content as $key =&amp;gt; $i)
    @if ($key &amp;gt; 0 &amp;amp;&amp;amp; Str::length($i) &amp;gt;= 300 &amp;amp;&amp;amp; $key % 5 === 0 &amp;amp;&amp;amp; count($content) &amp;gt;= 10)
      @include('google_ad')                        
    @elseif(!(Str::length($i[floor($key / 5) * 5 -1]) &amp;gt;= 300) &amp;amp;&amp;amp; $key % 8 === 0 &amp;amp;&amp;amp; count($content) &amp;gt;= 12)
      @include('google_ad')
    @endif
    &amp;lt;div class="post-content"&amp;gt;
      {!! $i !!}
    &amp;lt;/div&amp;gt;                     
  @endforeach
@else
  &amp;lt;div class="post-content"&amp;gt;
    {!! $post-&amp;gt;content !!}
  &amp;lt;/div&amp;gt;
@endif 

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

&lt;/div&gt;



&lt;p&gt;Here, the outer @if is checking if an article even qualifies for ads, else show normal $post-&amp;gt;content&lt;/p&gt;

&lt;p&gt;If an article qualifies I'm then checking if a paragraph is up to 300 characters and that paragraph is divisible by 5 (5th, 10th, 15th,...), lastly, if it passes the previous tests, the total paragraphs must be up to 10, then include an ad.&lt;/p&gt;

&lt;p&gt;If the 5th (10th, 15th,...) paragraph isn't long enough (that calc is wild I know) let's insert an ad after every 8th paragraph, provided the article is up to 12 paragraphs this time. The idea is if I've printed ad at position 15, 16th shouldn't even bother, 20th should have 24th skip, you get idea.&lt;/p&gt;

&lt;p&gt;Well, there you go. In case, you've wondered how to slot ads or anything in between a long string of text.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>AWS NETWORKING 101</title>
      <dc:creator>Keme Kenneth</dc:creator>
      <pubDate>Sun, 08 Oct 2023 09:45:52 +0000</pubDate>
      <link>https://dev.to/zeelz/aws-networking-101-1co6</link>
      <guid>https://dev.to/zeelz/aws-networking-101-1co6</guid>
      <description>&lt;p&gt;AWS networking can be overwhelming, at least it was for me at first. But when you piece its various parts apart it's simple and digestible.&lt;br&gt;
In this post, let's understand the network components in AWS that make your EC2 instance possible, say to run a web server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Outline/ Components&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;VPC&lt;/li&gt;
&lt;li&gt;Network Access Control List (NACL)&lt;/li&gt;
&lt;li&gt;Internet Gateway&lt;/li&gt;
&lt;li&gt;Route Table &amp;amp; Routes&lt;/li&gt;
&lt;li&gt;Subnets&lt;/li&gt;
&lt;li&gt;Security Groups&lt;/li&gt;
&lt;li&gt;Network Interface&lt;/li&gt;
&lt;li&gt;NAT Gateway&lt;/li&gt;
&lt;li&gt;Create EC2 Instance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;We would be using AWS CLI, so go ahead, install and set up AWS CLI -&lt;/em&gt; &lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html"&gt;https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;VPC
&lt;/h2&gt;

&lt;p&gt;A virtual private cloud (VPC) is a logically isolated portion of the AWS Cloud. Think of it as your own special cloud environment to create all kind of resources. A VPC spans a region. Subnets, explained later, helps VPC isolate resources to different availability zones (AZs) for redundancy.&lt;br&gt;
VPC is the first resource you create before anything else. A VPC helps you define an IP range, which would be sub-divided by subnets. Your AWS account comes with a default VPC but you're not to use that for production.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Let's create a VPC and enable fancy hostnames&lt;/em&gt;&lt;br&gt;
&lt;code&gt;aws ec2 create-vpc --cidr-block 10.0.0.0/16&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;# Take note of the VcpId. I usually would store it as an env var&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;aws ec2 modify-vpc-attribute --vpc-id $VPC_ID --enable-dns-hostnames "{\"Value\":true}"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Check my post to understand VPC/Subnet IP range and CIDR sub-division&lt;/em&gt; - &lt;a href="https://dev.to/zeelz/dividing-ips-for-multiple-subnets-in-a-vpc-4f2a"&gt;Dividing IPs for Multiple Subnets in a VPC&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt; Network Access Control List
&lt;/h2&gt;

&lt;p&gt;Network Access Control List (NACL) is a stateless network resource that controls traffic to/fro resources in a VPC from the subnet level. It allows or denies access.&lt;br&gt;
Every VPC needs at least a NACL. Hence, on creation of a new VPC AWS automatically creates a default NACL attached to the VPC.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt; Internet Gateway
&lt;/h2&gt;

&lt;p&gt;Internet Gateway (IGW) is truly a VPC's gateway to the internet. &lt;/p&gt;

&lt;p&gt;Say, we have a website domicile in an EC2 instance with a public-facing IP, when Kayode from Ibadan hits that IP or hostname how does that request get to the EC2? Traffic gets to the EC2 through, you guessed it - IGW&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Let's create one and attach it to our VPC, else Kayode won't be able to browse our fancy blog&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;aws ec2 create-internet-gateway&lt;/code&gt;&lt;br&gt;
&lt;em&gt;# Take note of IgwId from the output&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;aws ec2 attach-internet-gateway --internet-gateway-id $IGW_ID --vpc-id $VPC_ID&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt; Route Table and Routes
&lt;/h2&gt;

&lt;p&gt;A route table is basically a collection of routes that determine the flow of internal and external traffic to/fro resources in a VPC.&lt;/p&gt;

&lt;p&gt;Upon creation of a new VPC, AWS automatically creates a default (main) route table&lt;/p&gt;

&lt;p&gt;Since, a VPC may have multiple route tables each route table associates with at least a subnet so resources know which route table routes their traffic per the subnet they belong to. But then if route table/subnet association is not explicitly defined, it's assumed that all subnets are associated with the default (main) route table (The one AWS gave us).&lt;/p&gt;

&lt;p&gt;We said a route table is a collection of routes, right? Yes, so we need to define a route for internet access (egress &amp;amp; ingress). This route would use the IGW as its target (router).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;aws ec2 create-route --route-table-id ROUTE_TABLE_ID --destination-cidr-block 0.0.0.0/0 --gateway-id IGW_ID&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;# IGW_ID from when we created IGW&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;To get id of default route table list all route tables and copy the RouteTableId where the DestinationCidrBlock is 30.0.0.0/24&lt;/em&gt;&lt;br&gt;
&lt;code&gt;aws ec2 describe-route-tables&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;Subnets
&lt;/h2&gt;

&lt;p&gt;Think of subnets as a way of splitting your VPC to bits, to be put in different AZs and to hold different applications or resources.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Create a subnet for the VPC. Let AWS place it in any Az within the VPC's region&lt;/em&gt;&lt;br&gt;
&lt;code&gt;aws ec2 create-subnet --cidr-block 30.0.0.0/16 --vpc-id $VPC_ID&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/zeelz/dividing-ips-for-multiple-subnets-in-a-vpc-4f2a"&gt;Why 30.0.0.0/16?&lt;/a&gt; Just incase we decide to create another subnet.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Enable public IP generation for public subnet&lt;/em&gt;&lt;br&gt;
&lt;em&gt;If not EC2s you create in this subnet won't have public-facing IP address&lt;/em&gt;&lt;br&gt;
&lt;code&gt;aws ec2 modify-subnet-attribute --subnet-id $SUBNET_ID --map-public-ip-on-launch&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;AWS automatically associates this subnet to the default NACL of the VPC. NACLs are for subnets after all 🤷‍♂️  &lt;/p&gt;

&lt;p&gt;A subnet that wants internet access should have a route in its route table pointing to an IGW, that is how a subnet is even said to be "public" anyway.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;Security Group
&lt;/h2&gt;

&lt;p&gt;A security groups (SG) is a stateful firewall at the instance level, as against NACL at the subnet level.&lt;br&gt;
You can create SG rules to define various traffic types, ports and sources.&lt;br&gt;
Say we want to create a rule for tcp traffic for port 80 and 0.0.0.0/0 as source. This would allow anyone on the internet to access our blog on port 80.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Create a security group&lt;/em&gt;&lt;br&gt;
&lt;code&gt;aws ec2 create-security-group --vpc-id $VPC_ID --group-name http-80 --description "http 80"&lt;/code&gt;&lt;br&gt;
&lt;em&gt;# Copy the groupId (sg-04dffb200473a5ce9)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Add a rule to open port 80, (Allows non-secure http traffic from anywhere)&lt;/em&gt;&lt;br&gt;
&lt;code&gt;aws ec2 authorize-security-group-ingress --group-id $SG_ID --protocol tcp --port 80 --cidr 0.0.0.0/0&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Go ahead and add a rule to open port 22 for SSH access&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt; Network Interface
&lt;/h2&gt;

&lt;p&gt;AWS Elastic network interface (ENI) is a virtual network adapter that lets resources between a VPC connect with each other and with the internet. ENIs are created in subnets.&lt;/p&gt;

&lt;p&gt;So how does an ENI work you ask? An ENI connects an EC2 instance to network resources through its subnet.&lt;br&gt;
Remember our subnet is associated with a route table, which has an IGW route. You get the flow&lt;br&gt;
&lt;em&gt;ENI =&amp;gt; subnet =&amp;gt; route table =&amp;gt; IGW route =&amp;gt; internet&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;But we mustn't create an ENI ourselves. AWS creates one for us on EC2 creation and attaches it to the instance. It would use the subnet and SG we specify for the EC2.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt; NAT Gateway
&lt;/h2&gt;

&lt;p&gt;For every route table there's a default (local) route for resources within a VPC to communicate. But what if an EC2 which isn't public needs internet to download stuffs and update itself? This is where a Network Address Translation gateway (NAT gateway) comes in.&lt;br&gt;
A NAT gateway allows instances in a private subnet to connect to the internet.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Create a NAT gateway in a public subnet&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;aws ec2 create-nat-gateway --subnet-id $SUBNET_ID&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
&lt;em&gt;# Take note of the NatGatewayId&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Create a route in a private subnet route table to target the NAT gateway&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;aws ec2 create-route --route-table-id ROUTE_TABLE_ID --destination-cidr-block 0.0.0.0/0 --nat-gateway-id NatGatewayId&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note&lt;/strong&gt;: A private subnet is one that isn't associated with a route table, which has an IGW route.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now the instances you create in this private subnet can't be accessed from the internet but can access the internet to download software packages.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt; EC2 Instance
&lt;/h2&gt;

&lt;p&gt;This is not an exhaustive list of AWS network components, but they are the basic ones you need.&lt;/p&gt;

&lt;p&gt;To finalize, let's create an EC2 instance utilizing the network resources created and configured above to install a web server to check our new networking prowess 😃 &lt;/p&gt;

&lt;p&gt;SSH Key Pair&lt;br&gt;
To login (ssh) to the instance, we would be need an SSH key file.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Create an SSH key-pair with which you would ssh into the instance&lt;/em&gt;&lt;br&gt;
&lt;code&gt;aws ec2 create-key-pair --key-name fancy-blog-ssh&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;# Carefully copy and save the private key string to a file - &lt;code&gt;privkey.pem&lt;/code&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;aws ec2 run-instances \&lt;br&gt;
--image-id ami-067d1e60475437da2 \&lt;br&gt;
--instance-type t2.micro \&lt;br&gt;
--subnet-id $SUBNET_ID \&lt;br&gt;
--security-group-ids sg-04dffb200473a5ce9 \&lt;br&gt;
--key-name fancy-blog-ssh \&lt;br&gt;
--associate-public-ip-address&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;image-id =&amp;gt; OS image (AWS Linux 2)&lt;/li&gt;
&lt;li&gt;instance-type =&amp;gt; CPU &amp;amp; memory categorization (1vCPU 1GiB memory)&lt;/li&gt;
&lt;li&gt;subnet-id =&amp;gt; our subnet id&lt;/li&gt;
&lt;li&gt;security-group-ids =&amp;gt; our SG id&lt;/li&gt;
&lt;li&gt;key-name =&amp;gt; the name we gave our key pair&lt;/li&gt;
&lt;li&gt;associate-public-ip-address =&amp;gt; generate a public IP for this instance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;# Take note of the InstanceId&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You need the &lt;code&gt;PublicIpAddress&lt;/code&gt; value, which is not populated at first but when you view that instance.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;# To view the instance details to get our &lt;code&gt;PublicIpAddress&lt;/code&gt;, run:&lt;/em&gt;&lt;br&gt;
&lt;code&gt;aws ec2 describe-instances --instance-id INSTANCE_ID&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
&lt;em&gt;Let's SSH into our machine and install a simple web server - &lt;code&gt;httpd&lt;/code&gt;&lt;/em&gt;&lt;br&gt;
&lt;code&gt;ssh -i privkey.pem ec2-user@54.210.11.65&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo yum install httpd&lt;br&gt;
sudo systemctl start httpd&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now open your browser and enter &lt;code&gt;http://54.210.11.65&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You should see "&lt;strong&gt;It works!&lt;/strong&gt;", if you didn't may have done something wrong. Comment below.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resources&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://docs.aws.amazon.com/cli/latest/reference/ec2/"&gt;https://docs.aws.amazon.com/cli/latest/reference/ec2/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tear Down&lt;/strong&gt;&lt;br&gt;
Always remember to tear down all the resources you create for learning purposes, to avoid incurring cost. AWS likes money like all of us 😆 &lt;/p&gt;

&lt;p&gt;❤️ ✌️ &lt;/p&gt;

</description>
    </item>
    <item>
      <title>Dividing IPs for Multiple Subnets in a VPC</title>
      <dc:creator>Keme Kenneth</dc:creator>
      <pubDate>Sun, 01 Oct 2023 10:12:11 +0000</pubDate>
      <link>https://dev.to/zeelz/dividing-ips-for-multiple-subnets-in-a-vpc-4f2a</link>
      <guid>https://dev.to/zeelz/dividing-ips-for-multiple-subnets-in-a-vpc-4f2a</guid>
      <description>&lt;p&gt;When creating resources for your application in a cloud infrastructure like AWS you would categorize resources into public or private subnets, often spread across multiple Availability Zones (AZs) for high availability, all in a single virtual private cloud (VPC).&lt;/p&gt;

&lt;p&gt;VPC defines the total IP range using CDIR (Classless Inter-Domain Routing) notation.&lt;br&gt;
Eg. 10.0.0.0/22 - 1024 IPs&lt;/p&gt;

&lt;p&gt;The number after the slash "/" - 22 (prefix length) is used to calculate the total IPs following a formula - 2^(32 - PREFIX_LEN). It could go from /0 to /32.&lt;/p&gt;

&lt;p&gt;In the above VPC the CIDR is 10.0.0.0/22 - 1024 IPs&lt;br&gt;
This means the total number of subnets will share 1024 IPs &lt;/p&gt;

&lt;p&gt;But how do you now further divide these IPs for each subnet?&lt;/p&gt;

&lt;p&gt;Octets referencing: &lt;br&gt;
[10].[0].[0].[0] =&amp;gt; [1st].[2nd].[3rd].[4th]&lt;/p&gt;

&lt;p&gt;Subnet-1 =&amp;gt; 10.0.0.0/24 - 256 IPs&lt;br&gt;
Range 10.0.0.0, 10.0.0.1, 10.0.0.2, ... 10.0.0.255&lt;br&gt;
Meaning the 4th or last octet is full it has exactly 256 IPs.  &lt;/p&gt;

&lt;p&gt;But anything below /24 would have eaten into the 3rd octet, say /23 - 512 IPs, because the last octet certainly don't have up to 1024 IPs&lt;/p&gt;

&lt;p&gt;Subnet-2&lt;br&gt;
Knowing that the last octet is full, 2nd subnet has the 3rd octet to play with.&lt;br&gt;
Common practice when creating additional subnets is to increase the octet by 1 - 10.0.1.0/24 - 256 IPs&lt;br&gt;
Range 10.0.1.0, 10.0.1.1 ... 10.0.1.255&lt;/p&gt;

&lt;p&gt;I could choose any PREFIX_LEN (0-32) but I also have to bear in mind that the VPC's total range is 1024&lt;br&gt;
If I did 10.0.1.0/22, this won't work because 1024 + Subnet-1's 256 is more than the VPC's total.&lt;/p&gt;

&lt;p&gt;Subnet-3 =&amp;gt; 10.0.2.0/24 - 256 IPs&lt;br&gt;
Range 10.0.2.0, 10.0.2.1, 10.0.2.2 ... 10.0.2.255&lt;/p&gt;

&lt;p&gt;I hope this brief explanation helps you understand how to allocate IP ranges to a VPC's subnets better.&lt;/p&gt;

&lt;p&gt;Thanks for reading ❤️&lt;/p&gt;

</description>
      <category>vpc</category>
      <category>cidr</category>
      <category>aws</category>
      <category>subnets</category>
    </item>
    <item>
      <title>Tailwind CSS and HTML for Production without Framework</title>
      <dc:creator>Keme Kenneth</dc:creator>
      <pubDate>Fri, 05 May 2023 10:07:12 +0000</pubDate>
      <link>https://dev.to/zeelz/tailwind-css-and-html-for-production-without-framework-56gh</link>
      <guid>https://dev.to/zeelz/tailwind-css-and-html-for-production-without-framework-56gh</guid>
      <description>&lt;p&gt;Want to use plain old HTML with Tailwind CSS but you're not using any framework?&lt;/p&gt;

&lt;p&gt;Because &lt;a href="https://cdn.tailwindcss.com"&gt;https://cdn.tailwindcss.com&lt;/a&gt; is only advised to be used for "play" not for production.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here's the ABC:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Assuming you already have your html site in a directory called &lt;code&gt;'site'&lt;/code&gt;, create a parent directory to contain &lt;code&gt;'site'&lt;/code&gt; - &lt;code&gt;'tailwind/site'&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install and initial Tailwind CSS:&lt;br&gt;
&lt;code&gt;cd tailwind&lt;br&gt;
npm install -D tailwindcss&lt;br&gt;
npx tailwindcss init&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update the content array of your tailwind.config.js to:&lt;br&gt;
&lt;code&gt;content: ["./site/**/*.html"]&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you have any theme config go ahead to update the theme object as well&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a &lt;code&gt;tw.css&lt;/code&gt; file in your project root &lt;code&gt;./tailwind/tw.css&lt;/code&gt; and add the following tailwind directives:&lt;br&gt;
&lt;code&gt;@tailwind base;&lt;br&gt;
@tailwind components;&lt;br&gt;
@tailwind utilities;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run Tailwind build command &lt;br&gt;
&lt;code&gt;npx tailwindcss -i ./tw.css -o ./site/main.css --watch&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tailwind will generate a main.css inside your /site dir. Add &lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt; it to your html and start using Tailwindcss utility classes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When you're done building your site, stop the tailwind cli and copy the site directory or push just the site directory to GitHub for onward deployment&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enjoy!&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>Downgrade create-react-app@latest to @17</title>
      <dc:creator>Keme Kenneth</dc:creator>
      <pubDate>Mon, 24 Oct 2022 09:17:37 +0000</pubDate>
      <link>https://dev.to/zeelz/downgrade-create-react-applatest-to-17-54ko</link>
      <guid>https://dev.to/zeelz/downgrade-create-react-applatest-to-17-54ko</guid>
      <description>&lt;p&gt;You ran &lt;code&gt;npx create-react-app@latest&lt;/code&gt; to get things started. Now you want to take it down a notch, to say version @17.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do these:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Remove node_module&lt;/li&gt;
&lt;li&gt;Remove package-lock.json&lt;/li&gt;
&lt;li&gt;In package.json &amp;gt; change version for react &amp;amp; react-dom to "^17.2.0" or your choice&lt;/li&gt;
&lt;li&gt;Update index.js as shown:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { render } from 'react-dom'; 

const root = document.getElementById('root');
render(

  &amp;lt;React.StrictMode&amp;gt;
    &amp;lt;App /&amp;gt;
  &amp;lt;/React.StrictMode&amp;gt;,

  root

);

reportWebVitals();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;@17 doesn't use ReactDOM&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Get root element directly with DOM selector&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Pass root as 2nd arg to render()&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Promise.all(), Promise.any() as Simple as ABC</title>
      <dc:creator>Keme Kenneth</dc:creator>
      <pubDate>Fri, 21 Oct 2022 15:15:52 +0000</pubDate>
      <link>https://dev.to/zeelz/promiseall-promiseany-as-simple-as-abc-1b61</link>
      <guid>https://dev.to/zeelz/promiseall-promiseany-as-simple-as-abc-1b61</guid>
      <description>&lt;p&gt;Many of us now regard the beloved Javascript &lt;strong&gt;Promise API&lt;/strong&gt; as old fashioned, now that we have &lt;strong&gt;async/await&lt;/strong&gt;. But Promises still have their place and are still very relevant.&lt;/p&gt;

&lt;p&gt;But what if you're just beginning to learn Promises and are finding it hard to wrap your head around. Follow me briefly as I quickly explain it with a simple code example.&lt;/p&gt;

&lt;p&gt;A promise is a function that helps you write asynchronous code. What this means is that if you make a network request in your program other parts of the program won't have to wait  until your network request is complete. I'm sure you must have heard that Javascript is single-threaded, and runs your code from top to bottom.&lt;/p&gt;

&lt;p&gt;Javascript Promise API is available to us as a class, all you have to do is to instantiate it as you would a class in OOP.&lt;/p&gt;

&lt;p&gt;It takes two arguments, which are functions you use to return the data from your request or the error, if that was the case.&lt;/p&gt;

&lt;p&gt;Conventionally, we call the arguments resolve and reject. The former returns your data, while the latter returns error.&lt;/p&gt;

&lt;p&gt;Alright, enough talk. Let's see a simple example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const userPromise = new Promise((resolve, reject) =&amp;gt; {
    axios()
    .then((res) =&amp;gt; resolve(res.data))
    .catch((error) =&amp;gt; reject(error))
})

userPromise
.then((data) =&amp;gt; {
    // use data here
})
.catch((error) =&amp;gt; {
    // handle error elegantly
    console.log(error)
})

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

&lt;/div&gt;



&lt;p&gt;If what you need to make multiple API requests and you want all of them to complete (resolve) before you can do anything with them. You have just the perfect method of that - Promise.all()&lt;/p&gt;

&lt;p&gt;This method takes a list of promises or requests that haven't resolved.&lt;/p&gt;

&lt;p&gt;It resolves all your promises in a go if all of them went well but return the reject should any fail.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const axios = require('axios') #assumes axios is imported
const userPromise = new Promise((resolve, reject) =&amp;gt; {

    const req1 = axios.get('https://reqres.in/api/users/1')
    const req2 = axios.get('https://reqres.in/api/users/2')
    const req3 = axios.get('https://reqres.in/api/users/3')

    Promise.all([req1, req2, req3])
    // # when all of the promises resolve
    .then(promises =&amp;gt; resolve(promises))

    // # when any of the promises rejects
    .catch(err =&amp;gt; reject(err))
});

userPromise
// #if all 3 reqs went well
.then((listOfPromiseData) =&amp;gt; {    
    const users = listOfPromiseData.map(({data}) =&amp;gt; data.data.email)
    console.log(users)
})
// if any of reqs went south
.catch((err) =&amp;gt; console.log('just err...'))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remember in the above example all 3 requests must be successful for .all() to resolve. But in other situations you might need just one of the requests to come true to proceed, in such case the candidate is Promise.any(). I'm sure you don't need another example to show this. Use .any() in place .all() and intentionally fail of your requests.&lt;/p&gt;

&lt;p&gt;Hope you've learnt something today. Thank you for reading ❤️ &lt;/p&gt;

</description>
    </item>
    <item>
      <title>Scaling &amp; Load-balancing NodeJS Containers with Nginx</title>
      <dc:creator>Keme Kenneth</dc:creator>
      <pubDate>Sat, 08 Oct 2022 12:33:35 +0000</pubDate>
      <link>https://dev.to/zeelz/scaling-load-balancing-nodejs-containers-with-nginx-2fc0</link>
      <guid>https://dev.to/zeelz/scaling-load-balancing-nodejs-containers-with-nginx-2fc0</guid>
      <description>&lt;p&gt;So, your NodeJS application is getting loads of requests, and it has become too much for a single server to handle. Now, you don't have a fancy AWS managed service to help you. The solution would be to manually scale your servers horizontally. Horizontally scaling is provisioning replica servers as opposed to increasing the CPU/memory combination of a single server to handle more load.&lt;/p&gt;

&lt;p&gt;Luckily, Docker and Docker-compose with Nginx could easily get the job done for you.&lt;br&gt;
Docker could easily scale your servers to any number. With Docker-compose, the job becomes even easier as you don't always have to type in a bunch &lt;code&gt;docker&lt;/code&gt; commands.&lt;/p&gt;

&lt;p&gt;Okay, let's assume you've used Docker to replicate your servers to 3, meaning your NodeJS application is now running in 3 replica containers. The question becomes how would each of the server know when to handle a request? In comes Nginx.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Nginx: The software load balancer, reverse proxy, web server, &amp;amp; content cache with the enterprise features and support you expect.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Nginx at its core is a web server. &lt;br&gt;
While your 3 containers are running and not knowing when any of them should rise to the occasion and handle a request, Nginx can help with that situation with its load-balancing feature.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Load balancing refers to efficiently distributing incoming network traffic across a group of backend servers, also known as a server farm or server pool. - &lt;em&gt;Nginx&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Nginx in this case, will act as a proxy server, standing between your client requests and your 3 servers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fezylpnt3ifzgvie112nz.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%2Fezylpnt3ifzgvie112nz.png" alt="Depiction of application load balancing"&gt;&lt;/a&gt; © &lt;em&gt;phoenixNAP&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When a new request comes in Nginx will accept it and route it to one of the servers. It has 3 algorithms it uses to tell which server to route traffic per time. The default of those algorithm is round-robin.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Round-robin:&lt;/strong&gt;&lt;br&gt;
First request to to server1, second request to server2, and third to server3, then repeat&lt;/p&gt;

&lt;p&gt;Say your NodeJS server is listening on port 3000, a simple docker-compose script would look something 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;version: '3.9'

services:
  nodeapp:
    build: .
    ports:
      - "3000"

  nginx:
    image: nginx:latest
    ports:
      - "4000:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;docker-compose.yml&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The compose script builds your NodeJS app from your Dockerfile and pulls Nginx server from docker public registry. The &lt;code&gt;nodeapp&lt;/code&gt; service is not mapped to any specific host port because only a single machine can map to a host port at every given time. But the nginx server would be taken requests on port 80, mapped to the host's 4000.&lt;/p&gt;

&lt;p&gt;Furthermore, we added the &lt;code&gt;volumes&lt;/code&gt; directive, to enable to us write a config file to nginx to build. This config is the crux of this setup.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;events {
  worker_connections  4096;
}

http {
    server {
        listen 80;
        location / {
            proxy_pass http://nodeapp:3000;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;nginx.conf&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Nginx listens on &lt;code&gt;/&lt;/code&gt; (home route) on port &lt;code&gt;80&lt;/code&gt;, then routes traffic to &lt;code&gt;nodeapp&lt;/code&gt; on port &lt;code&gt;3000&lt;/code&gt; using its &lt;code&gt;proxy_pass&lt;/code&gt; directive.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Complete scripts including Dockerfile and simple Express app are available on my Github&lt;/em&gt; &lt;a href="https://github.com/zeelz/zeelz-developer/tree/nodejs-docker-compose-nginx" rel="noopener noreferrer"&gt;https://github.com/zeelz/zeelz-developer/tree/nodejs-docker-compose-nginx&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=4Bm2lA1m7xk" rel="noopener noreferrer"&gt;Video Walkthrough&lt;/a&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>nginx</category>
      <category>node</category>
      <category>containerapps</category>
    </item>
    <item>
      <title>Beautiful color scheme for iTerm2/Terminal</title>
      <dc:creator>Keme Kenneth</dc:creator>
      <pubDate>Sat, 08 Oct 2022 08:38:29 +0000</pubDate>
      <link>https://dev.to/zeelz/beautiful-color-scheme-for-iterm2terminal-44n</link>
      <guid>https://dev.to/zeelz/beautiful-color-scheme-for-iterm2terminal-44n</guid>
      <description>&lt;p&gt;&lt;strong&gt;Grey Green&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://raw.githubusercontent.com/mbadolato/iTerm2-Color-Schemes/master/schemes/Grey-green.itermcolors"&gt;https://raw.githubusercontent.com/mbadolato/iTerm2-Color-Schemes/master/schemes/Grey-green.itermcolors&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to Use:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&amp;gt; &lt;code&gt;iTerms2&lt;/code&gt; menu&lt;/li&gt;
&lt;li&gt;&amp;gt;&amp;gt; &lt;code&gt;Preferences&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;&amp;gt;&amp;gt;&amp;gt; &lt;code&gt;Profiles&lt;/code&gt; tab&lt;/li&gt;
&lt;li&gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt; &lt;code&gt;Colors&lt;/code&gt; tab&lt;/li&gt;
&lt;li&gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt; &lt;code&gt;Color Presets&lt;/code&gt; dropdown&lt;/li&gt;
&lt;li&gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt; Import downloaded color file&lt;/li&gt;
&lt;li&gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt; Choose imported color scheme from list&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
