
Personal Hub on dngioi.com
My personal homepage, portfolio and small community in one site: a timeline of updates, projects, a CV, and threads where members talk. Built end to end and running on one small server.
About the project
Personal Hub is the site you are on. It brings together who I am and what I do, a personal timeline, my projects, portfolio and CV, and a small community where signed-in members start threads and comment.
I built it in short cycles, each planned, tested and reviewed before release: from the foundation and media pipeline, through the wall, portfolio, projects, discussions and admin, to hardening, the move to production, page caching and the profile timeline. It runs live at dngioi.com on a 1 vCPU / 2 GB server in Vietnam, with nightly off-site backups.
Features
- Personal timeline: posts grouped by year and month, a sticky month header, and a year list to jump back in time; each post can be dated to the day it happened.
- Profile, portfolio and CV: experience, education, skills and certifications, with a printable CV and a PDF for members.
- Projects with screenshots, diagrams, videos and documents.
- Threads: categories (some for members only), comments and replies, member profiles and avatars.
- Sign in with Google; the owner edits everything in place, and an admin area moderates members and files.
Screenshots
Architecture
- API: Spring Boot 3 on Java 21 with PostgreSQL and Flyway. Every read and write goes through one access policy (public, members-only or owner-only; drafts and soft deletes).
- Web: Next.js 15 App Router. Public pages are cached and rebuilt at most once a minute; signed-in data comes from the API in the browser.
- Files on Cloudflare R2 through short-lived signed links; sign-in with Firebase Auth.
- Production: Docker Compose on one Ubuntu server behind Caddy (HTTPS), with nightly database backups copied off-site to R2.
Challenges & what I learned
- Serving every visitor the same cached pages without ever caching private content or an outage.
- Measuring real capacity with load tests on capped virtual servers to choose and price the hosting.
- Keeping a member's files private by default while their public posts stay viewable, through one media-visibility rule.
- Getting a timeline right across time zones: months are counted in Vietnam time everywhere.
- Small, reviewed cycles (spec, plan, tests, whole-branch review) keep a growing codebase understandable.
- Testing at three levels (Testcontainers, component tests, Playwright end-to-end) catches different mistakes.
- Measure before buying: page caching doubled what the smallest server handles.
