Lessons from Building My Portfolio Website (mihirsavla.com) — A Deep Dive into Docker, Apache, and DevOps on a VPS

Mihir SavlaMihir Savla
3 min read

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.

Here’s what I learned (and wish I had known earlier) while building mihirsavla.com:


✅ What Went Right

1. Dockerized App Architecture:

  • I built my site as a containerized app using Docker with Nginx.

  • Benefits: Portability, version control, clean local testing, and easy rebuilds.

2. Blog Integration with Hashnode API:

  • Instead of manually updating blog content, I used Hashnode’s GraphQL API to dynamically fetch and display blog posts on a /blog route.

  • Interactive, live, and always up-to-date without deploying changes for every post.

3. GitHub Actions for CI/CD:

  • Every push to GitHub triggers an automated deploy to my VPS via SSH keys.

  • I used GitHub Secrets to store my SSH private key securely.

  • This saves tons of manual effort and is incredibly satisfying when you see it "just work."

4. Reverse Proxy via Apache on Port 8080:

  • My VPS serves all domains through Apache on port 8080 (not the default port 80).

  • I added a custom VirtualHost rule using WHM’s Include Editor to reverse proxy mihirsavla.com to my Docker container running on port 8181.


🧠 Challenges That Made Me Wiser

1. Port Conflicts from Existing Services:

  • A previous script I wrote was using python3 -m http.server bound to port 80, which caused Apache to fail silently.

  • Lesson: Always check lsof -i :PORT and systemctl list-units to find conflicting services.

2. Misleading Success Signals:

  • Apache restarted successfully, but my domain still served the old script’s response.

  • Lesson: Curl your domain and 127.0.0.1 at the correct port to validate what's being served.

3. Confusing Apache with Docker and cPanel:

  • Apache via cPanel uses many layers: pre-main, pre-virtualhost, post-virtualhost, userdata, etc.

  • The actual serving domain might not be reading your config if not added in the correct include.

  • Solution: Use /scripts/rebuildhttpdconf followed by /scripts/restartsrv_httpd after every change.

4. Custom Userdata Folder Didn’t Exist:

  • For mihirsavla.com, I had to create a new proxy.conf manually in /etc/apache2/conf.d/userdata/std/2_4/mihir/mihirsavla.com/

  • Restarting Apache with restartsrv_httpd finally worked.


❌ What Not to Do

  • Don’t bind services directly to port 80 unless you're certain nothing else needs it.

  • Don’t rely on WHM config alone — always confirm Apache is actually listening with ss -tuln.

  • Don’t hardcode your deployment IPs — use a proper domain with reverse proxy and HTTPS if possible.

  • Don’t forget to test with curl and apachectl -S.


💡 Pro Tips for Self-Hosting on a VPS

  1. Always use Docker for static portfolio sites — it's overkill but educational and clean.

  2. Use port mapping smartly (0.0.0.0:8181->80 inside Docker).

  3. Keep a systemd script to restart essential scripts like your disk usage monitor.

  4. Consider a static site generator or Next.js for future scalability.


🔧 Tools & Tech Stack

  • Docker & Docker Compose

  • Apache on AlmaLinux VPS (cPanel/WHM)

  • GitHub Actions (CI/CD pipeline)

  • Hashnode GraphQL API

  • SSH with key-based auth

  • curl, lsof, ss, systemctl


🎯 Final Thoughts

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.

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.

Happy to answer any questions or help anyone trying something similar! update me on LinkedIn

0
Subscribe to my newsletter

Read articles from Mihir Savla directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Mihir Savla
Mihir Savla