<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Coding Blogs]]></title><description><![CDATA[Coding Blogs]]></description><link>https://blog.pranish.dev</link><generator>RSS for Node</generator><lastBuildDate>Mon, 20 Apr 2026 05:44:45 GMT</lastBuildDate><atom:link href="https://blog.pranish.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[# How to Point Subdomains to Different Ports Using Nginx - Complete Guide]]></title><description><![CDATA[What We'll Build
By the end of this tutorial, you'll have:

social-media.pranishpdl.ai pointing to your app running on port 3002

yantracore.pranishpdl.ai pointing to your app running on port 3000

Both running on the same server using Nginx as a rev...]]></description><link>https://blog.pranish.dev/how-to-point-subdomains-to-different-ports-using-nginx-complete-guide</link><guid isPermaLink="true">https://blog.pranish.dev/how-to-point-subdomains-to-different-ports-using-nginx-complete-guide</guid><dc:creator><![CDATA[Pranish Poudel]]></dc:creator><pubDate>Mon, 14 Jul 2025 10:39:57 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-what-well-build">What We'll Build</h2>
<p>By the end of this tutorial, you'll have:</p>
<ul>
<li><p><a target="_blank" href="http://social-media.pranishpdl.ai"><code>social-media.pranishpdl.ai</code></a> pointing to your app running on port 3002</p>
</li>
<li><p><a target="_blank" href="http://yantracore.pranishpdl.ai"><code>yantracore.pranishpdl.ai</code></a> pointing to your app running on port 3000</p>
</li>
<li><p>Both running on the same server using Nginx as a reverse proxy</p>
</li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<ul>
<li><p>A server (EC2, VPS, etc.) with root access</p>
</li>
<li><p>A domain name with DNS management access</p>
</li>
<li><p>Basic knowledge of command line</p>
</li>
</ul>
<h2 id="heading-step-1-install-and-configure-nginx">Step 1: Install and Configure Nginx</h2>
<p>First, let's install Nginx on your server:</p>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Update your system</span>
sudo yum update -y

<span class="hljs-comment"># Install Nginx</span>
sudo yum install nginx -y

<span class="hljs-comment"># Start Nginx service</span>
sudo systemctl start nginx

<span class="hljs-comment"># Enable Nginx to start on boot</span>
sudo systemctl <span class="hljs-built_in">enable</span> nginx
</code></pre>
<p>Verify Nginx is running:</p>
<p>bash</p>
<pre><code class="lang-bash">sudo systemctl status nginx
</code></pre>
<h2 id="heading-step-2-configure-dns-records">Step 2: Configure DNS Records</h2>
<p>Go to your domain registrar's DNS management panel (Cloudflare, GoDaddy, etc.) and add these A records:</p>
<pre><code class="lang-plaintext">Subdomain    Points To
social-media.pranishpdl.ai    [EC2 Public IP]
yantracore.pranishpdl.ai    [EC2 Public IP]
</code></pre>
<p><strong>Note:</strong> Replace <code>[your server's public IP]</code> with your actual server IP address.</p>
<h2 id="heading-step-3-create-nginx-configuration-files">Step 3: Create Nginx Configuration Files</h2>
<p>Now let's create separate configuration files for each subdomain.</p>
<h3 id="heading-configure-social-media-subdomain">Configure social-media subdomain</h3>
<p>Create a new configuration file:</p>
<p>bash</p>
<pre><code class="lang-bash">sudo vim /etc/nginx/conf.d/social-media.conf
</code></pre>
<p>Add the following configuration:</p>
<p>nginx</p>
<pre><code class="lang-nginx"><span class="hljs-section">server</span> {
    <span class="hljs-attribute">listen</span> <span class="hljs-number">80</span>;
    <span class="hljs-attribute">server_name</span> social-media.pranishpdl.ai;

    <span class="hljs-attribute">location</span> / {
        <span class="hljs-attribute">proxy_pass</span> http://localhost:3002;
        <span class="hljs-attribute">proxy_set_header</span> Host <span class="hljs-variable">$host</span>;
        <span class="hljs-attribute">proxy_set_header</span> X-Real-IP <span class="hljs-variable">$remote_addr</span>;
        <span class="hljs-attribute">proxy_set_header</span> X-Forwarded-For <span class="hljs-variable">$proxy_add_x_forwarded_for</span>;
        <span class="hljs-attribute">proxy_set_header</span> X-Forwarded-Proto <span class="hljs-variable">$scheme</span>;
    }
}
</code></pre>
<h3 id="heading-configure-yantracore-subdomain">Configure yantracore subdomain</h3>
<p>Create another configuration file:</p>
<p>bash</p>
<pre><code class="lang-bash">sudo vim /etc/nginx/conf.d/yantracore.conf
</code></pre>
<p>Add the following configuration:</p>
<p>nginx</p>
<pre><code class="lang-nginx"><span class="hljs-section">server</span> {
    <span class="hljs-attribute">listen</span> <span class="hljs-number">80</span>;
    <span class="hljs-attribute">server_name</span> yantracore.pranishpdl.ai;

    <span class="hljs-attribute">location</span> / {
        <span class="hljs-attribute">proxy_pass</span> http://localhost:3000;
        <span class="hljs-attribute">proxy_set_header</span> Host <span class="hljs-variable">$host</span>;
        <span class="hljs-attribute">proxy_set_header</span> X-Real-IP <span class="hljs-variable">$remote_addr</span>;
        <span class="hljs-attribute">proxy_set_header</span> X-Forwarded-For <span class="hljs-variable">$proxy_add_x_forwarded_for</span>;
        <span class="hljs-attribute">proxy_set_header</span> X-Forwarded-Proto <span class="hljs-variable">$scheme</span>;
    }
}
</code></pre>
<h2 id="heading-step-4-test-and-restart-nginx">Step 4: Test and Restart Nginx</h2>
<p>Before restarting, let's test our configuration:</p>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Test Nginx configuration syntax</span>
sudo nginx -t
</code></pre>
<p>If the test passes, restart Nginx:</p>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Restart Nginx to apply changes</span>
sudo systemctl restart nginx

<span class="hljs-comment"># Check if Nginx is running properly</span>
sudo systemctl status nginx
</code></pre>
<h2 id="heading-step-5-verify-your-setup">Step 5: Verify Your Setup</h2>
<ol>
<li><p>Make sure your applications are running on their respective ports:</p>
<ul>
<li><p>Social media app on port 3002</p>
</li>
<li><p>Yantracore app on port 3000</p>
</li>
</ul>
</li>
<li><p>Test your subdomains in a browser:</p>
<ul>
<li><p>Visit <a target="_blank" href="http://social-media.pranishpdl.ai"><code>http://social-media.pranishpdl.ai</code></a></p>
</li>
<li><p>Visit <a target="_blank" href="http://yantracore.pranishpdl.ai"><code>http://yantracore.pranishpdl.ai</code></a></p>
</li>
</ul>
</li>
</ol>
<h2 id="heading-troubleshooting-common-issues">Troubleshooting Common Issues</h2>
<h3 id="heading-dns-not-resolving">DNS Not Resolving</h3>
<ul>
<li><p>Wait 24-48 hours for DNS propagation</p>
</li>
<li><p>Use <code>nslookup</code> or <code>dig</code> to check DNS records</p>
</li>
</ul>
<h3 id="heading-502-bad-gateway-error">502 Bad Gateway Error</h3>
<ul>
<li><p>Ensure your applications are running on the specified ports</p>
</li>
<li><p>Check if ports are accessible: <code>netstat -tlnp | grep :3000</code></p>
</li>
</ul>
<h3 id="heading-permission-denied">Permission Denied</h3>
<ul>
<li><p>Check SELinux settings: <code>sudo setsebool -P httpd_can_network_connect 1</code></p>
</li>
<li><p>Verify firewall rules allow traffic on port 80</p>
</li>
</ul>
<h2 id="heading-security-considerations-optional-but-recommended">Security Considerations (Optional but Recommended)</h2>
<h3 id="heading-add-ssltls-with-lets-encrypt">Add SSL/TLS with Let's Encrypt</h3>
<p>Install Certbot:</p>
<p>bash</p>
<pre><code class="lang-bash">sudo yum install certbot python3-certbot-nginx -y
</code></pre>
<p>Generate SSL certificates:</p>
<p>bash</p>
<pre><code class="lang-bash">sudo certbot --nginx -d social-media.pranishpdl.ai -d yantracore.pranishpdl.ai
</code></pre>
<p>This will automatically update your Nginx configuration to use HTTPS.</p>
<h2 id="heading-advanced-configuration">Advanced Configuration</h2>
<p>You can enhance your setup by adding:</p>
<ul>
<li><p><strong>Rate limiting</strong> to prevent abuse</p>
</li>
<li><p><strong>Caching</strong> to improve performance</p>
</li>
<li><p><strong>Load balancing</strong> for high availability</p>
</li>
<li><p><strong>Custom error pages</strong> for better user experience</p>
</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>You've successfully configured Nginx to route different subdomains to different ports on your server! This setup allows you to run multiple applications on a single server while maintaining clean, professional URLs.</p>
<p>This reverse proxy approach is scalable and commonly used in production environments. You can easily add more subdomains by creating additional configuration files following the same pattern.</p>
<h2 id="heading-whats-next">What's Next?</h2>
<ul>
<li><p>Consider implementing SSL/TLS for security</p>
</li>
<li><p>Set up monitoring for your applications</p>
</li>
<li><p>Explore Nginx caching for better performance</p>
</li>
<li><p>Learn about load balancing for high availability</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[How to Host a Next.js App on Ubuntu Linux: A Step-by-Step Guide]]></title><description><![CDATA[Introduction
Hosting a Next.js application on an Ubuntu Linux server can be a straightforward process, but it's helpful to have a detailed guide to ensure a smooth setup. In this article, we'll walk through the necessary steps to get your Next.js app...]]></description><link>https://blog.pranish.dev/how-to-host-a-nextjs-app-on-ubuntu-linux-a-step-by-step-guide</link><guid isPermaLink="true">https://blog.pranish.dev/how-to-host-a-nextjs-app-on-ubuntu-linux-a-step-by-step-guide</guid><dc:creator><![CDATA[Pranish Poudel]]></dc:creator><pubDate>Tue, 29 Oct 2024 15:21:15 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1730215262644/c755046e-a680-488e-98ec-c5585ea41289.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>Hosting a Next.js application on an Ubuntu Linux server can be a straightforward process, but it's helpful to have a detailed guide to ensure a smooth setup. In this article, we'll walk through the necessary steps to get your Next.js app up and running on an Ubuntu Linux machine.</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before we begin, make sure you have the following:</p>
<ol>
<li><p><strong>Ubuntu Linux Server</strong>: You'll need an Ubuntu Linux server, either a physical machine or a virtual server (e.g., a cloud instance).</p>
</li>
<li><p><strong>Node.js and npm</strong>: You'll need to have Node.js and npm (the Node.js package manager) installed on your Ubuntu server. You can install the latest LTS version of Node.js using the following command:</p>
<pre><code class="lang-javascript"> bashCopycurl -fsSL https:<span class="hljs-comment">//deb.nodesource.com/setup_lts.x | sudo -E bash -</span>
 sudo apt-get install -y nodejs
</code></pre>
</li>
<li><p><strong>Git</strong>: You'll need to have Git installed to clone your Next.js project repository. You can install Git using the following command:</p>
<pre><code class="lang-javascript"> bashCopysudo apt-get install git
</code></pre>
</li>
<li><p><strong>PM2 (optional)</strong>: While not strictly required, we recommend using the PM2 process manager to manage your Next.js application. You can install PM2 using the following command:</p>
<pre><code class="lang-javascript"> bashCopynpm install -g pm2
</code></pre>
</li>
</ol>
<h2 id="heading-step-1-clone-your-nextjs-project-repository">Step 1: Clone Your Next.js Project Repository</h2>
<p>Start by cloning your Next.js project repository to the server. Assuming your project is hosted on GitHub, you can use the following command:</p>
<pre><code class="lang-javascript">bashCopygit clone https:<span class="hljs-comment">//github.com/your-username/your-project.git</span>
</code></pre>
<p>Replace <code>your-username/your-project</code> with the actual URL of your Next.js project repository.</p>
<h2 id="heading-step-2-install-dependencies">Step 2: Install Dependencies</h2>
<p>Navigate to the cloned project directory and install the necessary dependencies using npm:</p>
<pre><code class="lang-javascript">bashCopycd your-project
npm install
</code></pre>
<h2 id="heading-step-3-build-the-nextjs-application">Step 3: Build the Next.js Application</h2>
<p>Next, build your Next.js application for production:</p>
<pre><code class="lang-javascript">bashCopynpm run build
</code></pre>
<p>This will generate the optimized, production-ready files for your Next.js app.</p>
<h2 id="heading-step-4-start-the-nextjs-application">Step 4: Start the Next.js Application</h2>
<p>At this point, you have two options to start your Next.js application:</p>
<ol>
<li><p><strong>Using the Next.js Development Server</strong>: You can start the Next.js development server using the following command:</p>
<pre><code class="lang-javascript"> bashCopynpm start
</code></pre>
<p> This will start the Next.js server and make your application accessible at <a target="_blank" href="http://your-server-ip:3000"><code>http://your-server-ip:3000</code></a>.</p>
</li>
<li><p><strong>Using PM2 (Recommended)</strong>: If you installed PM2 earlier, you can use it to manage your Next.js application. Start the application using the following command:</p>
<pre><code class="lang-javascript"> bashCopypm2 start npm --name <span class="hljs-string">"your-app"</span> -- start
</code></pre>
<p> This will start your Next.js app using PM2 and give it the name "your-app". You can then use PM2 commands to manage your application, such as <code>pm2 status</code>, <code>pm2 logs</code>, and <code>pm2 restart your-app</code>.</p>
</li>
</ol>
<h2 id="heading-step-5-set-up-nginx-as-a-reverse-proxy">Step 5: Set Up Nginx as a Reverse Proxy</h2>
<p>To make your Next.js application accessible from the internet, you'll need to set up a reverse proxy using Nginx. Install Nginx using the following command:</p>
<pre><code class="lang-javascript">bashCopysudo apt-get install nginx
</code></pre>
<p>Create a new Nginx configuration file for your Next.js app:</p>
<pre><code class="lang-javascript">bashCopysudo nano /etc/nginx/conf.d/your-app.conf
</code></pre>
<p>Add the following content to the file, replacing <code>your-server-ip</code> with the IP address of your Ubuntu server:</p>
<pre><code class="lang-javascript">nginxCopyserver {
  listen <span class="hljs-number">80</span>;
  server_name your-server-ip;

  location / {
    proxy_pass http:<span class="hljs-comment">//localhost:3000;</span>
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $host;
    proxy_redirect off;
  }
}
</code></pre>
<p>Save the file and restart Nginx:</p>
<pre><code class="lang-javascript">bashCopysudo systemctl restart nginx
</code></pre>
<p>Now, your Next.js application should be accessible at <a target="_blank" href="http://your-server-ip"><code>http://your-server-ip</code></a>.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this guide, you've learned how to host a Next.js application on an Ubuntu Linux server. By following these steps, you can successfully deploy your Next.js app and make it accessible to your users. Remember to adapt the commands and file paths to match your specific project and server setup.</p>
]]></content:encoded></item><item><title><![CDATA[Backend Video Encoding using FFmpeg, Docker, and AWS ECS]]></title><description><![CDATA[Introduction
In this guide, we will explore how to build a backend system for video encoding using FFmpeg, Docker, and AWS services. We'll create a Node.js application that can accept video files, encode them into different formats, and store the enc...]]></description><link>https://blog.pranish.dev/backend-video-encoding-using-ffmpeg-docker-and-aws-ecs</link><guid isPermaLink="true">https://blog.pranish.dev/backend-video-encoding-using-ffmpeg-docker-and-aws-ecs</guid><dc:creator><![CDATA[Pranish Poudel]]></dc:creator><pubDate>Tue, 29 Oct 2024 15:14:16 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1730214842332/cf1af187-a8ac-4889-96b7-de24a9d85b39.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-introduction">Introduction</h3>
<p>In this guide, we will explore how to build a backend system for video encoding using FFmpeg, Docker, and AWS services. We'll create a Node.js application that can accept video files, encode them into different formats, and store the encoded videos in an S3 bucket. This setup allows for efficient, scalable, and on-demand video processing in the cloud.</p>
<h3 id="heading-prerequisites">Prerequisites</h3>
<ul>
<li><p>Node.js and npm installed on your development machine</p>
</li>
<li><p>Docker installed on your development machine</p>
</li>
<li><p>An AWS account with access to S3 and ECS</p>
<h3 id="heading-step-1-set-up-the-nodejs-application">Step 1: Set up the Node.js Application</h3>
<p>  First, let's create a new Node.js project and install the necessary dependencies:</p>
<pre><code class="lang-javascript">  bashCopymkdir video-encoder
  cd video-encoder
  npm init -y
  npm install ffmpeg-<span class="hljs-keyword">static</span> @aws-sdk/client-s3
</code></pre>
<p>  Now, create a new file called <code>app.js</code> and add the following code:</p>
<pre><code class="lang-javascript">  javascriptCopyconst fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'fs'</span>);
  <span class="hljs-keyword">const</span> { S3Client, PutObjectCommand } = <span class="hljs-built_in">require</span>(<span class="hljs-string">"@aws-sdk/client-s3"</span>);
  <span class="hljs-keyword">const</span> ffmpeg = <span class="hljs-built_in">require</span>(<span class="hljs-string">'ffmpeg-static'</span>);
  <span class="hljs-keyword">const</span> { spawn } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'child_process'</span>);

  <span class="hljs-comment">// AWS S3 configuration</span>
  <span class="hljs-keyword">const</span> s3 = <span class="hljs-keyword">new</span> S3Client({
    <span class="hljs-attr">region</span>: <span class="hljs-string">'us-east-1'</span>,
    <span class="hljs-attr">credentials</span>: {
      <span class="hljs-attr">accessKeyId</span>: <span class="hljs-string">'YOUR_AWS_ACCESS_KEY_ID'</span>,
      <span class="hljs-attr">secretAccessKey</span>: <span class="hljs-string">'YOUR_AWS_SECRET_ACCESS_KEY'</span>
    }
  });

  <span class="hljs-keyword">const</span> BUCKET_NAME = <span class="hljs-string">'your-s3-bucket-name'</span>;

  <span class="hljs-comment">// Function to encode a video file</span>
  <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">encodeVideo</span>(<span class="hljs-params">inputFile, outputFile, format</span>) </span>{
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =&gt;</span> {
      <span class="hljs-keyword">const</span> ffmpegProcess = spawn(ffmpeg, [
        <span class="hljs-string">'-i'</span>, inputFile,
        <span class="hljs-string">'-c:v'</span>, <span class="hljs-string">'libx264'</span>,
        <span class="hljs-string">'-preset'</span>, <span class="hljs-string">'medium'</span>,
        <span class="hljs-string">'-crf'</span>, <span class="hljs-string">'23'</span>,
        <span class="hljs-string">'-c:a'</span>, <span class="hljs-string">'aac'</span>,
        <span class="hljs-string">'-b:a'</span>, <span class="hljs-string">'128k'</span>,
        <span class="hljs-string">'-f'</span>, format,
        outputFile
      ]);

      ffmpegProcess.on(<span class="hljs-string">'close'</span>, <span class="hljs-function">(<span class="hljs-params">code</span>) =&gt;</span> {
        <span class="hljs-keyword">if</span> (code === <span class="hljs-number">0</span>) {
          resolve();
        } <span class="hljs-keyword">else</span> {
          reject(<span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">`FFmpeg exited with code <span class="hljs-subst">${code}</span>`</span>));
        }
      });

      ffmpegProcess.on(<span class="hljs-string">'error'</span>, <span class="hljs-function">(<span class="hljs-params">err</span>) =&gt;</span> {
        reject(err);
      });
    });
  }

  <span class="hljs-comment">// Function to upload a file to S3</span>
  <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">uploadToS3</span>(<span class="hljs-params">file, key</span>) </span>{
    <span class="hljs-keyword">await</span> s3.send(<span class="hljs-keyword">new</span> PutObjectCommand({
      <span class="hljs-attr">Bucket</span>: BUCKET_NAME,
      <span class="hljs-attr">Key</span>: key,
      <span class="hljs-attr">Body</span>: fs.createReadStream(file)
    }));
  }

  <span class="hljs-comment">// Example usage</span>
  <span class="hljs-keyword">const</span> inputFile = <span class="hljs-string">'path/to/input/video.mp4'</span>;
  <span class="hljs-keyword">const</span> outputFormats = [<span class="hljs-string">'mp4'</span>, <span class="hljs-string">'webm'</span>, <span class="hljs-string">'mov'</span>];

  (<span class="hljs-keyword">async</span> () =&gt; {
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> format <span class="hljs-keyword">of</span> outputFormats) {
      <span class="hljs-keyword">const</span> outputFile = <span class="hljs-string">`path/to/output/video.<span class="hljs-subst">${format}</span>`</span>;
      <span class="hljs-keyword">await</span> encodeVideo(inputFile, outputFile, format);
      <span class="hljs-keyword">await</span> uploadToS3(outputFile, <span class="hljs-string">`videos/video.<span class="hljs-subst">${format}</span>`</span>);
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Uploaded video in <span class="hljs-subst">${format}</span> format to S3`</span>);
    }
  })();
</code></pre>
<p>  This code sets up a basic video encoding and upload process using FFmpeg and AWS S3. It defines two main functions:</p>
<ol>
<li><p><code>encodeVideo</code>: This function takes an input video file, an output file, and the desired output format, and uses FFmpeg to encode the video.</p>
</li>
<li><p><code>uploadToS3</code>: This function uploads a file to an S3 bucket.</p>
</li>
</ol>
</li>
</ul>
<p>    The example usage at the bottom of the file demonstrates how to call these functions to encode a video file in multiple formats and upload them to S3.</p>
<h3 id="heading-step-2-dockerize-the-application">Step 2: Dockerize the Application</h3>
<p>    To make the application more portable and easier to deploy, we'll create a Docker image for it. Create a new file called <code>Dockerfile</code> in the project directory and add the following content:</p>
<pre><code class="lang-javascript">    DockerfileCopyFROM node:<span class="hljs-number">14</span>-slim

    WORKDIR /app

    COPY package.json .
    COPY app.js .

    RUN npm install

    CMD [<span class="hljs-string">"node"</span>, <span class="hljs-string">"app.js"</span>]
</code></pre>
<p>    This Dockerfile sets up a Node.js environment, copies the necessary files, installs the dependencies, and runs the <code>app.js</code> script when the container starts.</p>
<h3 id="heading-step-3-deploy-to-aws-ecs">Step 3: Deploy to AWS ECS</h3>
<p>    Now that we have our Docker image, we can deploy the application to AWS Elastic Container Service (ECS). Here's a high-level overview of the steps:</p>
<ol>
<li><p>Create an ECS cluster.</p>
</li>
<li><p>Create a task definition for your video encoding application.</p>
</li>
<li><p>Create a service to run the task definition.</p>
</li>
</ol>
<p>    You can follow the AWS documentation for detailed instructions on <a target="_blank" href="https://docs.aws.amazon.com/AmazonECS/latest/developerguide/create-cluster.html">creating an ECS cluster</a>, <a target="_blank" href="https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html">creating a task definition</a>, and <a target="_blank" href="https://docs.aws.amazon.com/AmazonECS/latest/developerguide/create-service.html">creating a service</a>.</p>
<p>    Once your application is deployed, you can trigger the video encoding process by sending HTTP requests to the ECS service. The service will then process the videos and store the encoded files in the specified S3 bucket.</p>
<h3 id="heading-conclusion">Conclusion</h3>
<p>    In this guide, you've learned how to build a backend system for video encoding using FFmpeg, Docker, and AWS services. By leveraging these tools, you can create a scalable, efficient, and cloud-based video processing solution that can handle a variety of video formats and store the results in an S3 bucket. This setup can be easily integrated into your existing applications or used as a standalone video encoding service.</p>
]]></content:encoded></item><item><title><![CDATA[Scaling Node.js Applications to Millions of Users]]></title><description><![CDATA[As your Node.js application grows in popularity and you start to see increasing user traffic, you'll need to think about how to scale your application to handle the load. In this tutorial, we'll walk through some strategies and code examples for scal...]]></description><link>https://blog.pranish.dev/scaling-nodejs-applications-to-millions-of-users</link><guid isPermaLink="true">https://blog.pranish.dev/scaling-nodejs-applications-to-millions-of-users</guid><category><![CDATA[Node.js]]></category><category><![CDATA[scalability]]></category><dc:creator><![CDATA[Pranish Poudel]]></dc:creator><pubDate>Tue, 29 Oct 2024 15:04:55 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1730214269552/e02366ea-6273-40ce-ac91-bdf77b2e5a76.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>As your Node.js application grows in popularity and you start to see increasing user traffic, you'll need to think about how to scale your application to handle the load. In this tutorial, we'll walk through some strategies and code examples for scaling a Node.js application to support millions of users.</p>
<h3 id="heading-understanding-the-scalability-challenge">Understanding the Scalability Challenge</h3>
<p>Node.js is known for its efficiency in handling concurrent connections, thanks to its event-driven, non-blocking I/O model. However, as the number of users and requests increases, you may start to encounter performance bottlenecks that need to be addressed.</p>
<p>Some of the key challenges you might face as you scale a Node.js application include:</p>
<ul>
<li><p><strong>CPU Utilization</strong>: Each incoming request is handled by a single thread in the Node.js event loop. If your application performs CPU-intensive tasks, it can quickly max out the available CPU resources.</p>
</li>
<li><p><strong>Memory Leaks</strong>: Improper management of memory in your Node.js application can lead to memory leaks, which can cause your application to crash or become unresponsive as the number of users grows.</p>
</li>
<li><p><strong>Disk I/O</strong>: If your application relies heavily on reading from or writing to the disk, you may encounter I/O bottlenecks as the number of concurrent requests increases.</p>
</li>
<li><p><strong>Database Scaling</strong>: As your user base grows, your database may become a bottleneck if it's not properly scaled to handle the increased load.</p>
</li>
</ul>
<h3 id="heading-strategies-for-scaling-nodejs-applications">Strategies for Scaling Node.js Applications</h3>
<p>Here are some strategies and code examples you can use to scale your Node.js application to handle millions of users:</p>
<ol>
<li><p><strong>Leverage Clustering</strong>:</p>
<pre><code class="lang-javascript"> <span class="hljs-keyword">const</span> cluster = <span class="hljs-built_in">require</span>(<span class="hljs-string">'cluster'</span>);
 <span class="hljs-keyword">const</span> numCPUs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'os'</span>).cpus().length;

 <span class="hljs-keyword">if</span> (cluster.isMaster) {
   <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Master process <span class="hljs-subst">${process.pid}</span> is running`</span>);

   <span class="hljs-comment">// Fork worker processes</span>
   <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; numCPUs; i++) {
     cluster.fork();
   }

   cluster.on(<span class="hljs-string">'exit'</span>, <span class="hljs-function">(<span class="hljs-params">worker, code, signal</span>) =&gt;</span> {
     <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`worker <span class="hljs-subst">${worker.process.pid}</span> died`</span>);
     cluster.fork(); <span class="hljs-comment">// Restart the worker</span>
   });
 } <span class="hljs-keyword">else</span> {
   <span class="hljs-comment">// Worker process code</span>
   <span class="hljs-built_in">require</span>(<span class="hljs-string">'./app.js'</span>);
 }
</code></pre>
<ol start="2">
<li><p><strong>Implement Load Balancing with AWS ECS and Docker</strong>:</p>
<pre><code class="lang-javascript"> <span class="hljs-keyword">const</span> AWS = <span class="hljs-built_in">require</span>(<span class="hljs-string">'aws-sdk'</span>);
 <span class="hljs-keyword">const</span> ecs = <span class="hljs-keyword">new</span> AWS.ECS();

 <span class="hljs-comment">// Define your Node.js application as a Docker container</span>
 <span class="hljs-keyword">const</span> containerDefinition = {
   <span class="hljs-attr">name</span>: <span class="hljs-string">'my-nodejs-app'</span>,
   <span class="hljs-attr">image</span>: <span class="hljs-string">'my-nodejs-app:latest'</span>,
   <span class="hljs-attr">portMappings</span>: [
     {
       <span class="hljs-attr">containerPort</span>: <span class="hljs-number">3000</span>,
       <span class="hljs-attr">hostPort</span>: <span class="hljs-number">3000</span>
     }
   ]
 };

 <span class="hljs-comment">// Create an ECS service to manage the containers</span>
 ecs.createService({
   <span class="hljs-attr">cluster</span>: <span class="hljs-string">'my-ecs-cluster'</span>,
   <span class="hljs-attr">serviceName</span>: <span class="hljs-string">'my-nodejs-app-service'</span>,
   <span class="hljs-attr">taskDefinition</span>: <span class="hljs-string">'my-nodejs-app-task-definition'</span>,
   <span class="hljs-attr">desiredCount</span>: <span class="hljs-number">3</span> <span class="hljs-comment">// Start with 3 containers</span>
 }, <span class="hljs-function">(<span class="hljs-params">err, data</span>) =&gt;</span> {
   <span class="hljs-keyword">if</span> (err) <span class="hljs-built_in">console</span>.error(err);
   <span class="hljs-keyword">else</span> <span class="hljs-built_in">console</span>.log(data);
 });
</code></pre>
<ol start="3">
<li><p><strong>Leverage Redis for Caching</strong>:</p>
<pre><code class="lang-javascript"> <span class="hljs-keyword">const</span> redis = <span class="hljs-built_in">require</span>(<span class="hljs-string">'redis'</span>);
 <span class="hljs-keyword">const</span> client = redis.createClient();

 <span class="hljs-comment">// Store a value in Redis</span>
 client.set(<span class="hljs-string">'mykey'</span>, <span class="hljs-string">'Hello, Redis!'</span>, <span class="hljs-function">(<span class="hljs-params">err</span>) =&gt;</span> {
   <span class="hljs-keyword">if</span> (err) <span class="hljs-built_in">console</span>.error(err);
   <span class="hljs-keyword">else</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Value stored in Redis'</span>);
 });

 <span class="hljs-comment">// Retrieve a value from Redis</span>
 client.get(<span class="hljs-string">'mykey'</span>, <span class="hljs-function">(<span class="hljs-params">err, value</span>) =&gt;</span> {
   <span class="hljs-keyword">if</span> (err) <span class="hljs-built_in">console</span>.error(err);
   <span class="hljs-keyword">else</span> <span class="hljs-built_in">console</span>.log(value); <span class="hljs-comment">// Output: Hello, Redis!</span>
 });
</code></pre>
<ol start="4">
<li><p><strong>Implement Asynchronous Task Processing with RabbitMQ</strong>:</p>
<pre><code class="lang-javascript"> <span class="hljs-keyword">const</span> amqp = <span class="hljs-built_in">require</span>(<span class="hljs-string">'amqplib'</span>);

 <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sendToQueue</span>(<span class="hljs-params">task</span>) </span>{
   <span class="hljs-keyword">const</span> connection = <span class="hljs-keyword">await</span> amqp.connect(<span class="hljs-string">'amqp://rabbitmq'</span>);
   <span class="hljs-keyword">const</span> channel = <span class="hljs-keyword">await</span> connection.createChannel();
   <span class="hljs-keyword">const</span> queue = <span class="hljs-string">'my_queue'</span>;

   channel.assertQueue(queue, {
     <span class="hljs-attr">durable</span>: <span class="hljs-literal">false</span>
   });

   channel.sendToQueue(queue, Buffer.from(<span class="hljs-built_in">JSON</span>.stringify(task)));

   <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Sent task to queue: <span class="hljs-subst">${task.name}</span>`</span>);

   <span class="hljs-keyword">await</span> channel.close();
   <span class="hljs-keyword">await</span> connection.close();
 }

 <span class="hljs-comment">// Example usage</span>
 sendToQueue({ <span class="hljs-attr">name</span>: <span class="hljs-string">'Process image'</span>, <span class="hljs-attr">data</span>: { <span class="hljs-attr">imageUrl</span>: <span class="hljs-string">'https://example.com/image.jpg'</span> } });
</code></pre>
<p> 5.<strong>Utilize Serverless Functions with AWS Lambda</strong>:</p>
<pre><code class="lang-javascript"> <span class="hljs-keyword">const</span> AWS = <span class="hljs-built_in">require</span>(<span class="hljs-string">'aws-sdk'</span>);
 <span class="hljs-keyword">const</span> lambda = <span class="hljs-keyword">new</span> AWS.Lambda();

 <span class="hljs-built_in">exports</span>.handler = <span class="hljs-keyword">async</span> (event) =&gt; {
   <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Received event:'</span>, event);

   <span class="hljs-comment">// Process the event data</span>
   <span class="hljs-keyword">const</span> result = <span class="hljs-keyword">await</span> processData(event.data);

   <span class="hljs-keyword">return</span> {
     <span class="hljs-attr">statusCode</span>: <span class="hljs-number">200</span>,
     <span class="hljs-attr">body</span>: <span class="hljs-built_in">JSON</span>.stringify(result)
   };
 };

 <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">processData</span>(<span class="hljs-params">data</span>) </span>{
   <span class="hljs-comment">// Implement your data processing logic here</span>
   <span class="hljs-keyword">return</span> { <span class="hljs-attr">message</span>: <span class="hljs-string">'Data processed successfully'</span> };
 }
</code></pre>
<p> By implementing these strategies, you can build a highly scalable Node.js application that can handle millions of users without sacrificing performance or stability. Remember, these are just introductory examples, and you may need to adapt them to fit the specific requirements of your application.</p>
</li>
</ol>
</li>
</ol>
</li>
</ol>
</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[Getting Started with Selenium WebDriver Automation in Node.js]]></title><description><![CDATA[Selenium WebDriver is a powerful tool for automating web browser interactions, and when combined with Node.js, it provides a robust framework for web automation. In this guide, we'll walk through setting up and using Selenium WebDriver with Node.js t...]]></description><link>https://blog.pranish.dev/getting-started-with-selenium-webdriver-automation-in-nodejs</link><guid isPermaLink="true">https://blog.pranish.dev/getting-started-with-selenium-webdriver-automation-in-nodejs</guid><category><![CDATA[selenium]]></category><category><![CDATA[automation]]></category><category><![CDATA[Web Automation]]></category><category><![CDATA[Node.js]]></category><dc:creator><![CDATA[Pranish Poudel]]></dc:creator><pubDate>Tue, 29 Oct 2024 14:46:16 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1730213334603/0b32bad1-bb59-4060-99e4-265603dc09dc.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Selenium WebDriver is a powerful tool for automating web browser interactions, and when combined with Node.js, it provides a robust framework for web automation. In this guide, we'll walk through setting up and using Selenium WebDriver with Node.js to create automated browser tests.</p>
<h3 id="heading-prerequisites">Prerequisites</h3>
<p>Before we begin, make sure you have:</p>
<ul>
<li><p>Node.js installed on your system</p>
</li>
<li><p>A code editor (like VS Code)</p>
</li>
<li><p>Chrome browser installed</p>
</li>
<li><p>Basic knowledge of JavaScript</p>
</li>
</ul>
<h3 id="heading-setting-up-your-project">Setting Up Your Project</h3>
<p>First, create a new directory for your project and initialize it:</p>
<pre><code class="lang-bash">mkdir selenium-automation
<span class="hljs-built_in">cd</span> selenium-automation
npm init -y
</code></pre>
<p>Install the required dependencies:</p>
<pre><code class="lang-bash">npm install selenium-webdriver chromedriver
</code></pre>
<h3 id="heading-writing-your-first-automation-script">Writing Your First Automation Script</h3>
<p>Here's a complete example that demonstrates how to automate a Google search:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> { Builder, By, Key, until } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'selenium-webdriver'</span>);
<span class="hljs-keyword">const</span> chrome = <span class="hljs-built_in">require</span>(<span class="hljs-string">'selenium-webdriver/chrome'</span>);

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">runAutomation</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-comment">// Create a new Chrome driver instance</span>
    <span class="hljs-keyword">const</span> driver = <span class="hljs-keyword">await</span> <span class="hljs-keyword">new</span> Builder()
        .forBrowser(<span class="hljs-string">'chrome'</span>)
        .build();

    <span class="hljs-keyword">try</span> {
        <span class="hljs-comment">// Navigate to Google</span>
        <span class="hljs-keyword">await</span> driver.get(<span class="hljs-string">'https://www.google.com'</span>);

        <span class="hljs-comment">// Find the search box and type a query</span>
        <span class="hljs-keyword">const</span> searchBox = <span class="hljs-keyword">await</span> driver.findElement(By.name(<span class="hljs-string">'q'</span>));
        <span class="hljs-keyword">await</span> searchBox.sendKeys(<span class="hljs-string">'Selenium WebDriver'</span>, Key.RETURN);

        <span class="hljs-comment">// Wait for search results to load</span>
        <span class="hljs-keyword">await</span> driver.wait(until.elementLocated(By.css(<span class="hljs-string">'h3'</span>)), <span class="hljs-number">5000</span>);

        <span class="hljs-comment">// Get and print the title of the first result</span>
        <span class="hljs-keyword">const</span> firstResult = <span class="hljs-keyword">await</span> driver.findElement(By.css(<span class="hljs-string">'h3'</span>));
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'First result:'</span>, <span class="hljs-keyword">await</span> firstResult.getText());

    } <span class="hljs-keyword">finally</span> {
        <span class="hljs-comment">// Always close the browser</span>
        <span class="hljs-keyword">await</span> driver.quit();
    }
}

runAutomation().catch(<span class="hljs-built_in">console</span>.error);
</code></pre>
<h3 id="heading-key-concepts-explained">Key Concepts Explained</h3>
<p>1) <strong>WebDriver Setup</strong></p>
<p>The <code>Builder()</code> class creates a new WebDriver instance. You can configure various options like browser type, window size, and more.</p>
<p><strong>2. Locating Elements</strong></p>
<p>Selenium provides multiple ways to locate elements:</p>
<ul>
<li><p><a target="_blank" href="http://By.id"><code>By.id</code></a><code>()</code>: Find element by ID</p>
</li>
<li><p><a target="_blank" href="http://By.name"><code>By.name</code></a><code>()</code>: Find element by name attribute</p>
</li>
<li><p><code>By.css()</code>: Find element using CSS selectors</p>
</li>
<li><p><code>By.xpath()</code>: Find element using XPath</p>
</li>
<li><p><code>By.className()</code>: Find element by class name</p>
</li>
</ul>
<p><strong>3. Waiting Strategies</strong></p>
<p>Always implement proper waits in your automation:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Explicit wait</span>
<span class="hljs-keyword">await</span> driver.wait(until.elementLocated(By.id(<span class="hljs-string">'myElement'</span>)), <span class="hljs-number">5000</span>);

<span class="hljs-comment">// Implicit wait</span>
<span class="hljs-keyword">await</span> driver.manage().setTimeouts({ <span class="hljs-attr">implicit</span>: <span class="hljs-number">5000</span> });
</code></pre>
<p><strong>4. Common Actions</strong></p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Click an element</span>
<span class="hljs-keyword">await</span> element.click();

<span class="hljs-comment">// Type text</span>
<span class="hljs-keyword">await</span> element.sendKeys(<span class="hljs-string">'Hello World'</span>);

<span class="hljs-comment">// Clear input field</span>
<span class="hljs-keyword">await</span> element.clear();

<span class="hljs-comment">// Get text content</span>
<span class="hljs-keyword">const</span> text = <span class="hljs-keyword">await</span> element.getText();

<span class="hljs-comment">// Check if element is displayed</span>
<span class="hljs-keyword">const</span> isVisible = <span class="hljs-keyword">await</span> element.isDisplayed();
</code></pre>
<h3 id="heading-best-practices">Best Practices</h3>
<ul>
<li><p><strong>Always Use Try-Finally Blocks</strong> Ensure your browser sessions are properly closed even if errors occur.</p>
</li>
<li><p><strong>Implement Proper Waits</strong> Don't rely on fixed timeouts with <code>setTimeout</code>. Use explicit or implicit waits.</p>
</li>
<li><p><strong>Use Page Object Model</strong> Organize your code by separating page elements and actions into classes</p>
</li>
</ul>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">LoginPage</span> </span>{
    <span class="hljs-keyword">constructor</span>(driver) {
        <span class="hljs-built_in">this</span>.driver = driver;
        <span class="hljs-built_in">this</span>.usernameInput = By.id(<span class="hljs-string">'username'</span>);
        <span class="hljs-built_in">this</span>.passwordInput = By.id(<span class="hljs-string">'password'</span>);
        <span class="hljs-built_in">this</span>.loginButton = By.css(<span class="hljs-string">'button[type="submit"]'</span>);
    }

    <span class="hljs-keyword">async</span> login(username, password) {
        <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.driver.findElement(<span class="hljs-built_in">this</span>.usernameInput).sendKeys(username);
        <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.driver.findElement(<span class="hljs-built_in">this</span>.passwordInput).sendKeys(password);
        <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.driver.findElement(<span class="hljs-built_in">this</span>.loginButton).click();
    }
}
</code></pre>
<p><strong>Handling Different Browsers</strong></p>
<p>While Chrome is popular, you might need to support multiple browsers:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> firefox = <span class="hljs-built_in">require</span>(<span class="hljs-string">'selenium-webdriver/firefox'</span>);
<span class="hljs-keyword">const</span> edge = <span class="hljs-built_in">require</span>(<span class="hljs-string">'selenium-webdriver/edge'</span>);

<span class="hljs-comment">// Firefox setup</span>
<span class="hljs-keyword">const</span> firefoxDriver = <span class="hljs-keyword">new</span> Builder()
    .forBrowser(<span class="hljs-string">'firefox'</span>)
    .build();

<span class="hljs-comment">// Edge setup</span>
<span class="hljs-keyword">const</span> edgeDriver = <span class="hljs-keyword">new</span> Builder()
    .forBrowser(<span class="hljs-string">'MicrosoftEdge'</span>)
    .build();
</code></pre>
<h3 id="heading-error-handling">Error Handling</h3>
<p>Implement robust error handling in your automation scripts:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">await</span> driver.get(<span class="hljs-string">'https://example.com'</span>);
    <span class="hljs-keyword">await</span> driver.findElement(By.id(<span class="hljs-string">'non-existent'</span>));
} <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-keyword">if</span> (error.name === <span class="hljs-string">'NoSuchElementError'</span>) {
        <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'Element not found:'</span>, error.message);
    } <span class="hljs-keyword">else</span> {
        <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'Unexpected error:'</span>, error);
    }
} <span class="hljs-keyword">finally</span> {
    <span class="hljs-keyword">await</span> driver.quit();
}
</code></pre>
<h3 id="heading-conclusion">Conclusion</h3>
<p>Selenium WebDriver with Node.js provides a powerful platform for web automation. Whether you're writing test scripts or automating repetitive tasks, following these patterns and best practices will help you create maintainable and reliable automation scripts.</p>
<p>Remember to always handle errors properly, implement appropriate waits, and structure your code well. As your automation suite grows, consider implementing a test framework like Mocha or Jest for better organization and reporting.</p>
<p>Happy automating!</p>
]]></content:encoded></item></channel></rss>