All Articles

1091 articles in total

Building an Org-Wide Admin Console with GitHub App + Cloudflare Access

Notes on building an admin console where non-engineers can trigger deploys and data updates for multiple database sites without GitHub or Vercel accounts. Combines GitHub App authentication with Cloudflare Access (Zero Trust), and walks through how PAT, OAuth App, and GitHub App differ.

githubgithub-appcloudflarecloudflare-access

Why Drupal's Automatic Updates Wasn't Running: `Unattended background updates` Is Disabled by Default

I assumed having Drupal's Automatic Updates module installed meant security updates would just land. They weren't. The cron-time policy `Unattended background updates` ships disabled by default, so the module was effectively idle. This post records the diagnosis, the configuration that finally let 10.6.3 → 10.6.7 apply automatically, and the 'not officially supported' warning that surfaces once you turn it on.

drupalautomatic-updatessecuritycron

🛡Defending Against Bot Pivots with AWS WAF Geo Allowlists and ASN-Based IPSets

A record of how attackers pivoted to HK/VN/ID/DE after a Singapore Geo Block was applied, and how I switched to a Geo allowlist plus Tencent/Alibaba ASN-based IPSets

awswafcloudfrontsecurity
Members

ElevenLabs v2 vs v3 for Japanese Tech Narration — A/B Comparison Using a Voice-Cloned Synthetic Voice

I ran an experiment narrating Japanese tech-blog articles with a voice-cloned synthetic voice trained on my own speech, using ElevenLabs Voice Cloning + the eleven_v3 model. This post records an A/B comparison of v2 and v3 on identical narration material, plus operational notes.

elevenlabsvoice-cloningpodcastyoutube

Mirador 4.0.0 hides supplementing annotations from the Annotations panel — a `filteredMotivations` gotcha

I delivered IIIF Presentation 3 OCR text annotations with `motivation: "supplementing"`, and they showed up in Annona and other viewers but not in Mirador 4.0.0's Annotations side panel. Reverse-engineering the deployed Mirador bundle revealed that the released default for `config.annotations.filteredMotivations` is `['oa:commenting', 'oa:tagging', 'sc:painting', 'commenting', 'tagging']` — `supplementing` isn't in the allowlist. This post walks through how I found that, the `['commenting', 'supplementing']` array workaround, and the relevant spec / Cookbook references.

iiifmiradorannotationpresentation-api

Building an Access-Controlled IIIF Digital Archive — Cantaloupe + S3 + Elasticsearch + Next.js, Gated by Cloudflare Access

An implementation log for a digital archive that delivers historical photographs which cannot be made fully public, while still preserving the benefits of IIIF (spec-compliant high-resolution viewer, manifest delivery) for an authorized membership. The stack is Cantaloupe (IIIF server) + S3-compatible storage + Elasticsearch (search) + Next.js (UI) + Cloudflare Tunnel + Access. We also lay out where IIIF Auth API 2.0 would fit in for cross-host interoperability.

iiifcantaloupeelasticsearchnextjs

📅Auto-filling Chouseisan attendance with Playwright, deciding answers via Claude Code's Google Calendar MCP

A small CLI that automates attendance responses on Chouseisan (chouseisan.com) using Playwright. The decision part — whether each candidate slot should be ◯/△/× given the user's Google Calendar — is delegated to Claude Code via the claude.ai Google Calendar MCP. The workflow is split into three independent stages (fetch / fill / submit), and decision rules live in CLAUDE.md.

playwrightclaude-codemcpgoogle-calendar

Comparing NDL Koten OCR-Lite and Cloud Vision API on a Jiaxing Tripitaka 'Mahāprajñāpāramitā Sūtra' — Observations across 105 Images

We applied two OCR engines — Japan's National Diet Library NDL Koten OCR-Lite and Cloud Vision API DOCUMENT_TEXT_DETECTION — to 105 IIIF images of fascicles 571–575 of the Mahāprajñāpāramitā Sūtra in the Jiaxing Tripitaka held by Yūrenja (formerly the Hōonzō of Zōjōji), and compared the patterns of error in their outputs. NDL produced phantom kana lines on 12 pages; Vision picked up color charts, rulers, and shelf labels as if they were body text on all 105.

ocrndl-koten-ocrgoogle-vision-apiiiif

🖼️Migrating an IIIF Image Server from Cantaloupe to serverless-iiif

Notes on migrating a Cantaloupe-based IIIF image server running on EC2/Docker to a serverless setup on AWS Lambda + CloudFront (serverless-iiif by Samvera).

iiifawslambdacloudfront

💀Retiring a Stale Service Worker After a Framework Migration Using a Kill-Switch SW

Immediately after migrating a Nuxt 2 + @nuxtjs/pwa SPA to a different framework, some users kept seeing frozen, outdated HTML. The cause was the old Service Worker's cache-first strategy. This post documents the procedure for retiring it by serving a kill-switch SW at the same URL.

serviceworkerpwanuxtnextjs

Routing an Externally Managed Subdomain to Cloudflare Workers — Adding AWS CloudFront + WAF as a Front Layer

An attempt to assign a subdomain managed by an external organization's DNS as a Cloudflare Workers custom domain hit the constraint that Cloudflare's free plan doesn't accept external subdomains as zones. The final solution was to place AWS CloudFront + WAF in front as a termination layer.

cloudflareworkerscloudfrontaws

Stopping Bot Scraping with AWS WAF — Geo Block, JA3 Fingerprint, and UA Block in Stages

A record of blocking bot scraping against a cultural-archive site using AWS WAF, combining Geo block, IPset, JA3 fingerprint, and UA block in stages.

awswafcloudfrontsecurity

📚DH Weekly Topics — 2026年4月19日週

DH Weekly Topics — 2026年4月19日週

dhweeklydigitalhumanitiesデジタルアーカイブocr

Retrofitting CloudFront + WAF onto an Existing Reverse-Proxy Origin: Practical Patterns

An implementation log of migrating a group of services running on Docker + Traefik, with no downtime, to a CloudFront + WAF-protected setup. I cover naming for the origin-only subdomain, pitfalls with shared Security Groups, the case for starting WAF in COUNT mode, cache design for SPARQL/API traffic, and other recurring decision points.

awscloudfrontwafterraform

Generating CiNii Articles Links from a Researcher Number — How the NII Researcher ID Works

By prefixing a KAKENHI researcher number (8 digits) with 1000, you can mechanically generate a CiNii Articles URL. This also applies to populating university faculty information systems.

ciniikakenniiresearcher-info

📚DH Weekly Topics — 2026年4月12日週

DH Weekly Topics — 2026年4月12日週

dhweeklydigitalhumanitiesデジタルアーカイブocr

🤖Exposing vLLM on mdx.jp Through Cloudflare Tunnel as an OpenAI-Compatible API

How I exposed a vLLM server running on mdx.jp through Cloudflare Tunnel and used it as an OpenAI-compatible API, including the practical pitfalls

cloudflaretunnelzerotrustvllm

🚀Serving LLM-jp-4 32B Thinking on mdx.jp A100 x2 with vLLM and Using It via an OpenAI-Compatible API

Notes from running the official LLM-jp-4-32b-a3b-thinking model on an mdx.jp A100 40GB x2 server and switching from a Transformers OOM to a vLLM deployment

aillmgpuvllm

🧪Running LLM-jp-4 Locally on a MacBook Pro M4 Max 128GB with Ollama’s OpenAI-Compatible API

Notes and measurements from running LLM-jp-4 8B locally on a MacBook Pro M4 Max 128GB and exposing it through Ollama’s OpenAI-compatible API

aillmmacollama

Securing SSH with Cloudflare Zero Trust

How to securely connect to a server via SSH without opening any ports, using Cloudflare Zero Trust Access

cloudflarezerotrustsshsecurity