Back to Articles

How I Built and Deployed My React + Next.js Portfolio with Node.js and Docker

Published May 29, 2025
next.jsreactnodedockerwebdevportfolio

As a full-stack developer, having a personal website isn’t just a nice-to-have — it’s your digital handshake.
I wanted mine to reflect not only my projects, but the tech I use daily: React, Node.js, containers, CI/CD — the works.

Here’s how I built luisfaria.dev from the ground up.


The Stack

  • Frontend: Next.js — React framework with SSR support
  • Backend: Node.js API (Express-flavored)
  • Deployment: Dockerized everything and hosted on DigitalOcean
  • Reverse Proxy: Nginx container
  • Domain & SSL: Let’s Encrypt + custom DNS
  • Extras: GitHub Actions, Certbot, and a dash of stubbornness

1. Scaffolding the Project

Started with:

npx create-next-app@latest

This gave me a solid file structure with pages/, public/, and API routes baked in.
I created a custom _app.tsx, dynamic routing for my /projects page, and styled everything with Tailwind CSS.


2. Backend Setup

I created a lightweight Node.js API to handle future blog posts and contact form entries
(eventually hooked into a headless CMS or Supabase).


3. Dockerizing Everything 🐳

This was non-negotiable.
I created:

  • frontend/Dockerfile
  • backend/Dockerfile
  • docker-compose.yml

To fit it all in!


4. SSL, DNS, and The Headache

I mapped luisfaria.dev to my droplet using an A record.
Then used Certbot inside the Nginx container to generate my SSL certificates.

But here’s the real kicker:
My local /etc/hosts file still pointed to an old IP from months ago (157.245.x.x)

I flushed DNS, restarted routers: nothing. The fix?
Overwriting the record manually in /etc/hosts.
Always double-check your local DNS overrides.


5. Rebuilding From Scratch

For a clean restart:

docker-compose down --volumes --remove-orphans docker-compose build --no-cache docker-compose up -d

This guaranteed my containers weren’t holding onto any stale image cache.


6. Final Touches

  • Clean SEO tags for pages
  • Lighthouse optimization
  • Minimalistic design focused on performance and clarity

Key Takeaways

  • DNS issues can masquerade as app bugs — always check your IP resolution.
  • Docker networking is powerful, but naming your services correctly in proxy_pass matters.
  • Nginx + Let’s Encrypt + Next.js is a beautiful trio — once you tame them.

The Result

My site is now live at https://luisfaria.dev — secure, fast, and 100% mine.

If you’re building your own dev portfolio, feel free to fork mine or drop a question below.
I’m happy to help others skip the landmines I stepped on. 😅