<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Linux on MangoDriod</title><link>https://md.eknath.dev/tags/linux/</link><description>Recent content in Linux on MangoDriod</description><generator>Hugo -- 0.141.0</generator><language>en-us</language><lastBuildDate>Sat, 13 Sep 2025 12:00:00 +0530</lastBuildDate><atom:link href="https://md.eknath.dev/tags/linux/index.xml" rel="self" type="application/rss+xml"/><item><title>Introduction to Nginx: Hosting Your First Website</title><link>https://md.eknath.dev/posts/software-development/introduction-to-nginx/</link><pubDate>Sat, 13 Sep 2025 12:00:00 +0530</pubDate><guid>https://md.eknath.dev/posts/software-development/introduction-to-nginx/</guid><description>&lt;p>So you have a server, and now you want to share your project with the world. To do that, you need a web server. Nginx (pronounced &amp;ldquo;Engine-X&amp;rdquo;) is one of the most popular, powerful, and efficient web servers available. It&amp;rsquo;s famous for its high performance and its ability to also act as a reverse proxy, but at its core, it&amp;rsquo;s brilliant at serving web pages.&lt;/p>
&lt;p>This guide will walk you through the basics of Nginx, explaining its structure and showing you how to set up your very first website.&lt;/p></description><content:encoded><![CDATA[<p>So you have a server, and now you want to share your project with the world. To do that, you need a web server. Nginx (pronounced &ldquo;Engine-X&rdquo;) is one of the most popular, powerful, and efficient web servers available. It&rsquo;s famous for its high performance and its ability to also act as a reverse proxy, but at its core, it&rsquo;s brilliant at serving web pages.</p>
<p>This guide will walk you through the basics of Nginx, explaining its structure and showing you how to set up your very first website.</p>
<h2 id="1-installation">1. Installation</h2>
<p>If you haven&rsquo;t already, you can install Nginx on any Debian-based system (like Ubuntu) with a single command. It&rsquo;s also good practice to ensure your firewall allows web traffic.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Install Nginx</span>
</span></span><span style="display:flex;"><span>sudo apt update
</span></span><span style="display:flex;"><span>sudo apt install nginx -y
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Allow Nginx through the firewall</span>
</span></span><span style="display:flex;"><span>sudo ufw allow <span style="color:#e6db74">&#39;Nginx Full&#39;</span>
</span></span></code></pre></div><p>To check that it&rsquo;s running, you can use <code>systemctl</code>:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo systemctl status nginx
</span></span></code></pre></div><p>If it&rsquo;s active, you can visit your server&rsquo;s IP address in a web browser, and you should see the default &ldquo;Welcome to Nginx!&rdquo; page.</p>
<h2 id="2-understanding-the-nginx-directory-structure">2. Understanding the Nginx Directory Structure</h2>
<p>Nginx&rsquo;s configuration can seem intimidating, but it&rsquo;s very logical. All the important files live in <code>/etc/nginx/</code>.</p>
<ul>
<li><code>/etc/nginx/nginx.conf</code>: The main configuration file. You will rarely need to edit this file directly.</li>
<li><code>/etc/nginx/sites-available/</code>: This is where you will store the configuration files for each of your websites. Think of it as a library of all possible sites you <em>could</em> host.</li>
<li><code>/etc/nginx/sites-enabled/</code>: This directory contains symbolic links (shortcuts) to the files in <code>sites-available</code>. Nginx only reads the configurations in this <code>sites-enabled</code> directory. This setup allows you to easily turn websites on and off without deleting their configuration.</li>
</ul>
<h2 id="3-setting-up-your-first-site-a-server-block">3. Setting Up Your First Site (A Server Block)</h2>
<p>Let&rsquo;s host a website for a domain you own, <code>your-domain.com</code>. First, ensure you have pointed your domain to your server&rsquo;s IP address using an <code>A</code> record at your domain registrar.</p>
<h3 id="step-1-create-a-home-for-your-website">Step 1: Create a Home for Your Website</h3>
<p>It&rsquo;s standard practice to store website files in the <code>/var/www/</code> directory.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Create a directory for your domain</span>
</span></span><span style="display:flex;"><span>sudo mkdir -p /var/www/your-domain.com/html
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Assign ownership to your current user so you can edit files easily</span>
</span></span><span style="display:flex;"><span>sudo chown -R $USER:$USER /var/www/your-domain.com/html
</span></span></code></pre></div><h3 id="step-2-create-a-sample-page">Step 2: Create a Sample Page</h3>
<p>Let&rsquo;s create a simple <code>index.html</code> file for Nginx to serve.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>echo <span style="color:#e6db74">&#34;&lt;h1&gt;Success! The your-domain.com server block is working!&lt;/h1&gt;&#34;</span> &gt; /var/www/your-domain.com/html/index.html
</span></span></code></pre></div><h3 id="step-3-create-the-nginx-configuration-file">Step 3: Create the Nginx Configuration File</h3>
<p>Nginx calls the configuration for a single site a &ldquo;server block&rdquo;. We will create a new file in <code>sites-available</code> for our domain.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo nano /etc/nginx/sites-available/your-domain.com
</span></span></code></pre></div><p>Paste in the following configuration. Each line is explained by the comments.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#75715e"># This defines a server
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">server</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Listen on port 80 (standard HTTP) for both IPv4 and IPv6
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>    <span style="color:#f92672">listen</span> <span style="color:#ae81ff">80</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">listen</span> <span style="color:#e6db74">[::]:80</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># The root directory where the website files are stored
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>    <span style="color:#f92672">root</span> <span style="color:#e6db74">/var/www/your-domain.com/html</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># The order of files to look for when a request comes in
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>    <span style="color:#f92672">index</span> <span style="color:#e6db74">index.html</span> <span style="color:#e6db74">index.htm</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># The domain names this server block should respond to
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>    <span style="color:#f92672">server_name</span> <span style="color:#e6db74">your-domain.com</span> <span style="color:#e6db74">www.your-domain.com</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># This block handles how to find files
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>    <span style="color:#f92672">location</span> <span style="color:#e6db74">/</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#75715e"># Try to serve the requested file, then a directory, or else show a 404 error
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#f92672">try_files</span> $uri $uri/ =<span style="color:#ae81ff">404</span>;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><h3 id="step-4-enable-your-site">Step 4: Enable Your Site</h3>
<p>Now, we need to tell Nginx to actually use this configuration. We do this by creating a symbolic link to the file in the <code>sites-enabled</code> directory.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo ln -s /etc/nginx/sites-available/your-domain.com /etc/nginx/sites-enabled/
</span></span></code></pre></div><h3 id="step-5-test-and-restart-nginx">Step 5: Test and Restart Nginx</h3>
<p>It&rsquo;s very important to test your configuration file for syntax errors before restarting Nginx.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo nginx -t
</span></span></code></pre></div><p>If you see <code>syntax is ok</code> and <code>test is successful</code>, you are good to go. Restart Nginx to apply the changes.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo systemctl restart nginx
</span></span></code></pre></div><p>That&rsquo;s it! If you now visit <code>http://your-domain.com</code> in your browser, you will see your &ldquo;Success!&rdquo; message instead of the default Nginx welcome page.</p>
<h2 id="4-whats-next">4. What&rsquo;s Next?</h2>
<p>You have successfully configured Nginx to host a basic website. This is the foundation for hosting any web project. From here, you can:</p>
<ul>
<li><strong>Host multiple websites</strong> on the same server by creating a new directory and a new server block file for each domain.</li>
<li><strong>Set up a reverse proxy</strong> to pass traffic to applications running on different ports (like Node.js or Python apps).</li>
<li><strong>Secure your sites with SSL/TLS</strong> using a free tool like Certbot to enable HTTPS.</li>
</ul>
<p>These more advanced topics are covered in our &ldquo;Advanced VPS Guide: Mastering Nginx, Subdomains, and Reverse Proxies&rdquo;.</p>
]]></content:encoded></item><item><title>A Beginner's Guide to Your First Hour on a Linux VPS</title><link>https://md.eknath.dev/posts/software-development/beginners-guide-to-vps-setup/</link><pubDate>Sat, 13 Sep 2025 11:00:00 +0530</pubDate><guid>https://md.eknath.dev/posts/software-development/beginners-guide-to-vps-setup/</guid><description>&lt;p>Congratulations on your new Virtual Private Server (VPS)! This is your own private space on the internet, a blank canvas ready for your projects. That freedom can also be a bit intimidating. What should you do first?&lt;/p>
&lt;p>This guide is designed for the absolute beginner. We will walk through the first essential steps to secure your server, get it ready for projects, and host your first website securely with Nginx and a free SSL certificate.&lt;/p></description><content:encoded><![CDATA[<p>Congratulations on your new Virtual Private Server (VPS)! This is your own private space on the internet, a blank canvas ready for your projects. That freedom can also be a bit intimidating. What should you do first?</p>
<p>This guide is designed for the absolute beginner. We will walk through the first essential steps to secure your server, get it ready for projects, and host your first website securely with Nginx and a free SSL certificate.</p>
<h2 id="1-your-first-login-the-root-user">1. Your First Login: The Root User</h2>
<p>Your hosting provider will give you an IP address (e.g., <code>123.45.67.89</code>) and a password for the <code>root</code> user. The <code>root</code> user is the super-administrator with unlimited power. It&rsquo;s powerful, but also risky to use for everyday tasks.</p>
<h3 id="step-1-connect-to-the-server">Step 1: Connect to the Server</h3>
<p>Open a terminal on your computer and connect to your server using the <code>ssh</code> command.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>ssh root@YOUR_SERVER_IP
</span></span></code></pre></div><h3 id="step-2-change-the-root-password">Step 2: Change the Root Password</h3>
<p>If your provider gave you a temporary password, your first action should be to change it to something strong and unique.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>passwd
</span></span></code></pre></div><h2 id="2-create-your-own-user-account">2. Create Your Own User Account</h2>
<p>This is the single most important security step. We will create a standard user account and give it administrative privileges using the <code>sudo</code> command.</p>
<h3 id="step-1-create-the-new-user">Step 1: Create the New User</h3>
<p>Replace <code>devuser</code> with a username you like.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>adduser devuser
</span></span></code></pre></div><h3 id="step-2-grant-administrative-privileges">Step 2: Grant Administrative Privileges</h3>
<p>Add your new user to the <code>sudo</code> group, which allows it to run commands as the administrator.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>usermod -aG sudo devuser
</span></span></code></pre></div><h3 id="step-3-log-in-as-your-new-user">Step 3: Log in as Your New User</h3>
<p>Log out of the root account (<code>exit</code>) and log back in with your new credentials.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>ssh devuser@YOUR_SERVER_IP
</span></span></code></pre></div><p>From now on, you should <strong>always</strong> log in with this user.</p>
<h2 id="3-update-system-and-install-essential-tools">3. Update System and Install Essential Tools</h2>
<p>Now that you are logged in as your new <code>sudo</code> user, the first actions are to update the server and install some essential tools.</p>
<h3 id="step-1-update-the-system">Step 1: Update the System</h3>
<p>This command downloads the latest list of available software (<code>update</code>) and then installs those updates (<code>upgrade</code>).</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo apt update <span style="color:#f92672">&amp;&amp;</span> sudo apt upgrade -y
</span></span></code></pre></div><h3 id="step-2-install-basic-tools">Step 2: Install Basic Tools</h3>
<p>Next, install a few common and useful tools.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo apt install curl git vim htop unzip nginx -y
</span></span></code></pre></div><p>We include <strong>Nginx</strong> here as it is a lightweight, high-performance web server we will configure later.</p>
<h2 id="4-set-your-timezone">4. Set Your Timezone</h2>
<p>Correct server time is important for logs and many applications. Find your timezone from the list and set it.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Find your timezone (press &#39;q&#39; to quit the list)</span>
</span></span><span style="display:flex;"><span>timedatectl list-timezones
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Set your timezone (replace with your own)</span>
</span></span><span style="display:flex;"><span>sudo timedatectl set-timezone Asia/Kolkata
</span></span></code></pre></div><h2 id="5-basic-firewall-setup">5. Basic Firewall Setup</h2>
<p>A firewall is a digital security guard. We will use <code>ufw</code> (Uncomplicated Firewall) to block unwanted traffic.</p>
<h3 id="step-1-allow-essential-traffic">Step 1: Allow Essential Traffic</h3>
<p><strong>This is critical:</strong> You must allow SSH traffic, otherwise the firewall will lock you out. We will also allow Nginx traffic.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo ufw allow OpenSSH
</span></span><span style="display:flex;"><span>sudo ufw allow <span style="color:#e6db74">&#39;Nginx Full&#39;</span>
</span></span></code></pre></div><p>&lsquo;Nginx Full&rsquo; allows traffic on both HTTP (port 80) and HTTPS (port 443).</p>
<h3 id="step-2-enable-the-firewall">Step 2: Enable the Firewall</h3>
<p>Now, turn the firewall on.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo ufw enable
</span></span></code></pre></div><h2 id="6-host-a-website-with-nginx">6. Host a Website with Nginx</h2>
<p>Now we will configure Nginx to serve a website for a domain you own.</p>
<h3 id="step-0-point-your-domain-to-the-server-dns">Step 0: Point Your Domain to the Server (DNS)</h3>
<p>Before Nginx can work, you have to tell the internet that your domain should point to your server&rsquo;s IP address. You do this at your <strong>domain registrar</strong> (the company where you bought your domain, like GoDaddy, Namecheap, Google Domains, etc.).</p>
<ol>
<li>Log in to your domain registrar&rsquo;s website.</li>
<li>Find the DNS management page for your domain.</li>
<li>You need to create two <strong>&lsquo;A&rsquo; records</strong>:
<ul>
<li><strong>Record 1 (Root Domain):</strong>
<ul>
<li><strong>Type:</strong> <code>A</code></li>
<li><strong>Host/Name:</strong> <code>@</code> (this symbol represents the root domain itself)</li>
<li><strong>Value/Points to:</strong> Your server&rsquo;s IP address (e.g., <code>123.45.67.89</code>)</li>
<li><strong>TTL (Time to Live):</strong> Leave as default (often 1 hour).</li>
</ul>
</li>
<li><strong>Record 2 (www subdomain):</strong>
<ul>
<li><strong>Type:</strong> <code>A</code></li>
<li><strong>Host/Name:</strong> <code>www</code></li>
<li><strong>Value/Points to:</strong> Your server&rsquo;s IP address (the same one)</li>
<li><strong>TTL:</strong> Leave as default.</li>
</ul>
</li>
</ul>
</li>
</ol>
<p>DNS changes can take anywhere from a few minutes to a few hours to update across the internet.</p>
<h3 id="step-1-create-a-directory-for-your-site">Step 1: Create a Directory for Your Site</h3>
<p>We&rsquo;ll store our website&rsquo;s files in the <code>/var/www</code> directory.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Create a directory for your domain</span>
</span></span><span style="display:flex;"><span>sudo mkdir -p /var/www/your-domain.com/html
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Assign ownership to your user</span>
</span></span><span style="display:flex;"><span>sudo chown -R $USER:$USER /var/www/your-domain.com/html
</span></span></code></pre></div><h3 id="step-2-create-a-sample-page">Step 2: Create a Sample Page</h3>
<p>Let&rsquo;s create a simple <code>index.html</code> file for testing.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>echo <span style="color:#e6db74">&#34;&lt;h1&gt;Hello from my Nginx Site!&lt;/h1&gt;&#34;</span> | sudo tee /var/www/your-domain.com/html/index.html
</span></span></code></pre></div><h3 id="step-3-create-an-nginx-server-block">Step 3: Create an Nginx Server Block</h3>
<p>Nginx uses &ldquo;server block&rdquo; files to know how to handle incoming domains. We&rsquo;ll create one for our domain.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo nano /etc/nginx/sites-available/your-domain.com
</span></span></code></pre></div><p>Paste the following configuration into the file:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#66d9ef">server</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">listen</span> <span style="color:#ae81ff">80</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">listen</span> <span style="color:#e6db74">[::]:80</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">root</span> <span style="color:#e6db74">/var/www/your-domain.com/html</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">index</span> <span style="color:#e6db74">index.html</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">server_name</span> <span style="color:#e6db74">your-domain.com</span> <span style="color:#e6db74">www.your-domain.com</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">location</span> <span style="color:#e6db74">/</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">try_files</span> $uri $uri/ =<span style="color:#ae81ff">404</span>;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><h3 id="step-4-enable-the-server-block">Step 4: Enable the Server Block</h3>
<p>We enable the site by creating a symbolic link from this file into the <code>sites-enabled</code> directory.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo ln -s /etc/nginx/sites-available/your-domain.com /etc/nginx/sites-enabled/
</span></span></code></pre></div><p>Now, test your Nginx configuration for errors and restart it.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo nginx -t
</span></span><span style="display:flex;"><span>sudo systemctl restart nginx
</span></span></code></pre></div><p>Once your DNS has updated, if you visit <code>http://your-domain.com</code> in a browser, you should see your &ldquo;Hello World&rdquo; message.</p>
<h2 id="7-secure-your-site-with-ssl-https">7. Secure Your Site with SSL (HTTPS)</h2>
<p>To secure your site, we&rsquo;ll get a free SSL certificate from Let&rsquo;s Encrypt using a tool called Certbot.</p>
<h3 id="step-1-install-certbot">Step 1: Install Certbot</h3>
<p>Certbot has a dedicated Nginx plugin that makes the process simple.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo apt install certbot python3-certbot-nginx -y
</span></span></code></pre></div><h3 id="step-2-obtain-the-ssl-certificate">Step 2: Obtain the SSL Certificate</h3>
<p>Run Certbot. It will read your Nginx configuration, see the domain you just set up, and guide you through obtaining the certificate.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo certbot --nginx
</span></span></code></pre></div><p>Certbot will ask for your email, for you to agree to the terms of service, and if you want to redirect all HTTP traffic to HTTPS. It is highly recommended to choose the redirect option.</p>
<h3 id="step-3-verify-auto-renewal">Step 3: Verify Auto-Renewal</h3>
<p>Let&rsquo;s Encrypt certificates are valid for 90 days. Certbot automatically sets up a task to renew them for you. You can test the renewal process with a dry run.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo certbot renew --dry-run
</span></span></code></pre></div><p>If this runs without errors, you are all set. Your site is now secure and accessible via <code>https://your-domain.com</code>.</p>
<p><strong>To add a subdomain</strong> (e.g., <code>blog.your-domain.com</code>), you simply repeat the process: create a new directory in <code>/var/www</code>, create a new server block file in <code>sites-available</code>, enable it, and then run <code>sudo certbot --nginx</code> again.</p>
<h2 id="8-quick-tips-and-best-practices">8. Quick Tips and Best Practices</h2>
<ul>
<li>
<p><strong>Use SSH Keys:</strong> Passwords can be cracked. SSH keys are a much more secure way to log in. This is a highly recommended next security step.</p>
</li>
<li>
<p><strong>Keep Your System Updated:</strong> Get in the habit of running <code>sudo apt update &amp;&amp; sudo apt upgrade -y</code> at least once a week.</p>
</li>
<li>
<p><strong>Be Careful with Commands:</strong> Don&rsquo;t run scripts or commands from the internet without understanding what they do.</p>
</li>
<li>
<p><strong>Use Strong Passwords:</strong> The password for your <code>sudo</code> user should be strong and unique.</p>
</li>
</ul>
]]></content:encoded></item><item><title>Advanced VPS Guide: Mastering Nginx, Subdomains, and Reverse Proxies</title><link>https://md.eknath.dev/posts/software-development/vps-setup-guide/</link><pubDate>Sun, 07 Sep 2025 12:00:00 +0530</pubDate><guid>https://md.eknath.dev/posts/software-development/vps-setup-guide/</guid><description>&lt;p>A Virtual Private Server (VPS) is your personal canvas on the internet. While basic setup is straightforward, unlocking its true potential requires mastering the web server. This guide dives deep into using Nginx to host multiple projects, manage subdomains, and route traffic to different services, transforming your single server into a multi-functional powerhouse.&lt;/p>
&lt;h2 id="1-initial-server-setup">1. Initial Server Setup&lt;/h2>
&lt;p>After acquiring a VPS, you&amp;rsquo;ll get an IP address and root access. Your first steps are to secure the server and create a non-root user for daily operations.&lt;/p></description><content:encoded><![CDATA[<p>A Virtual Private Server (VPS) is your personal canvas on the internet. While basic setup is straightforward, unlocking its true potential requires mastering the web server. This guide dives deep into using Nginx to host multiple projects, manage subdomains, and route traffic to different services, transforming your single server into a multi-functional powerhouse.</p>
<h2 id="1-initial-server-setup">1. Initial Server Setup</h2>
<p>After acquiring a VPS, you&rsquo;ll get an IP address and root access. Your first steps are to secure the server and create a non-root user for daily operations.</p>
<p>Connect to your server via SSH:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>ssh root@YOUR_SERVER_IP
</span></span></code></pre></div><h3 id="create-a-sudo-user">Create a Sudo User</h3>
<p>Operating as <code>root</code> is risky. Create a new user and grant administrative privileges.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Create the new user (replace &#39;devuser&#39; with your username)</span>
</span></span><span style="display:flex;"><span>adduser devuser
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Add the user to the &#39;sudo&#39; group</span>
</span></span><span style="display:flex;"><span>usermod -aG sudo devuser
</span></span></code></pre></div><p>Now, set up SSH key authentication for your new user for enhanced security and convenience, then log in as that user.</p>
<h2 id="2-essential-security-and-updates">2. Essential Security and Updates</h2>
<p>A public server is a constant target. Secure it immediately.</p>
<h3 id="configure-the-firewall">Configure the Firewall</h3>
<p><code>ufw</code> (Uncomplicated Firewall) makes this easy. We&rsquo;ll allow SSH, HTTP, and HTTPS traffic.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Allow OpenSSH (so you don&#39;t lock yourself out)</span>
</span></span><span style="display:flex;"><span>sudo ufw allow OpenSSH
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Allow Nginx to handle web traffic on ports 80 and 443</span>
</span></span><span style="display:flex;"><span>sudo ufw allow <span style="color:#e6db74">&#39;Nginx Full&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Enable the firewall</span>
</span></span><span style="display:flex;"><span>sudo ufw enable
</span></span></code></pre></div><p>After enabling, check its status to ensure it&rsquo;s active and your rules are loaded.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo ufw status
</span></span></code></pre></div><h3 id="update-your-server">Update Your Server</h3>
<p>Keep your system&rsquo;s packages current to patch security vulnerabilities.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo apt update <span style="color:#f92672">&amp;&amp;</span> sudo apt upgrade -y
</span></span></code></pre></div><h2 id="3-installing-and-understanding-nginx">3. Installing and Understanding Nginx</h2>
<p>Nginx is the heart of our setup. It&rsquo;s a high-performance web server that can also act as a reverse proxy, load balancer, and more.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Install Nginx</span>
</span></span><span style="display:flex;"><span>sudo apt install nginx -y
</span></span></code></pre></div><p>While the package should start and enable Nginx automatically, it&rsquo;s good practice to run the commands explicitly to be sure.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Start the Nginx service</span>
</span></span><span style="display:flex;"><span>sudo systemctl start nginx
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Enable Nginx to start automatically on boot</span>
</span></span><span style="display:flex;"><span>sudo systemctl enable nginx
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Now, check that it&#39;s running and enabled</span>
</span></span><span style="display:flex;"><span>sudo systemctl status nginx
</span></span></code></pre></div><p>You should see <code>active (running)</code> in the output. Visiting your server&rsquo;s IP in a browser should also show the Nginx welcome page.</p>
<h3 id="nginx-configuration-structure">Nginx Configuration Structure</h3>
<p>Nginx&rsquo;s configuration lives in <code>/etc/nginx</code>. The <code>-p</code> flag in the commands below ensures that the command does nothing if the directories already exist.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo mkdir -p /etc/nginx/sites-available
</span></span><span style="display:flex;"><span>sudo mkdir -p /etc/nginx/sites-enabled
</span></span></code></pre></div><p>The key directories are:</p>
<ul>
<li><code>/etc/nginx/nginx.conf</code>: The main configuration file. You rarely edit this.</li>
<li><code>/etc/nginx/sites-available/</code>: Where you store the configuration files for each of your sites (called &ldquo;server blocks&rdquo;).</li>
<li><code>/etc/nginx/sites-enabled/</code>: Where you create symbolic links to the configurations in <code>sites-available</code> that you want to be active.</li>
</ul>
<p>This structure lets you easily enable or disable sites without deleting their configuration files.</p>
<h2 id="4-advanced-hosting-subdomains-and-reverse-proxies">4. Advanced Hosting: Subdomains and Reverse Proxies</h2>
<p>This is where the magic happens. A single server can host a blog, a portfolio website, a web app, and several APIs, all neatly organized using subdomains.</p>
<p>The core concept is the <strong>Reverse Proxy</strong>. Your Nginx server listens on the standard web ports (80 for HTTP, 443 for HTTPS) and intelligently forwards incoming requests to the correct internal service based on the requested domain or subdomain.</p>
<h3 id="scenario">Scenario:</h3>
<p>Let&rsquo;s say we want to set up the following on our server:</p>
<ol>
<li><code>eknath.dev</code>: A static HTML/CSS website.</li>
<li><code>blog.eknath.dev</code>: A separate project, maybe a Hugo or Jekyll site.</li>
<li><code>api.eknath.dev</code>: A Node.js application running on port <code>3000</code>.</li>
</ol>
<h3 id="step-1-create-project-directories">Step 1: Create Project Directories</h3>
<p>Organize your projects in the <code>/var/www</code> directory.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Create directories for the main site and blog</span>
</span></span><span style="display:flex;"><span>sudo mkdir -p /var/www/eknath.dev/html
</span></span><span style="display:flex;"><span>sudo mkdir -p /var/www/blog.eknath.dev/html
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Set correct permissions</span>
</span></span><span style="display:flex;"><span>sudo chown -R $USER:$USER /var/www/eknath.dev
</span></span><span style="display:flex;"><span>sudo chown -R $USER:$USER /var/www/blog.eknath.dev
</span></span></code></pre></div><p>Verify that the directories were created with the correct ownership.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>ls -ld /var/www/eknath.dev/
</span></span><span style="display:flex;"><span>ls -ld /var/www/blog.eknath.dev/
</span></span></code></pre></div><p>Now, place some placeholder files.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>echo <span style="color:#e6db74">&#34;&lt;h1&gt;Welcome to Eknath&#39;s Site&lt;/h1&gt;&#34;</span> | sudo tee /var/www/eknath.dev/html/index.html
</span></span><span style="display:flex;"><span>echo <span style="color:#e6db74">&#34;&lt;h1&gt;Welcome to Eknath&#39;s Blog&lt;/h1&gt;&#34;</span> | sudo tee /var/www/blog.eknath.dev/html/index.html
</span></span></code></pre></div><h3 id="step-2-create-nginx-server-blocks">Step 2: Create Nginx Server Blocks</h3>
<p>Now, we create a configuration file for each site in <code>sites-available</code>.</p>
<p><strong>For the main domain (<code>eknath.dev</code>):</strong></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo nano /etc/nginx/sites-available/eknath.dev
</span></span></code></pre></div><p>Add the following server block:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#66d9ef">server</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">listen</span> <span style="color:#ae81ff">80</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">listen</span> <span style="color:#e6db74">[::]:80</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">server_name</span> <span style="color:#e6db74">eknath.dev</span> <span style="color:#e6db74">www.eknath.dev</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">root</span> <span style="color:#e6db74">/var/www/eknath.dev/html</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">index</span> <span style="color:#e6db74">index.html</span> <span style="color:#e6db74">index.php</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">location</span> <span style="color:#e6db74">/</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">try_files</span> $uri $uri/ =<span style="color:#ae81ff">404</span>;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p><strong>For the blog subdomain (<code>blog.eknath.dev</code>):</strong></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo nano /etc/nginx/sites-available/blog.eknath.dev
</span></span></code></pre></div><p>Add this configuration:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#66d9ef">server</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">listen</span> <span style="color:#ae81ff">80</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">listen</span> <span style="color:#e6db74">[::]:80</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">server_name</span> <span style="color:#e6db74">blog.eknath.dev</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">root</span> <span style="color:#e6db74">/var/www/blog.eknath.dev/html</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">index</span> <span style="color:#e6db74">index.html</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">location</span> <span style="color:#e6db74">/</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">try_files</span> $uri $uri/ =<span style="color:#ae81ff">404</span>;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><h3 id="step-3-configure-the-reverse-proxy-for-the-api">Step 3: Configure the Reverse Proxy for the API</h3>
<p>For <code>api.eknath.dev</code>, we&rsquo;ll proxy requests to our Node.js app, which we assume is running on <code>http://127.0.0.1:3000</code>.</p>
<p>Create the configuration file:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo nano /etc/nginx/sites-available/api.eknath.dev
</span></span></code></pre></div><p>Add the reverse proxy configuration:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#66d9ef">server</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">listen</span> <span style="color:#ae81ff">80</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">listen</span> <span style="color:#e6db74">[::]:80</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">server_name</span> <span style="color:#e6db74">api.eknath.dev</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">location</span> <span style="color:#e6db74">/</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">proxy_pass</span> <span style="color:#e6db74">http://127.0.0.1:3000</span>;
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">proxy_set_header</span> <span style="color:#e6db74">Host</span> $host;
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">proxy_set_header</span> <span style="color:#e6db74">X-Real-IP</span> $remote_addr;
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">proxy_set_header</span> <span style="color:#e6db74">X-Forwarded-For</span> $proxy_add_x_forwarded_for;
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">proxy_set_header</span> <span style="color:#e6db74">X-Forwarded-Proto</span> $scheme;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><h3 id="step-4-enable-the-sites-and-test">Step 4: Enable the Sites and Test</h3>
<p>Now, link these configurations into <code>sites-enabled</code> to activate them.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo ln -s /etc/nginx/sites-available/eknath.dev /etc/nginx/sites-enabled/
</span></span><span style="display:flex;"><span>sudo ln -s /etc/nginx/sites-available/blog.eknath.dev /etc/nginx/sites-enabled/
</span></span><span style="display:flex;"><span>sudo ln -s /etc/nginx/sites-available/api.eknath.dev /etc/nginx/sites-enabled/
</span></span></code></pre></div><p>Test the Nginx configuration for syntax errors:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo nginx -t
</span></span></code></pre></div><p>If it&rsquo;s successful, restart Nginx to apply the changes:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo systemctl restart nginx
</span></span></code></pre></div><p>Check the status to ensure it restarted correctly.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo systemctl status nginx
</span></span></code></pre></div><p>After setting up your DNS records, you&rsquo;ll be able to access each service through its unique subdomain.</p>
<h2 id="5-securing-your-sites-with-ssl-https">5. Securing Your Sites with SSL (HTTPS)</h2>
<p>We&rsquo;ll use <strong>Let&rsquo;s Encrypt</strong>, a free and automated Certificate Authority, and <strong>Certbot</strong>, a tool that makes managing SSL/TLS certificates effortless.</p>
<h3 id="step-1-install-certbot">Step 1: Install Certbot</h3>
<p>Certbot has a dedicated Nginx plugin that automates the process.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Install Certbot and its Nginx plugin</span>
</span></span><span style="display:flex;"><span>sudo apt install certbot python3-certbot-nginx -y
</span></span></code></pre></div><h3 id="step-2-obtain-and-install-the-ssl-certificates">Step 2: Obtain and Install the SSL Certificates</h3>
<p>With your server blocks already configured, running Certbot is incredibly simple.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Run Certbot to get certificates for all configured domains</span>
</span></span><span style="display:flex;"><span>sudo certbot --nginx
</span></span></code></pre></div><p>Certbot will guide you through a few simple steps:</p>
<ol>
<li><strong>Enter your email address.</strong></li>
<li><strong>Agree to the Terms of Service.</strong></li>
<li><strong>Choose domains</strong> from the list Certbot finds.</li>
<li><strong>Choose to redirect HTTP to HTTPS.</strong> This is highly recommended.</li>
</ol>
<h3 id="step-3-verify-the-new-configuration">Step 3: Verify the New Configuration</h3>
<p>Certbot automatically modifies your Nginx files to enable HTTPS. You can check the new configuration by running <code>sudo nginx -t</code> and then reloading Nginx with <code>sudo systemctl reload nginx</code>.</p>
<h3 id="step-4-understanding-automatic-renewal">Step 4: Understanding Automatic Renewal</h3>
<p>Let&rsquo;s Encrypt certificates are valid for 90 days. The Certbot package automatically sets up a task to renew them. You can test the renewal process with a dry run:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo certbot renew --dry-run
</span></span></code></pre></div><p>If this command runs without errors, your auto-renewal is set up correctly.</p>
<h2 id="conclusion">Conclusion</h2>
<p>You have now transformed a basic VPS into a sophisticated, multi-tenant hosting platform. By leveraging Nginx&rsquo;s server blocks and reverse proxy capabilities, you can host and manage numerous projects, each on its own subdomain, from a single server. Happy hosting!</p>
]]></content:encoded></item></channel></rss>