<?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[Lois Bassey's Blog]]></title><description><![CDATA[This blog is where I share thoughts, lessons, and practical insights on backend engineering, infrastructure, systems architecture, and the realities of building]]></description><link>https://blog.loisbassey.com</link><generator>RSS for Node</generator><lastBuildDate>Wed, 15 Apr 2026 17:16:28 GMT</lastBuildDate><atom:link href="https://blog.loisbassey.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[IaC Explained: A Beginner's Guide to its Implementation and Advantages]]></title><description><![CDATA[In the past, when you needed to deploy an application to a server, you had to acquire a server, set it up, install all the required software, and configure these programs to prepare the application for execution. In an enterprise environment? This sa...]]></description><link>https://blog.loisbassey.com/iac-explained-a-beginners-guide-to-its-implementation-and-advantages</link><guid isPermaLink="true">https://blog.loisbassey.com/iac-explained-a-beginners-guide-to-its-implementation-and-advantages</guid><category><![CDATA[Infrastructure as code]]></category><category><![CDATA[#InfrastructureAsCode]]></category><category><![CDATA[Devops]]></category><category><![CDATA[Devops articles]]></category><category><![CDATA[automation]]></category><category><![CDATA[#IaC]]></category><category><![CDATA[deployment]]></category><dc:creator><![CDATA[Lois Bassey]]></dc:creator><pubDate>Sun, 25 Feb 2024 03:44:27 GMT</pubDate><content:encoded><![CDATA[<p>In the past, when you needed to deploy an application to a server, you had to acquire a server, set it up, install all the required software, and configure these programs to prepare the application for execution. In an enterprise environment? This same process will involve system administrators manually configuring servers, networks, and storage devices using command-line interfaces and configuration files.</p>
<p>However, in reality, this entire process is quite burdensome. It consumes a significant amount of time and is prone to errors due to human nature. Just think about the effort needed to set up a server from scratch—installing all the necessary software and configuring everything precisely. And that's just the beginning. Maintenance presents its own set of challenges. From backing up databases to addressing crashes and updating software, it's a continuous cycle of tasks. Additionally, managing multiple test environments means repeating this setup process numerous times.</p>
<h3 id="heading-the-need-for-automation-and-standardization"><strong>The Need for Automation and Standardization</strong></h3>
<p>As technology advanced and organizations depended more on digital infrastructure, it became clear that manual setups had limitations. The need for quicker deployment, scalability, and reliability led to the search for automation solutions. These tools aimed to simplify repetitive tasks, maintain consistent configurations, and ease the workload on humans. However, many of these tools lacked a cohesive and adaptable approach, resulting in disjointed solutions and dependency on specific vendors.</p>
<h3 id="heading-enter-infrastructure-as-code-iac"><strong>Enter Infrastructure as Code (IaC)</strong></h3>
<p>The concept of Infrastructure as Code (IaC) emerged as a shift in infrastructure management, drawing inspiration from software development practices. <strong><em>IaC treats infrastructure configurations as code</em></strong>, enabling the automation of infrastructure provisioning, deployment, and management <strong><em>through programmable scripts and configuration files</em></strong>. By representing infrastructure as code, organizations gain the ability to version control, test, and deploy infrastructure changes with the same rigor and agility as software applications.</p>
<p><strong>What is Infrastructure as Code (IaC)?</strong><br /><em>Although touched upon in the previous paragraph, let's define IaC for the sake of clarity</em>. <mark>Infrastructure as Code (IaC) is a methodology that allows infrastructure provisioning and management tasks to be automated through code. In essence, IaC treats infrastructure configurations as software, allowing for the same versioning, testing, and deployment practices used in software development to be applied to infrastructure management.</mark></p>
<p><strong>The Key Components of Infrastructure as Code (IaC):</strong><br />Now that we've established the fundamentals of Infrastructure as Code (IaC), it's time to explore its core components that drive its effectiveness, enabling organizations to automate, streamline, and scale their infrastructure provisioning and management processes. Here are the key components of IaC:</p>
<ol>
<li><p><strong>Infrastructure as Code Templates:</strong> IaC relies on templates or configuration files that describe the desired configuration of infrastructure resources such as servers, networks, storage, and services. These templates are typically written using domain-specific languages (DSLs) or configuration management tools like Terraform, AWS CloudFormation, or Ansible.</p>
</li>
<li><p><strong>Version Control:</strong> Recall from our definition of IaC that Infrastructure as code is treated as software code and so it allows for version controlling. Hence it can be deduced that IaC is stored in version control systems like Git. This enables teams to track changes, collaborate effectively, and rollback to previous versions if needed. Version control ensures that infrastructure changes are documented, auditable, and reproducible.</p>
</li>
<li><p><strong>Automation and Orchestration:</strong> One of the core principles of IaC is automation. Tasks such as infrastructure provisioning, configuration, and management are automated through scripts or configuration files. These tasks are coordinated by orchestration tools to ensure smooth deployment and management of infrastructure resources.</p>
</li>
<li><p><strong>Testing and Validation:</strong> Similar to software development, IaC promotes the use of testing and validation practices. Infrastructure code is subjected to various tests to ensure correctness, reliability, and security. Testing frameworks and tools are used to automate the testing process, including unit tests, integration tests, and validation against compliance standards.</p>
</li>
<li><p><strong>Immutable Infrastructure:</strong> IaC encourages the concept of immutable infrastructure, where infrastructure resources are treated as disposable and are not modified once deployed. <em>Imagine you have a web application running on a server. With immutable infrastructure, instead of making changes directly to that server, you would create a new server with the updated configuration or application version. Once the new server is ready and tested, you would replace the old server with the new one.</em> This ensures that your infrastructure remains consistent and predictable, as each deployment involves creating a fresh instance rather than modifying existing ones.</p>
</li>
<li><p><strong>Continuous Integration and Continuous Deployment (CI/CD):</strong> IaC integrates with CI/CD pipelines to automate the process of building, testing, and deploying infrastructure changes. Continuous integration ensures that changes are integrated into the main codebase frequently, while continuous deployment automates the process of deploying infrastructure changes to production environments.</p>
</li>
<li><p><strong>Declarative Configuration:</strong> In Infrastructure as Code (IaC), a declarative approach is utilized to define infrastructure resources and their configurations in code. This is achieved through the use of high-level configuration languages such as <strong>YAML</strong> or <strong>JSON</strong>, where users specify the desired state of the infrastructure.  </p>
<p> <strong>For example</strong>, in a declarative IaC script written in YAML, a user may specify that they want two virtual machines with specific attributes, such as a certain amount of CPU and memory, and configured with particular software packages. The IaC tool interprets this declarative script and orchestrates the creation of the virtual machines according to the specified attributes and configurations.</p>
<p> This approach simplifies infrastructure management by abstracting away the complexities of implementation details. Users do not need to concern themselves with the intricate steps required to provision each resource; instead, they focus on defining the desired end state. The IaC tool takes care of translating these high-level declarations into actionable provisioning and configuration tasks, ensuring consistency and repeatability in infrastructure deployments.</p>
</li>
</ol>
<h3 id="heading-benefits-of-infrastructure-as-code"><strong>Benefits of Infrastructure as Code</strong></h3>
<p>If you've reached this point in the article, you likely already have some understanding of the benefits of Infrastructure as Code (IaC) in software engineering. However, let's delve into them further and explore additional advantages:</p>
<ol>
<li><p><strong>Automation and Consistency:</strong> IaC eliminates manual intervention in infrastructure provisioning, configuration and management through automation, reducing the likelihood of human errors and ensuring consistency across environments.</p>
</li>
<li><p><strong>Standardization:</strong> IaC promotes standardization and consistency across environments, ensuring that infrastructure configurations are reproducible and maintainable.</p>
</li>
<li><p><strong>Scalability and Agility:</strong> By automating infrastructure provisioning, IaC enables organizations to scale resources up or down rapidly in response to changing demand, thereby enhancing agility and reducing time-to-market for new applications and services.</p>
</li>
<li><p><strong>Reliability:</strong> IaC improves the reliability of infrastructure deployments by enforcing consistent configurations and enabling automated testing and validation.</p>
</li>
<li><p><strong>Cost</strong> <strong>Optimization:</strong> IaC helps optimize infrastructure costs by right-sizing resources, eliminating over-provisioning, and improving resource utilization efficiency.</p>
</li>
</ol>
<p>To sum up, this article has served as a beginner's guide to understanding the evolution and history of IaC, its key components, and its benefits.</p>
<p>Embracing IaC is not only a best practice but also a strategic imperative for organizations seeking to thrive in the era of cloud computing and DevOps. By treating infrastructure as code, you and your team can achieve enhanced agility, consistency, and cost-effectiveness in managing their infrastructure.</p>
<p>Before you go, why not dive deeper into the world of Infrastructure as Code (IaC) with my guide on <strong>Getting Started with Infrastructure as Code</strong>? Learn how to Start by selecting an IaC tool that aligns with your organization's infrastructure requirements and preferences with step-by-step instructions and practical examples.</p>
]]></content:encoded></item><item><title><![CDATA[Secure Ubuntu Server: Step-by-Step Guide to Creating a New User on Digital Ocean]]></title><description><![CDATA[It is not just recommended but crucial to create a new user separate from the default “root” user on provisioning a new Digital Ocean droplet. Why? For security reasons.

Relying solely on the ‘root’ user for remote access is similar to leaving your ...]]></description><link>https://blog.loisbassey.com/secure-ubuntu-server-step-by-step-guide-to-creating-a-new-user-on-digital-ocean</link><guid isPermaLink="true">https://blog.loisbassey.com/secure-ubuntu-server-step-by-step-guide-to-creating-a-new-user-on-digital-ocean</guid><category><![CDATA[DigitalOcean]]></category><category><![CDATA[Ubuntu]]></category><category><![CDATA[cloud server security]]></category><category><![CDATA[user management]]></category><category><![CDATA[ssh]]></category><category><![CDATA[ssh-keys]]></category><category><![CDATA[ssh-keygen]]></category><category><![CDATA[remote access]]></category><category><![CDATA[Linux]]></category><category><![CDATA[#cybersecurity]]></category><category><![CDATA[cybersecurity]]></category><category><![CDATA[server administration]]></category><category><![CDATA[TechHowTo]]></category><dc:creator><![CDATA[Lois Bassey]]></dc:creator><pubDate>Tue, 28 Nov 2023 18:14:49 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/xEy9QNUCdRI/upload/5a5299c857c954bfd400dde4b4ac5e3f.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>It is not just recommended but <strong>crucial</strong> to create a new user separate from the default “root” user on provisioning a new Digital Ocean droplet. Why? <strong>For security reasons</strong>.</p>
<blockquote>
<p>Relying solely on the ‘<strong>root</strong>’ user for remote access is similar to leaving your front door wide open for anyone with malicious intent. That’s why creating a separate user account, armed with administrative privileges, is not just recommended — it’s a crucial step toward fortifying your server’s defenses.”</p>
</blockquote>
<p>Now that we’ve established the significance of creating a new user for your Digital Ocean droplet, let’s walk through the process of creating a new user with administrative rights on your Ubuntu-based Digital Ocean droplet.</p>
<h3 id="heading-step-one-accessing-your-digital-ocean-droplet"><strong>Step One: Accessing Your Digital Ocean Droplet</strong></h3>
<p>To begin, log in to your Digital Ocean account and navigate to the Droplets section. Locate the specific droplet to which you want to add a new user. Once you’ve selected the droplet, click on the ‘Access’ option on the left-hand side of the page. Then, proceed by clicking the ‘Launch Droplet Console’ button.”</p>
<p><img src="https://cdn-images-1.medium.com/max/1600/1*S_bZYZxsawIBY9TgvA9WJA.png" alt /></p>
<p>After clicking the ‘Launch Droplet Console’ button, a terminal will open up in another tab in your browser window, successfully logging you into your terminal as a root user. From here, you’ll proceed with the necessary commands to create a new user with administrative privileges.</p>
<h3 id="heading-step-two-running-terminal-commands"><strong>Step Two: Running Terminal Commands</strong></h3>
<p>Next, execute the following command in the terminal:</p>
<pre><code class="lang-bash">sudo adduser username
</code></pre>
<p>Replace “username” with the desired name for the new user. This command will prompt you to set a password for the new user and enter additional information if needed.</p>
<h3 id="heading-step-three-verifying-the-successful-creation-of-the-user"><strong>Step Three: Verifying the Successful Creation of the User</strong></h3>
<p>To verify the successful creation of this new user, run the command</p>
<pre><code class="lang-bash">cat /etc/passwd
</code></pre>
<p>This command will output the contents of the <code>/etc/passwd</code> file, which includes a list of users along with their basic information. Scan the output for the user you just created. Look for an entry containing the username you specified during the user creation process.</p>
<h3 id="heading-understanding-the-adduser-command"><strong>Understanding the adduser Command</strong></h3>
<p>Now that you've executed the <code>sudo adduser username</code> command to create a new user, let's take a moment to delve into what exactly happens behind the scenes when the <code>adduser</code> command is run. Here's a breakdown of what it does:</p>
<ol>
<li><p><strong>Creation Of Home Directory + .ssh Directory:</strong></p>
<p> The home directory is established in <code>/home/username</code>, while the <code>.ssh</code> directory resides within <code>/home/username/.ssh</code>.</p>
</li>
<li><p><strong>Creation Of An Authorised Keys File:</strong></p>
<p> An important component for SSH authentication, the authorized keys file is located at <code>/home/username/.ssh/authorized_keys</code>.</p>
</li>
<li><p><strong>User Creation + Setting Of Home Directory For User:</strong></p>
<p> The user is created, and their home directory is set to <code>/home/username</code>. This means that upon logging in, the user is directed to the <code>/home/username</code> directory.</p>
</li>
<li><p><strong>Password For User:</strong></p>
<p> The command also facilitates the setting of a password for the user. While SSH key authentication is preferred, setting a password provides an alternative method. Please note that enabling <code>PasswordAuthentication</code> in <code>/etc/ssh/sshd_config</code> is required for this to function, although it's not the recommended practice for security reasons.</p>
</li>
<li><p><strong>Readable and Executable Permissions:</strong></p>
<p> Ownership of the home directory is assigned to the new user. Additionally, permissions for the <code>.ssh</code> directory and <code>.ssh/authorized_keys</code> file are updated to ensure readability and executability.</p>
</li>
</ol>
<p>Now, let's return to the practical steps to verify the successful creation of your new user.</p>
<h3 id="heading-step-four-accessing-the-new-user-terminal-via-digital-oceans-droplet-ui"><strong>Step Four: Accessing the New User Terminal Via Digital Ocean's Droplet UI</strong></h3>
<p>To access the new user, navigate to the access panel on the droplet, and input the username of the newly created user in place of "<strong>root</strong>". Then, clicking on the 'Launch Droplet' button as before. This time, you'll access the console not as the root user but as the newly created user. Once again, to verify the successful creation of the home directory + .ssh directory for new user, run the following commands in the console:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">echo</span> <span class="hljs-variable">$HOME</span>
</code></pre>
<p>This above command checks the user's home directory and outputs it as a text in the format <code>/home/username</code>.</p>
<pre><code class="lang-bash"><span class="hljs-built_in">echo</span> <span class="hljs-variable">$PWD</span>
</code></pre>
<p>This command outputs the current path to the directory you’re currently in, which should be <code>/home</code>.</p>
<h3 id="heading-step-five-generating-ssh-keys-for-new-users-remote-access-of-droplet"><strong>Step Five: Generating SSH keys For New User's Remote Access Of Droplet</strong></h3>
<p>Open a terminal on your local machine and run:</p>
<pre><code class="lang-bash">ssh-keygen -t rsa -b 4096 -C <span class="hljs-string">"your_email@example.com"</span>
</code></pre>
<p>Replace <code>"</code><a target="_blank" href="mailto:your_email@example.com"><code>your_email@example.com</code></a><code>"</code> with your email address. This command will create an RSA key pair by default (<code>id_rsa</code> for the private key and <code>id_</code><a target="_blank" href="http://rsa.pub"><code>rsa.pub</code></a> for the public key) in the <code>~/.ssh/</code> directory. So make sure to use an appropriate name if you do not want it to default to id_rsa as the key names.</p>
<h3 id="heading-step-six-manually-copy-public-key"><strong>Step Six: Manually Copy Public Key</strong></h3>
<p>On your local machine:</p>
<pre><code class="lang-bash">cat ssh-key-name.pub
</code></pre>
<p>Replace <code>ssh-key-name</code> with the actual name of the SSH you created for the new user. This command will display the content of <code>ssh-key-name.pub</code> in your terminal. Next, copy the contents using Ctrl + C.</p>
<h3 id="heading-step-seven-edit-the-new-users-authorizedkeys-file-using-vim"><strong>Step Seven: Edit The New User's</strong> <code>authorized_keys</code> <strong>File Using Vim</strong></h3>
<p>Return to the droplet's console, ensure you're logged in as the new user. Then use the Vim editor to open the <code>authorized_keys</code> file:</p>
<pre><code class="lang-bash">vim ~/.ssh/authorized_keys
</code></pre>
<p>After the <code>authorized_keys</code> file is opened, press <code>i</code> to enter insert mode in <code>vim</code>. Next, press Ctrl + V in the terminal to paste the contents you copied from the <code>cat ssh-key-name.pub</code> command on your local machine. This will insert the public key into the file.</p>
<h3 id="heading-step-eight-save-and-exit-vim-for-new-user"><strong>Step Eight: Save And Exit Vim For New User</strong></h3>
<p>Finally, after pasting the content, press <code>Esc</code> to exit insert mode in vim. Then type <code>:wq</code> and press <code>Enter</code> to save the changes and exit vim.</p>
<h3 id="heading-step-nine-check-new-users-ssh-directory-and-file-permissions"><strong>Step Nine: Check New User's SSH Directory And File Permissions</strong></h3>
<p>The <code>.ssh</code> directory should have permissions set to 700 (<code>drwx------</code>) and the <code>authorized_keys</code> file should have permissions set to 600 (<code>-rw-------</code>). Incorrect permissions might prevent SSH from using the keys.</p>
<p>To set appropriate permissions, run the following command:</p>
<pre><code class="lang-bash">chmod 700 ~/.ssh 
chmod 600 ~/.ssh/authorized_keys
</code></pre>
<h3 id="heading-step-ten-logging-in-via-ssh-as-new-user"><strong>Step Ten: Logging In Via SSH As New User</strong></h3>
<p>Up to this point, we have been remotely accessing the droplet using Digital Ocean's UI, now let's switch to using SSH to access the droplet remotely as the new user.</p>
<p>To log in using SSH with the new user's credentials, execute the following command in your terminal:</p>
<pre><code class="lang-bash">ssh username@server_ip
</code></pre>
<p>Replace <code>username</code> with the actual username you want to log in with and <code>server_ip</code> with the IP address or domain name of the server you are trying to access. This command assumes that you are using the default <code>id_rsa</code> key and will look for this key on your local machine.</p>
<p>If you're using a specific private key for authentication (not the default <code>id_rsa</code>), you can specify the key explicitly in your SSH command:</p>
<pre><code class="lang-bash">ssh -i /path/to/private_key username@server_ip
</code></pre>
<p>Replace <code>/path/to/private_key</code> with the actual path to your private key file. After running this command, you'll be prompted to enter the passphrase associated with the SSH key created for the user. Simply paste the passphrase into the terminal when prompted, and upon successful authentication, you should be logged in.</p>
<blockquote>
<p>In wrapping up, creating a new user on your Digital Ocean droplet is a fundamental step in fortifying security and managing remote access effectively. By following these steps I've outlined, you will be securing your droplet's defences for remote access while prioritising security.</p>
</blockquote>
<p><strong>If you found this article insightful or helpful, please do not forget to show your support! Please like, share, and comment on this article to spread it further. 💜</strong></p>
]]></content:encoded></item><item><title><![CDATA[Setup A React Application Using CPanel]]></title><description><![CDATA[One of the hardest website hosting control panels to use in hosting static web applications like a react app is CPanel, the reason is that by default CPanel is not built for handling static web applications. On the other hand, if you plan on hosting ...]]></description><link>https://blog.loisbassey.com/setup-a-react-application-using-cpanel</link><guid isPermaLink="true">https://blog.loisbassey.com/setup-a-react-application-using-cpanel</guid><category><![CDATA[Devops]]></category><category><![CDATA[cpanel]]></category><category><![CDATA[namecheap]]></category><category><![CDATA[React]]></category><category><![CDATA[serverless]]></category><dc:creator><![CDATA[Lois Bassey]]></dc:creator><pubDate>Sat, 16 Sep 2023 03:32:46 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/52774f07c660e6655fd17df20c7b19b5.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>One of the hardest website hosting control panels to use in hosting static web applications like a react app is CPanel, the reason is that by default CPanel is not built for handling static web applications. On the other hand, if you plan on hosting PHP/Laravel applications? CPanel is your cheapest option to work with!</p>
<p>Recently, I had to host a react application created by my team on CPanel and eventually after scouring the net for hours plus various trials and errors, I finally came upon a solution. This solution is one I'm sure will be very helpful to you if you face this same issue. Without further ado, let us dive in!</p>
<h3 id="heading-steps"><strong>Steps</strong></h3>
<ol>
<li><p>Get a flexible CPanel hosting plan.</p>
</li>
<li><p>Install nodejs and npm.</p>
</li>
<li><p>Create a subdomain to host your react application.</p>
</li>
<li><p>Serve the react application via your CPanel's terminal.</p>
</li>
<li><p>Create or update the Nginx server block for the subdomain you created so it targets the URL generated on serving the react application.</p>
</li>
</ol>
<hr />
<h3 id="heading-get-a-flexible-cpanel-hosting-plan"><strong>Get a flexible CPanel hosting plan</strong></h3>
<p>As an example, I will make use of Namecheap's hosting service. Of course, you can make use of any hosting service provider that enables you to have a flexible CPanel hosting plan.</p>
<h3 id="heading-1-get-a-virtual-private-server"><strong>1. Get A Virtual Private Server</strong></h3>
<p>Honestly, if you are using CPanel, the best hosting you can get that gives you enough flexibility to tweak and change things on your server is the VPS option. The shared hosting option is limiting in so many ways and I won't recommend that. A few dollars extra and you can have a VPS that enables you to work as you want.</p>
<blockquote>
<p>Please note that to run this application, <strong>YOU</strong> <strong>MUST</strong> get a VPS or a similar CPanel hosting service that gives you <strong>root server</strong> and <strong>terminal access</strong>.</p>
</blockquote>
<hr />
<h3 id="heading-install-nodejs-and-npm"><strong>Install Nodejs and Npm</strong></h3>
<p>To install Node.js and npm using NVM on your CentOS system, follow these steps:</p>
<h3 id="heading-1-install-nvm-node-version-manager"><strong>1. Install NVM (Node Version Manager)</strong></h3>
<p>To download the <code>nvm</code> install script run the following command:</p>
<pre><code class="lang-makefile">curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash
</code></pre>
<p>The script will clone the nvm repository from Github to <code>~/.nvm</code> and add the script Path to your Bash or ZSH profile. The output of the curl command is referenced below:</p>
<pre><code class="lang-makefile">=&gt; Close and reopen your terminal to start using nvm or run the following to use it now:

<span class="hljs-keyword">export</span> NVM_DIR=<span class="hljs-string">"$HOME/.nvm"</span>
[ -s <span class="hljs-string">"$NVM_DIR/nvm.sh"</span> ] &amp;&amp; \. <span class="hljs-string">"$NVM_DIR/nvm.sh"</span>  <span class="hljs-comment"># This loads nvm</span>
[ -s <span class="hljs-string">"$NVM_DIR/bash_completion"</span> ] &amp;&amp; \. <span class="hljs-string">"$NVM_DIR/bash_completion"</span>  <span class="hljs-comment"># This loads nvm bash_completion</span>
</code></pre>
<p>Close and reopen your terminal and verify that nvm was properly installed by running the command:</p>
<pre><code class="lang-bash">nvm --version
</code></pre>
<h3 id="heading-2-install-nodejs-using-nvm"><strong>2. Install Node.js using NVM</strong></h3>
<p>Now that the <code>nvm</code> tool is installed we can install the latest available version of Node.js, by typing:</p>
<pre><code class="lang-bash">nvm install 16
</code></pre>
<p>Verify the Node.js and npm version, by typing:</p>
<pre><code class="lang-bash">node -v
npm -v
</code></pre>
<hr />
<h3 id="heading-serve-the-react-application-via-your-cpanels-terminal"><strong>Serve the react application via your CPanel's terminal</strong></h3>
<p>To do this, perform the following steps:</p>
<h3 id="heading-1-serve-the-application"><strong>1. Serve the application</strong></h3>
<p>Using the terminal application on your server, navigate to the folder(<strong>subdomain</strong>) containing your react app and run the command:</p>
<pre><code class="lang-bash">npm run start
</code></pre>
<h3 id="heading-2-verify-that-the-application-is-running"><strong>2. Verify that the application is running</strong></h3>
<p>Next, you need to verify that the application is running in the desired port, by default react apps are served on port <strong>3000</strong>.</p>
<pre><code class="lang-bash">netstat -tulpn | grep LISTEN
</code></pre>
<p>The output should look this way</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672784799246/1810a952-743b-4d21-a3ae-d27c285ce747.png" alt class="image--center mx-auto" /></p>
<p>To keep the application running, install <strong>pm2</strong> for keeping an application alive.</p>
<pre><code class="lang-bash">npm i -g pm2
</code></pre>
<p>Next, serve the application so it keeps running even after closing the terminal:</p>
<pre><code class="lang-bash">pm2 start node_modules/react-scripts/scripts/start.js --name <span class="hljs-string">"your-project-name"</span>
</code></pre>
<p>Update Nginx</p>
<pre><code class="lang-bash">server {
    index index.html index.htm index.nginx-debian.html;

    <span class="hljs-comment">#set $CPANEL_APACHE_PROXY_PASS $scheme://apache_backend_${scheme}_18x_19x_2i_14b;</span>

    <span class="hljs-built_in">set</span> <span class="hljs-variable">$CPANEL_APACHE_PROXY_PASS</span> http://0.0.0.0:3000;

    location / {
        proxy_pass <span class="hljs-variable">$CPANEL_APACHE_PROXY_PASS</span>;
        proxy_buffering off;
        proxy_buffer_size 16k;
        proxy_busy_buffers_size 24k;
        proxy_buffers 64 4k;
     }
 }
</code></pre>
<p>Reload Nginx after making the update</p>
<h3 id="heading-possible-errors-you-might-face"><strong>Possible Errors You Might Face</strong></h3>
<ol>
<li><p><code>/usr/bin/env node permission denied</code><br /> This error comes up on starting the react application <code>npm run start</code> . To fix it, do the following:</p>
<ol>
<li><p>Run the command: <code>npm install -g npm@9.2.0</code></p>
</li>
<li><p>Run the command to start the application. (The error should be gone)</p>
</li>
</ol>
</li>
<li><p><strong>Nginx reverse proxy gives "502 Bad Gateway"</strong><br /> On my end, I had this error and the solution was to tune <code>proxy_buffer_size</code> this way:</p>
<pre><code class="lang-bash"> proxy_buffering off;
 proxy_buffer_size 16k;
 proxy_busy_buffers_size 24k;
 proxy_buffers 64 4k;
</code></pre>
<pre><code class="lang-bash"> sudo tail -n 100 /var/<span class="hljs-built_in">log</span>/nginx/error.log
</code></pre>
</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[Macbook Pro M1 fix -Service 'mysql' failed to build : no matching manifest for linux/arm64/v8 in the manifest list entries]]></title><description><![CDATA[The newest Apple Silicon M1 chips are not compatible with some Docker images and end up throwing: no matching manifest for linux/arm64/v8 in the manifest list entries
To fix this error, run the following:
export DOCKER_BUILDKIT=0
export COMPOSE_DOCKE...]]></description><link>https://blog.loisbassey.com/macbook-pro-m1-fix-service-mysql-failed-to-build-no-matching-manifest-for-linuxarm64v8-in-the-manifest-list-entries</link><guid isPermaLink="true">https://blog.loisbassey.com/macbook-pro-m1-fix-service-mysql-failed-to-build-no-matching-manifest-for-linuxarm64v8-in-the-manifest-list-entries</guid><category><![CDATA[macbook]]></category><category><![CDATA[Linux]]></category><category><![CDATA[Docker]]></category><dc:creator><![CDATA[Lois Bassey]]></dc:creator><pubDate>Fri, 03 Jun 2022 00:35:06 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/unsplash/Im7lZjxeLhg/upload/v1654216330615/9dOrs2dGs.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The newest Apple Silicon M1 chips are not compatible with some Docker images and end up throwing: <code>no matching manifest for linux/arm64/v8 in the manifest list entries</code></p>
<p>To fix this error, run the following:</p>
<pre><code><span class="hljs-built_in">export</span> DOCKER_BUILDKIT=0
<span class="hljs-built_in">export</span> COMPOSE_DOCKER_CLI_BUILD=0
</code></pre><pre><code>docker pull <span class="hljs-operator">-</span><span class="hljs-operator">-</span>platform linux<span class="hljs-operator">/</span>x86_64 mysql
</code></pre><p>After which you run your previous command that threw the above error in the first place.😃</p>
]]></content:encoded></item></channel></rss>