How I Built a 19,000-Page Website From My Android Phone Using Termux
No laptop. No desktop. Just an Android phone, Termux, and a problem I wanted to solve.
I run Moviepiq, a movie discovery site built around one core idea: people don't search for genres, they search for feelings. "What to watch when I can't sleep." "Movies for when I feel stuck in life." "Something that feels like a warm hug."
So I built it. 19,000+ pages of curated film lists organized by mood, occasion, energy state, and emotional outcome. All from my phone.
Here is the actual stack and the architecture that makes it work for zero hosting costs.
The Architecture
Static article pages sit on Cloudflare Pages, connected to a GitHub repo. Every git push from Termux triggers a Pages deploy automatically via GitHub Actions. No heavy continuous integration (CI) setup was required beyond connecting the repo once.
The programmatic list pages, however, are a different beast entirely. 19,000 pages cannot live in a standard git repo without absolutely killing build times.
Instead, they live in Cloudflare R2 and are served by a Cloudflare Worker called moviepiq-lists-worker. The Worker intercepts every request to /lists/, /lists2/ through /lists6/, fetches the raw HTML from R2, and processes everything at the edge.
[User Request to /lists/movie-slug]
│
▼
[Cloudflare Worker]
│
├───► (Fetches raw HTML from Cloudflare R2)
│
▼
[Worker Edge Processing: Injects Canonical, OG Tags, Speculation Rules, Geo-Banner]
│
▼
Final Rendered Page to User
The Worker handles a massive amount of logic—around 3,000 lines of JavaScript running on every single list page request. At the edge, it handles dynamic canonical rewriting, Open Graph (OG) tag injection, hreflang implementation, article timestamps, robots meta, and injecting Speculation Rules for instant browser prerendering.
The Page Generation Matrix
Each list tier is generated by a Python script running locally in Termux. The scripts call the TMDB API to pull real-time film data, build complete HTML pages with structured data, create sitemap entries, and push them to R2 via the Cloudflare API.
None of this code ever touches git. Committing 19,000 HTML files would destroy build times and burn through free GitHub Actions minutes instantly.
Directory Slug | Page Count | Combination Logic / Matrix
/lists/ | 2,416 pages | 7 genres × 14 occasions × 19 mood slugs
/lists2/ | 12,600 pages | 12 genres × 14 occasions × 15 moods × 5 eras
/lists3/ to /lists6/ | 4,000+ pages | Energy states, emotional microstates, cognitive states
The Termux Workflow & Environmental Gotchas
Everything runs in Termux on Android. Git operations happen through the Termux git client, and Python handles the data processing.
Developing on a mobile terminal environment comes with incredibly specific limitations. Here are the environment rules I learned the hard way:
- Never use /tmp: It does not exist in the Android/Termux environment directory tree. Always default to $TMPDIR.
- Heredoc + Pipe limitations: Standard heredocs combined with pipes tend to fail or hang in Termux. Write your scripts to $TMPDIR/script.py first, then execute them.
- Piping output: Always pipe heavy terminal output to termux-clipboard-set so you can instantly paste data into mobile apps or browsers.
- File Operations: Skip sed entirely for heavy text manipulation. Python is vastly more stable and reliable for regex and file operations on Android.
- Worker Management: The Cloudflare dashboard editor does not save reliably on mobile browsers. Deploy exclusively via API curl commands. For example, handling geolocation and asset optimization without an origin server means mapping hundreds of global routing targets down to precise, zero-allocation variables directly inside the edge cycle: function injectGeoBanner(html, country) { if (!country || html.includes('data-mpiq-geo')) return html; const COUNTRY_NAMES = { 'NG':'Nigeria', 'GH':'Ghana', 'KE':'Kenya', 'ZA':'South Africa', 'EG':'Egypt', 'US':'the US', 'CA':'Canada', 'MX':'Mexico', 'UK':'the UK', 'DE':'Germany' // ... maps 60+ countries globally directly at the edge }; const name = COUNTRY_NAMES[country] || 'your country'; const banner = Trending in ${name}; return html.replace('', '' + banner); } By keeping environmental configurations mapped explicitly within the script payload itself, updates are deployed natively from a terminal prompt without needing heavy build steps: curl -X PUT "https://api.cloudflare.com/client/v4/accounts/$CF_ACCOUNT_ID/workers/scripts/moviepiq-lists-worker" -H "Authorization: Bearer $CF_API_TOKEN" -H "Content-Type: application/javascript" --data-binary @worker_patched.js Overcoming Edge Case Problems
- Stripping Extensions at the Edge Cloudflare Pages automatically strips .html from URLs and serves clean slugs. Because my list pages are pulled dynamically from R2, the Worker has to mimic this exact behavior. Every canonical tag, OG URL, and internal href link is rewritten programmatically at the edge to strip .html before the response hits the user.
- The GitHub Actions Mirror Hack Because GitHub Actions free accounts have a monthly limit on build minutes, high-volume updates can exhaust them. To bypass this, I created a mirror repository (ayoreeth/weefilm-mirror) connected to a secondary Pages project. When the main repo hits its limit, I point my Termux push script to the mirror. Two repos, one site, seamless swapping when minutes run low.
- Surgical Cache Purges On Cloudflare's free plan, a complete "Purge Everything" request can leave the site unstable or slow for up to 15 minutes while the cache re-primes. Furthermore, scoping API tokens for global purges can be restricted on mobile setups. The workaround? I perform highly targeted, URL-level surgical purges directly when content changes, keeping the edge cache highly optimized. Why Android? Honestly, because it's what I have right now. But looking back, the constraint forced a workflow that is incredibly clean, fast, and resilient. Everything is scripted, everything is automated, and nothing depends on a heavy desktop GUI. The site runs entirely on Cloudflare's global edge infrastructure—no origin server, no VPS maintenance, and zero hosting costs. 19,000 pages. One phone. Termux. The site is https://moviepiq.com if you want to see what the final edge-rendered product looks like.













