Hello, IPFS

ipfs ens ethereum meta

Welcome to the new site. The old WordPress install at chasewright.com is on its way out — fifteen years of PHP, plugins, database backups, and security updates, replaced by something radically simpler: flat files, content-addressed, served from anywhere.

Why bother?

A personal website doesn’t need a server. It needs to exist — preferably in a way that doesn’t depend on a single host staying online, a billing account staying current, or a WordPress plugin not getting popped.

This site is:

  • Astro building everything to static HTML at compile time
  • Added to IPFS and pinned on my own Kubo gateway node
  • Published over IPNS, so updates are free
  • Resolved through ENSmysticryuujin.eth points at the IPNS name

No database, no comments, no admin panel to patch. The ENS contenthash was a single transaction, ever. Publishing a new build is just:

edit markdown astro build ipfs add ipns publish

Anyone — including me, several times over — can pin the content, and the name keeps resolving to it.

The one weird trick: relative URLs

The thing that makes an IPFS website actually work is boring: every URL in the build output must be relative. The same site gets served at https://mysticryuujin.eth.limo/, at /ipfs/<CID>/ path gateways, and at subdomain gateways — absolute paths break at least one of them. Astro doesn’t do this natively; a small post-build integration (astro-relative-links) rewrites everything. The corollary rule: never reference assets from CSS url(), because nothing can rewrite compiled CSS safely. System fonts, inline SVG, <img> tags. Vitalik’s site has quietly followed this discipline for years — view-source on vitalik.eth and you’ll see ./css/main.css everywhere.

Pinning redundancy (and free-tier shenanigans)

The content lives on my own node, but a single home server is a single point of failure, so every deploy also pushes to two pinning services. Both turned out to gate “pin by CID” — the standard Pinning Service API — behind paid plans. Both have a free workaround:

  • Pinata: uploading the same files with cidVersion: 1 reproduces the byte-identical root CID. An upload is a pin if the DAG matches.
  • Filebase: their S3-compatible API accepts CAR files with an x-amz-meta-import: car header. ipfs dag export the build, PUT it to a bucket, and the response header confirms the same CID — exact-DAG import, free tier.

Same bytes, four places: my node, Pinata, Filebase, and a Cloudflare Pages mirror for the eventual chasewright.com cutover.

Migrating 10 years of WordPress

The 50 old posts came over via the WordPress REST API — wp-json is wide open on most WP sites, which is either convenient or terrifying depending on which side of it you’re standing on. A small script converted HTML to markdown, downloaded every image, fenced every code block (old pre-Gutenberg posts wrap code in bare <pre> tags that markdown converters silently mangle), and detected languages for syntax highlighting.

Credit where due: a bunch of the networking posts here — the VXLAN EVPN series, the Ansible posts — were written by Jason Miller back when this blog had two authors. His byline survived the migration.

Hat tips

This build leaned on the work of others:

  • Vitalik’s website — the proof that an ENS+IPFS personal site is a solved problem, and the inspiration to finally do it
  • ethskills by Austin Griffith — Claude skills that encode how Ethereum actually works today, including the IPFS deployment playbook this site started from
  • Claude Code — the entire build, migration, and deployment pipeline was pair-programmed with an AI agent, start to finish
  • The IPFS/Kubo, ENS, and eth.limo teams for infrastructure that just works

More posts soon — this one exists to prove the pipeline works. If you’re reading it over IPFS: hello from the permanent web. 🌐

← All posts