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.