Sirui Chen·sirui.dev

Project

sirui.dev — Full-Stack Portfolio on AWS EC2

Production-style portfolio deployed on a self-managed AWS EC2 box.

Next.js 16React 19TypeScript (strict)Tailwind CSS 4shadcn/uiAWS EC2 (Ubuntu)NginxPM2CertbotGitHub Actions

Overview

A typed Next.js portfolio shipped end-to-end: app, Nginx reverse proxy, PM2 process manager, Let's Encrypt HTTPS, and a GitHub Actions deploy pipeline running on Ubuntu EC2.

Problem

Most portfolios are static templates that prove nothing about deployment or production engineering. I needed a site that doubles as evidence that I can ship and operate a real service end-to-end.

What I built

Built a strict-TypeScript Next.js (App Router) site with a typed data layer, server components everywhere, generated OG images, robots and sitemap, then deployed it on a self-managed EC2 instance behind Nginx + PM2 with HTTPS from Certbot and CI/CD from GitHub Actions.

Architecture

  • Porkbun DNS → EC2 Elastic IP (34.203.127.239)
  • Nginx (80 → 301 → 443) terminating TLS from Let's Encrypt
  • Reverse proxy to Next.js on 127.0.0.1:3000 (never exposed publicly)
  • PM2 manages the Node process with systemd-based startup
  • GitHub Actions runs lint + typecheck + build, then SSHes in to git pull and pm2 restart
  • Content lives in typed data/*.ts modules — no database, no CMS in v1

Technical highlights

  • Strict TypeScript with noUncheckedIndexedAccess and readonly data; no any in app code.
  • Server Components by default — no client-side data fetching, no hydration tax on content pages.
  • Nginx is the only public entry point; the app binds 127.0.0.1 so port 3000 is never reachable from the internet.
  • HTTPS-only with HSTS preload-ready headers, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, and Permissions-Policy.
  • UFW restricts ingress to 22 / 80 / 443; everything else is denied by default.
  • CI fails fast on lint or build errors before any SSH step touches the server.

Impact

  • Acts as the live proof-of-work for full-stack applications: deployment, DNS, HTTPS, reverse proxying, CI/CD, and frontend craft.
  • Editing the site reduces to changing typed TS files and pushing to main.