<?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[mihirsavla(Portfolio website)]]></title><description><![CDATA[mihirsavla(Portfolio website)]]></description><link>https://mihirsavla.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Sat, 07 Nov 2026 11:35:21 GMT</lastBuildDate><atom:link href="https://mihirsavla.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Lessons from Building My Portfolio Website (mihirsavla.com) — A Deep Dive into Docker, Apache, and DevOps on a VPS]]></title><description><![CDATA[Building a personal website might seem straightforward — pick a template, write some HTML, host it somewhere, and you’re live. But when you choose to do it…]]></description><link>https://mihirsavla.hashnode.dev/lessons-from-building-my-portfolio-website-mihirsavlacom-a-deep-dive-into-docker-apache-and-devops-on-a-vps</link><guid isPermaLink="true">https://mihirsavla.hashnode.dev/lessons-from-building-my-portfolio-website-mihirsavlacom-a-deep-dive-into-docker-apache-and-devops-on-a-vps</guid><category><![CDATA[Linux]]></category><category><![CDATA[System administration]]></category><category><![CDATA[cpanel]]></category><category><![CDATA[Docker]]></category><category><![CDATA[GitHub]]></category><category><![CDATA[Git]]></category><category><![CDATA[ssh]]></category><category><![CDATA[ssh-keys]]></category><category><![CDATA[apache]]></category><category><![CDATA[AlmaLinux]]></category><dc:creator><![CDATA[Mihir Savla]]></dc:creator><pubDate>Fri, 08 Aug 2025 05:35:27 GMT</pubDate><content:encoded><![CDATA[<hr />
<p>Building a personal website might seem straightforward — pick a template, write some HTML, host it somewhere, and you’re live. But when you choose to do it the engineering way, self-hosted on a VPS with full control, it becomes a project that challenges your understanding of servers, Docker, networking, reverse proxies, and deployment pipelines.</p>
<p>Here’s what I learned (and wish I had known earlier) while building <a target="_blank" href="https://mihirsavla.com"><strong>mihirsavla.com</strong></a>:</p>
<hr />
<h3 id="heading-what-went-right">✅ What Went Right</h3>
<p><strong>1. Dockerized App Architecture:</strong></p>
<ul>
<li><p>I built my site as a containerized app using Docker with Nginx.</p>
</li>
<li><p>Benefits: Portability, version control, clean local testing, and easy rebuilds.</p>
</li>
</ul>
<p><strong>2. Blog Integration with Hashnode API:</strong></p>
<ul>
<li><p>Instead of manually updating blog content, I used Hashnode’s GraphQL API to dynamically fetch and display blog posts on a <code>/blog</code> route.</p>
</li>
<li><p>Interactive, live, and always up-to-date without deploying changes for every post.</p>
</li>
</ul>
<p><strong>3. GitHub Actions for CI/CD:</strong></p>
<ul>
<li><p>Every push to GitHub triggers an automated deploy to my VPS via SSH keys.</p>
</li>
<li><p>I used GitHub Secrets to store my SSH private key securely.</p>
</li>
<li><p>This saves tons of manual effort and is incredibly satisfying when you see it "just work."</p>
</li>
</ul>
<p><strong>4. Reverse Proxy via Apache on Port 8080:</strong></p>
<ul>
<li><p>My VPS serves all domains through Apache on port 8080 (not the default port 80).</p>
</li>
<li><p>I added a custom <code>VirtualHost</code> rule using WHM’s Include Editor to reverse proxy mihirsavla.com to my Docker container running on port 8181.</p>
</li>
</ul>
<hr />
<h3 id="heading-challenges-that-made-me-wiser">🧠 Challenges That Made Me Wiser</h3>
<p><strong>1. Port Conflicts from Existing Services:</strong></p>
<ul>
<li><p>A previous script I wrote was using <code>python3 -m http.server</code> bound to port 80, which caused Apache to fail silently.</p>
</li>
<li><p>Lesson: Always check <code>lsof -i :PORT</code> and <code>systemctl list-units</code> to find conflicting services.</p>
</li>
</ul>
<p><strong>2. Misleading Success Signals:</strong></p>
<ul>
<li><p>Apache restarted successfully, but my domain still served the old script’s response.</p>
</li>
<li><p>Lesson: Curl your domain and 127.0.0.1 at the correct port to validate what's being served.</p>
</li>
</ul>
<p><strong>3. Confusing Apache with Docker and cPanel:</strong></p>
<ul>
<li><p>Apache via cPanel uses many layers: pre-main, pre-virtualhost, post-virtualhost, userdata, etc.</p>
</li>
<li><p>The actual serving domain might not be reading your config if not added in the correct include.</p>
</li>
<li><p>Solution: Use <code>/scripts/rebuildhttpdconf</code> followed by <code>/scripts/restartsrv_httpd</code> after every change.</p>
</li>
</ul>
<p><strong>4. Custom Userdata Folder Didn’t Exist:</strong></p>
<ul>
<li><p>For <code>mihirsavla.com</code>, I had to create a new <code>proxy.conf</code> manually in <code>/etc/apache2/conf.d/userdata/std/2_4/mihir/mihirsavla.com/</code></p>
</li>
<li><p>Restarting Apache with <code>restartsrv_httpd</code> finally worked.</p>
</li>
</ul>
<hr />
<h3 id="heading-what-not-to-do">❌ What Not to Do</h3>
<ul>
<li><p>Don’t bind services directly to port 80 unless you're certain nothing else needs it.</p>
</li>
<li><p>Don’t rely on WHM config alone — always confirm Apache is actually listening with <code>ss -tuln</code>.</p>
</li>
<li><p>Don’t hardcode your deployment IPs — use a proper domain with reverse proxy and HTTPS if possible.</p>
</li>
<li><p>Don’t forget to test with <code>curl</code> and <code>apachectl -S</code>.</p>
</li>
</ul>
<hr />
<h3 id="heading-pro-tips-for-self-hosting-on-a-vps">💡 Pro Tips for Self-Hosting on a VPS</h3>
<ol>
<li><p>Always use Docker for static portfolio sites — it's overkill but educational and clean.</p>
</li>
<li><p>Use port mapping smartly (<code>0.0.0.0:8181-&gt;80</code> inside Docker).</p>
</li>
<li><p>Keep a systemd script to restart essential scripts like your disk usage monitor.</p>
</li>
<li><p>Consider a static site generator or Next.js for future scalability.</p>
</li>
</ol>
<hr />
<h3 id="heading-tools-amp-tech-stack">🔧 Tools &amp; Tech Stack</h3>
<ul>
<li><p>Docker &amp; Docker Compose</p>
</li>
<li><p>Apache on AlmaLinux VPS (cPanel/WHM)</p>
</li>
<li><p>GitHub Actions (CI/CD pipeline)</p>
</li>
<li><p>Hashnode GraphQL API</p>
</li>
<li><p>SSH with key-based auth</p>
</li>
<li><p>curl, lsof, ss, systemctl</p>
</li>
</ul>
<hr />
<h3 id="heading-final-thoughts">🎯 Final Thoughts</h3>
<p>Building mihirsavla.com wasn't just about a website — it was about proving to myself that I could manage deployments, handle conflicts, automate everything, and deliver a product that reflects engineering maturity.</p>
<p>If you’re looking to learn DevOps through a real project — building and deploying your own site is one of the best ways to do it.</p>
<p>Happy to answer any questions or help anyone trying something similar! update me on <a target="_blank" href="https://linkedin.com/in/mihir-savla">LinkedIn</a></p>
]]></content:encoded></item></channel></rss>