Hello, IPFS
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 ENS —
mysticryuujin.ethpoints 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: 1reproduces 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: carheader.ipfs dag exportthe 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. 🌐