Portfolio Platform: personal website, blog and admin panel
A personal website that grew into a small CMS: Next.js frontend, NestJS backend, auth service, admin panel, Markdown content, files, comments, navigation, technologies and Docker infrastructure.
The project started as a simple personal website, but it quickly became clear that a static page was not enough. I wanted to build a platform where I could manage content without editing code manually: hero, about, cases, posts, technologies, navigation, comments, files and site settings.
As a result, the project became a practical fullstack showcase. On the outside it is a minimal personal website. Under the hood it has a backend, admin panel, authentication, roles, file storage, Markdown content, Docker and production-oriented configuration.
What I Built
The platform includes:
- public website on Next.js with RU/EN locales;
- backend on NestJS/Fastify;
- separate auth service;
- PostgreSQL and Drizzle ORM;
- Redis for infrastructure tasks;
- admin panel for hero, about, cases, posts, technologies, navigation, settings, contacts and comments;
- file uploads, cover images and galleries;
- Markdown editor with preview;
- comments with captcha and moderation;
- view tracking with deduplication;
- Docker Compose for local and production setup.
Architecture
The backend is modular: commands, queries, handlers, DTOs, mappers and repositories are separated by domain area. This is heavier than quickly wiring controllers together, but for a project with admin workflows, public pages, preview mode, moderation and files, the structure pays off quickly.
On the frontend, App Router is used together with code organized into app, widgets, entities and shared. Public pages stay thin, while admin forms live in separate widgets. This keeps the public showcase and the working admin interface from bleeding into each other.
What Had to Be Improved
As the project grew from “a few pages” into a small product system, real engineering problems appeared:
- refreshing admin data after POST/PATCH/DELETE without manual page reloads;
- keeping authentication stable after page refreshes;
- uploading and reusing files;
- bulk import for technologies and Markdown posts;
- rendering external technology icons correctly;
- using admin-managed navigation on the public site;
- preparing Docker/Caddy setup for deployment to a separate server and domain.
Result
The result is not just a portfolio page, but a small platform around my personal brand and engineering experience. It can grow further: I can add new cases, publish technical articles, update visual blocks through the admin panel and move the environment between servers without manual rebuilds on the machine.
For me, this project is also an honest example of how I work: when a system starts growing, I do not leave it as a pile of temporary decisions. I gradually move it toward clear architecture, usable admin UX and reproducible deployment.