My personal portfolio website — a landing page with project and work-experience sections, theming (light/dark), and SEO.
- Nuxt 4 (Vue 3, Nitro server)
- @nuxt/content v3 — Markdown content, backed by SQLite (
better-sqlite3) - Tailwind CSS v4 via
@tailwindcss/vite - @nuxt/image, @nuxt/fonts
- @nuxtjs/seo (sitemap, robots, OG image, schema.org)
- @nuxtjs/color-mode for theming
- Package manager: pnpm (pinned via
packageManagerinpackage.json)
Install dependencies:
pnpm installStart the dev server on http://localhost:3000:
pnpm devpnpm build # build the Nitro server output into .output/
pnpm preview # locally preview the production buildThe server entry point is .output/server/index.mjs. It listens on HOST/PORT
(defaults 0.0.0.0:3000, or whatever you set via env).
The included Dockerfile is a multi-stage build (Alpine):
docker build -t personal-website .
docker run -p 3002:3002 personal-websiteThe container serves on port 3002 (PORT/HOST are set as ENV; override at
runtime if your platform injects its own $PORT).
@nuxt/content v3 uses better-sqlite3, a native C++ addon, to serve content
from a SQLite database. This affects the Docker build in two ways:
- Build stage needs
python3 make g++to compilebetter-sqlite3(no musl prebuilt binary ships for Alpine). - Runtime stage needs
libstdc++installed — the compiled addon links against it at load time. The basenode:alpineimage does not include it, so withoutapk add libstdc++the server crashes on startup withError loading shared library libstdc++.so.6, and the container never comes up (a fronting proxy will show a generic 500 / "temporarily unavailable").
Both are already handled in the Dockerfile — keep them if you edit it.
This repo uses semantic-release with
Conventional Commits. Versioning and CHANGELOG.md are generated automatically
from commit messages in CI.