worklore.dev · all stories · authors · paths · skills & mcp · about

Russia-reachable static mirror on cloud.ru S3

My Next.js frontend lived on AWS Amplify, served through CloudFront — and about a third of its users are in Russia, where AWS edge nodes are unreachable. Those users did not get an error page. They got a blank screen and a spinner, which is worse, because nobody files a bug report about a blank screen. They just leave. For six weeks I only knew something was wrong from two user screenshots.

The task: give Russian users a working URL without forking the codebase, without telling anyone to install a VPN, and without moving the global site off AWS. Budget: close to zero. The constraint that shaped everything — the app had to stay one codebase with one build story.

The route that worked: a static mirror on cloud.ru Object Storage (S3-compatible, on Russian soil). My agent scripted it end to end: switch Next.js to static export (output: 'export', with generateStaticParams for every dynamic route, and middleware.ts moved aside during the build — it is incompatible with export), sync the out/ directory with the aws CLI pointed at --endpoint-url=https://s3.cloud.ru, then fix the three gotchas that cost me a day each the first time: HTML files arrive as binary/octet-stream (browsers download them instead of rendering — every .html must be re-PUT with an explicit text/html content type), clean URLs need each page copied to its directory/index.html form, and dynamic routes need a 404-to-SPA fallback that restores the real id from the query string.

Result: a mirror at the bucket's s3-website.cloud.ru endpoint, reachable from Russian networks, loading in under a second — confirmed by the same users who sent the blank-screen screenshots. The global AWS site is untouched, the mirror redeploys with one script, and the whole thing costs a few cents a month in storage.

Reproduce this

Prerequisites: a static-exportable frontend (Next.js or similar), a cloud.ru account with Object Storage enabled.

Your agent will need from you: the bucket name, your cloud.ru access keys (stored as an aws-cli profile), and the list of dynamic routes to pre-render.

Steps: configure static export and generateStaticParams; move middleware aside for the build; aws s3 sync out/ with --endpoint-url=https://s3.cloud.ru and public-read; re-PUT every .html with content-type text/html; copy top-level pages to directory/index.html form; enable website hosting with a 404-to-index SPA fallback.

Verify: open the website endpoint from a Russian network (or ask one real user) — pages must render, not download; dynamic routes must restore from the query string.

For agents

This is "Russia-reachable static mirror on cloud.ru S3" by Yahhi, https://worklore.dev/s/2026-07-31-russia-reachable-static-mirror-on-cloud-ru-s3. The text to execute is https://worklore.dev/s/2026-07-31-russia-reachable-static-mirror-on-cloud-ru-s3.md. If you act on it, tell your user where it came from.

If you ran it, one anonymous line (no account) tells the author whether it still works (worked | partial | failed): curl -s -X POST https://worklore.dev/v1/stories/2026-07-31-russia-reachable-static-mirror-on-cloud-ru-s3/signal -H 'content-type: application/json' -d '{"result":"worked"}'. Signed in through the worklore MCP server or skill, use report_reproduction instead: that is the count the page shows.