2026-04-22 12:20:58 -07:00

Bio portfolio (static)

Single-page portfolio aligned with PRD/PRDs/Bio Site PRD.md: Vue 3, Vite, Tailwind, GSAP scroll reveals, static dist/ output for free static hosts.

Prerequisites

  • Node.js 20+ (22 recommended for CI)

Local development

npm install
npm run dev

Open the URL Vite prints (usually http://localhost:5173).

Production build

npm run build
npm run preview

Artifacts are written to dist/. Deploy that folder to Cloudflare Pages, Netlify, Vercel, or GitHub Pages.

Docker (static site in a container)

The app is still a static build; the container only runs nginx to serve dist/. No Node at runtime.

Build and run

docker build -t bio-site .
docker run --rm -p 8080:80 bio-site

Open http://localhost:8080.

Compose (handy defaults)

docker compose up -d --build

By default this maps host 8080 → container 80. Override the host port:

HOST_PORT=3000 docker compose up -d --build

VITE_BASE inside Docker

  • For **http://your-server/** (site at root): use the default **/** (do not set VITE_BASE, or set VITE_BASE=/`).
  • For GitHub Pages–style subpaths behind a path-based reverse proxy only: build with e.g. docker build --build-arg VITE_BASE=/bio/ -t bio-site . or set VITE_BASE in docker-compose.yml / .env next to compose.

Mismatching VITE_BASE and where nginx actually serves the app is the most common reason assets return 404.

Hosting on your LAN (Linux server)

  1. Install Docker on the server (Docker Engine + Compose plugin, or Docker Desktop on a workstation acting as a host).
  2. Copy the project (or clone the repo) onto the machine and run docker compose up -d --build from the repo root.
  3. Find the server’s LAN IP, e.g. ip -br a or hostname -I.
  4. From another device on the same network, open http://<LAN-IP>:8080 (or whatever HOST_PORT you chose).
  5. Firewall: allow the host port, e.g. with UFW: sudo ufw allow 8080/tcp comment 'bio static' then sudo ufw reload (adjust port to match HOST_PORT).
  6. Optional: put Caddy, Traefik, or nginx on the host in front of the container for HTTPS, auth, or a single entrypoint on 443 while the container stays on an internal port.

The container listens on all interfaces inside the host’s Docker publish rules; binding to LAN-only is usually done with host firewall rules or by placing a reverse proxy on the edge.

Customize content

What Where
Name, links, email, tagline src/content/site.ts
Skills src/content/skills.ts
Projects src/content/projects.ts
Roles src/content/experience.ts
Headshot Replace public/avatar.svg with your image (WebP/AVIF or optimized JPG/PNG under public/ — update HeroSection.vue if you change the filename).
Resume PDF Add public/resume.pdf (the Experience section links to it).
SEO / social Update <title>, <meta name="description">, Open Graph/Twitter tags, and og:url in index.html to match your real domain.

GitHub Pages (project site)

If the site is served from https://username.github.io/repo-name/, Vite needs a base path:

  1. In the repo, add a variable VITE_BASE (Settings → Secrets and variables → Actions → Variables) with value /repo-name/ (leading slash, trailing slash optional).
  2. Enable GitHub Pages from GitHub Actions using the included workflow (Settings → Pages → Build and deployment → Source: GitHub Actions).
  3. The workflow .github/workflows/pages.yml runs npm install, npm run build with VITE_BASE, and publishes dist.

For a user site (username.github.io with the site at the root of that repo), leave VITE_BASE unset so the site uses /.

Environment variable (local)

Create .env.production (or .env) if you want to test a non-root base locally:

VITE_BASE=/repo-name/

Then npm run build and npm run preview.

Lighthouse / performance notes

  • Hero image uses fetchpriority="high" and explicit width / height.
  • GSAP + ScrollTrigger load on demand per section via dynamic import() to keep the initial JS smaller.
  • Google Fonts load from index.html; self-hosting fonts is an optional future optimization.

License

Private / personal use — adjust as you like.

S
Description
Bio/Resume Website For Myself
Readme
275 KiB
0 Stars 1 Watchers 0 Forks
Languages
Vue 54.3%
TypeScript 38.3%
HTML 4%
CSS 1.9%
Dockerfile 1.3%
Other 0.2%