Personal brand website & portfolio for Franck Ngaha — Senior Python & AI Engineer. Goal: a fast, clean, production-minded portfolio to attract freelance / consulting opportunities.
Live: https://helloworldhub.dev
Languages: EN + FR (prefix routing: /en, /fr)
- Modern static frontend with Astro (multi-page, i18n, SEO basics)
- Backend API with FastAPI (
/contact, validation, rate limiting, CORS) - Production deployment on Google Cloud Run (frontend + api)
- Runtime config pattern for frontend (served
config.js) - Security hygiene: no secrets committed, Cloud Run + Secret Manager (Resend API key)
- Developer experience: Makefile, Docker builds/runs, consistent structure
Frontend
- Astro (static output)
- Nginx (serving static + redirects)
- Runtime config via
public/config.js(generated/templated)
Backend
- FastAPI
- Pydantic v2 (
pydantic-settings) - CORS + lightweight rate limiting
- Contact flow: store message (Firestore) + enqueue email (Cloud Tasks) + send via Resend
Infra
- Google Cloud Run (2 services:
helloworldhub-frontend,helloworldhub-api) - Secret Manager for
RESEND_API_KEY - Firestore + Cloud Tasks
api/
app/
main.py
config.py
routers/
services/
frontend/
src/
public/
Makefile
make installmake api
make frontendmake docker-build
make docker-runThe frontend reads window.__CONFIG__.API_BASE_URL from:
https://<domain>/config.js
Examples:
CORS_ORIGINS_CSVCONTACT_EMAIL_TOPUBLIC_API_BASE_URLGCP_PROJECT_ID,GCP_REGION,CONTACT_TASKS_QUEUE, …
RESEND_API_KEYis provided via Secret Manager and injected into Cloud Run using--set-secrets.
This repo is designed for Cloud Run deployments.
See Makefile targets (e.g. cr-build, cr-push, cr-deploy-*) or deploy manually with gcloud run deploy.
Code is provided as a portfolio showcase. You may use it for learning/inspiration, but please avoid reusing branding/assets (logo, name, images) 1:1.
© Franck Ngaha — HelloWorldHub