Kochi, IndiaNo. 4 · Friday, 2 October 2026v0.4.0

Ajmal Roshan



astro · nginx · oci · devops

How this site is built and shipped

Astro, zero client-side JavaScript, nginx on an always-free Oracle Cloud VM, and tag-driven releases.

This site is deliberately boring infrastructure: static HTML, one small VM, one shell script.

Stack

  • Astro: renders every page to plain HTML at build time. The site ships no client-side JavaScript at all; the figure on the home page is plain inline SVG.
  • Markdown content collections: every post is a .md file with a typed frontmatter schema, so a missing date fails the build rather than the page.
  • Newsreader and IBM Plex Mono, self-hosted. The paper grain is two SVG noise filters, so there are no texture images to download.
  • nginx on an Oracle Cloud Always Free VM.Standard.E2.1.Micro with 1 GB of RAM.

Deploys

Production only changes when I push a vX.Y.Z tag. GitHub Actions builds the site, attaches the build to a GitHub Release, and ships that exact tarball.

A build is a directory of files, so a deploy is a copy plus a symlink swap:

npm run build
rsync -az --delete --link-dest="$ROOT/current/" dist/ "oci:$ROOT/releases/$REL/"
ssh oci "ln -sfn $ROOT/releases/$REL $ROOT/current.tmp && mv -Tf $ROOT/current.tmp $ROOT/current"

mv -T over a symlink is a single rename(2), so nginx never serves a half-copied tree. --link-dest hard-links unchanged files from the previous release, which makes keeping the last five releases for rollback almost free.

Caching

Astro fingerprints everything under /_astro/, so those files get Cache-Control: immutable for a year. HTML gets five minutes. That’s the entire caching strategy.

Why not a platform?

Vercel or Cloudflare Pages would work well here. But I already run a box for my other services, and I like knowing where every byte comes from.