Full-stack developer at @flexion, building tools for news intelligence, home automation, media management, and developer workflows. Passionate about self-hosting and running my own infrastructure — if something can be self-hosted, I've probably already tried it.
I write primarily in TypeScript and Python, tend toward clean architecture over clever code, and run a personal homelab with 30+ services across 6 machines.
This portfolio is built with Astro v5 + Svelte 5, deployed on Vercel, backed by a Turso (libSQL) database. Features include:
- Projects — live demos embedded directly in the page (4 embed modes below)
- Blog — Markdown-based posts with live preview
- Admin panel — standalone local Express service (
admin-panel/) with HMAC-signed session auth and full CRUD for posts and projects - Admin CLI — interactive terminal tool for managing content without a browser
- Interactive homelab map — 3D Three.js visualisation of all machines and services
- 4 embed types —
iframe·static·mfe(micro-frontend) ·none
| Project | Description | Stack |
|---|---|---|
| WatchYourTone | AI-powered sentiment and emotion analysis on news headlines with trend tracking and Stripe subscriptions | Next.js · TypeScript · PostgreSQL · Stripe |
| Fullsend Discord Bot | All-in-one bot: media requests, downloads, price watching, and plant care reminders | TypeScript · Discord.js · n8n · Docker |
| MC-Manager | Self-hosted Minecraft server manager via Docker — web UI, WebSocket console, live metrics | React · Node.js · WebSocket · Docker |
| LumiSync | Sync Govee LED lights to monitor content or music in real time | Python · cross-platform |
| Balena Sound Stereo | DIY multi-room audio (Bluetooth, AirPlay, Spotify Connect) on Raspberry Pi 4 | TypeScript · Balena · Raspberry Pi |
I run a personal homelab with 30+ self-hosted services across 6 machines (Proxmox hypervisor, tower, RPi 5, dedicated media server, dev server, and a Home Assistant hub).
Highlights: Proxmox · Jellyfin · Home Assistant · n8n · Gitea · Jenkins · AdGuard Home · Immich
→ Full tour at lukegarceau.dev/homelab
Languages: TypeScript · Python · JavaScript · Shell Frontend: Astro · Next.js · React · Svelte · Angular · Tailwind CSS · Angular Material Backend: Node.js · Flask · Drizzle ORM · PostgreSQL · SQLite/Turso · Spring Boot DevOps: Docker · AWS (heavy) · AWS CDK · Nginx · Jenkins · GitHub Actions · Vercel · Proxmox · Balena · Artifactory · Selenium Design: Figma · Mural Analytics: PostHog · Google Analytics Project management: Jira · Confluence · Scrum (lead)
Developer Setup
npm install
cp .env.example .env # fill in ADMIN_PASSWORD, SESSION_SECRET, CONTACT_EMAIL
npm run db:push # creates local.db with posts + projects tables
npm run dev # http://localhost:4321| Variable | Where | Purpose |
|---|---|---|
ADMIN_PASSWORD |
local + Vercel | Password for the admin panel and CLI |
SESSION_SECRET |
local + Vercel | Signs session cookies — use a random 32+ char string |
CONTACT_EMAIL |
local + Vercel | Email shown on the contact page |
TURSO_DATABASE_URL |
Vercel only | libsql://your-db.turso.io |
TURSO_AUTH_TOKEN |
Vercel only | Turso auth token |
Locally, TURSO_DATABASE_URL defaults to file:./local.db — no env var needed.
The admin panel is a standalone local Express service in admin-panel/. It is not part of the deployed Astro site.
cd admin-panel
./start # installs deps, copies .env if missing, opens browser at http://localhost:3001Or manually:
cd admin-panel
cp .env.example .env # set ADMIN_PASSWORD and SESSION_SECRET
npm install
npm startThe panel runs on http://localhost:3001 and connects to the same local.db (or Turso in production via env vars).
| Route | What it does |
|---|---|
/ |
Dashboard — post/project counts, quick links |
/posts |
List all posts |
/posts/new |
New post (Markdown editor with live preview) |
/posts/:id |
Edit or delete a post |
/projects |
List all projects |
/projects/new |
New project |
/projects/:id |
Edit or delete a project |
An interactive terminal tool for managing content without a browser.
cd admin-panel
npm run cliNavigates via arrow-key menus:
Manage: Posts / Projects / Exit
└── List all
└── New (prompts for all fields, opens $EDITOR for Markdown content)
└── Edit (select from list, fields pre-filled)
└── Delete (select from list, requires confirmation)
Each project has an embed type that controls what shows on its detail page.
none — description + links only
Use for libraries, CLI tools, anything without a visual demo.
iframe — embed a deployed app
Set demoUrl to the full URL of the running app. Renders in a full-height <iframe>.
static — self-contained HTML/CSS/JS preview
Drop files into public/demos/[slug]/index.html. Renders in a sandboxed iframe.
mfe — Micro Frontend (remote JS module)
Your remote app must export mount(container: HTMLElement). Set mfeUrl to the remote entry URL.
npm run db:push # sync schema changes to local.db (dev)
npm run db:studio # open Drizzle Studio GUI at localhost:4983
npm run db:generate # generate SQL migration files (for production deploys)
npm run db:migrate # apply migration filesThis site uses @astrojs/vercel and deploys to Vercel with Turso as the database. The admin-panel/ directory is not deployed — it is local-only.
vercel deploy
# Set TURSO_DATABASE_URL + TURSO_AUTH_TOKEN in Vercel dashboard
# Run: npm run db:migrate (against Turso)src/
pages/
index.astro # home — hero, featured projects, latest posts
homelab.astro # homelab / datacenter tour
projects/[slug].astro # project detail + demo embed
blog/[slug].astro # blog post (Markdown rendered)
contact.astro # mailto: button
api/ # public API routes (no admin routes in production)
components/
DemoEmbed.astro # routes to iframe / MFE / static based on embedType
svelte/
FilterBar.svelte # client-side project filter (language + tag + search)
HomelabMap.svelte # interactive 3D Three.js homelab visualisation
MfeBridge.svelte # dynamically loads remote MFE module
lib/
db.ts # Drizzle singleton
auth.ts # session create/verify (HMAC-signed cookie)
middleware.ts # passthrough (admin routes live in admin-panel/)
db/
schema.ts # posts + projects table definitions
public/
demos/[slug]/index.html # static demo files (embedType: static)
admin-panel/
server.js # Express admin service (local only, port 3001)
cli.js # interactive CLI for managing posts and projects
start # convenience script — installs, copies .env, opens browser