How this site is built
A small project, but it touches the same pieces as a larger deployment: source control, CI/CD, DNS, TLS, security headers and cost control.
Goal
A fast, secure resume site that costs almost nothing to run and updates automatically when I push a change.
Architecture
Decisions
- Static HTML/CSS/JS — no server to patch and no database, so very little attack surface.
- Azure Static Web Apps (Free) — $0 hosting, managed TLS, built-in GitHub deployment.
- GitHub Actions — every push to
maindeploys automatically. - Custom domain — registered at Namecheap and pointed at Azure with DNS records.
- Security headers — a strict Content-Security-Policy,
X-Content-Type-Options,X-Frame-Optionsand a referrer policy, set instaticwebapp.config.json. - No inline scripts or styles — that lets the CSP stay at
'self'withoutunsafe-inline. - Cost control — an Azure budget alert as a safety net, even on a free plan.
What I learned
Check the file, not the filename.
My resume download opened as a blank page. The browser console said the PDF had an invalid structure, and
inspecting the file showed it was actually a LibreOffice Draw document renamed to .pdf.
The fix was exporting a real PDF instead of renaming.
Security headers can break legitimate features.
Before finding that, I suspected my X-Frame-Options: DENY header, because browsers' built-in PDF
viewers render PDFs in a frame. It wasn't the cause here, but it's a real interaction, so I added a route-specific
override for the /assets folder and kept the strict headers everywhere else.
Git has a staging area for a reason.
A commit that reported "no changes added to commit" taught me to read git status before every commit.
Changes show up red until they're staged and green once they are.
Let the platform write the pipeline, then read it.
Azure commits the GitHub Actions workflow to the repo when the app is created, so my local copy was behind
until I ran git pull. Reading the generated workflow showed exactly how the deploy token and build
settings connect the repo to Azure.
Keep secrets out of the repo.
Before the first commit I moved a credentials note out of the project folder and added a .gitignore
that blocks files with names like *creds*, .env and *.key.