wordpress-playground icon indicating copy to clipboard operation
wordpress-playground copied to clipboard

Run on Cloudflare Workers

Open batonac opened this issue 2 years ago β€’ 8 comments

This might be far out there, but here goes...

Since WordPress is working with WebAssembly and SQLite based on this project, how about expanding the scope from testing to production with Cloudflare Workers + CloudFlare D1 (SQLite database)?

Related issues

  • [ ] https://github.com/WordPress/wordpress-playground/issues/762

batonac avatar Nov 14 '22 15:11 batonac

+1, I'd love this to happen!

adamziel avatar Nov 16 '22 22:11 adamziel

I got PHP.wasm working in the local worker dev env provided by CloudFlare, I shared the setup below.

The bad news: I couldn't deploy it because of the 5MB size limitation – php_8_0.wasm is around 5.8MB. Maybe there's a way to get under 5MB πŸ€” I'm rebuilding PHP with no extensions and more aggressive optimizations to find out.

Edit: I got it down to 4.4MB!

src/index.js:

import { PHP } from './web/index-213897b2.js';
import wasm from './web/php_7_3.wasm'; 
const phpPromise = PHP.load('7.3', {
	emscriptenOptions: {
		instantiateWasm(info, receive) {
			phpError = JSON.stringify(Object.keys(info.a));
			let instance;
			try {
				instance = new WebAssembly.Instance(wasm, info)
			} catch (e) {
				phpError = e + 'thrown!';
				throw e;
			}
			phpError = instance+'';
			receive(instance)
			return instance.exports
		},
	}
}).then(loaded => {
	phpError = 'loaded in theory';
	php = loaded;
}).catch(e => {
	phpError = e;
});

let php;
let phpError;

export default {
	async fetch() {
		if (php) {
			const r = await php.run({
				code: `<?php echo "Hello World from PHP!"; ?>`
			})
			return new Response(
				r.text
			);
		} else {
			return new Response(
				phpError+'',
				{
					status: 500
				}
			);
		}
	}
}

wrangler.toml:

name = "playground-worker"
main = "src/index.js"
node_compat = true
compatibility_date = "2020-04-04"

src/web/php_7_3.js:

export const dependenciesTotalSize = 4428017; 
-import dependencyFilename from './php_7_3.wasm'; 
+const dependencyFilename = './php_7_3.wasm'; 

adamziel avatar Apr 14 '23 14:04 adamziel

Running WordPress on CloudFlare is not viable yet. Loading PHP alone exceeds CloudFlare 128MB memory limit by a tiny margin, and that doesn't even include loading WordPress files.

This issue is blocked until either PHP.wasm can run with much less memory or CloudFlare doubles the memory limit.

Longer version below:


I managed to deploy PHP into CloudFlare and now am running into this error when the worker was starting:

Error: Script startup exceeded memory limits. [code: 10021]

Then I've built PHP with a different set of options and the worker started, but the first request resulted in this error:

RangeError: WebAssembly.Instance(): Out of memory: Cannot allocate Wasm memory for new instance

CloudFlare platform limits for paid users are, as of today:

  • 5MB for worker files
  • 128MB memory

Measuring the memory required by the node.js build tells me it requires roughly 132MB – very narrow margin:

/usr/bin/time -l npx @php-wasm/cli -r 'echo "Hello, world";' 139237696 peak memory footprint

I've tried building PHP with the following options:

    -s INITIAL_MEMORY=128MB \
    -s ALLOW_MEMORY_GROWTH=0         \

But that didn't help.

adamziel avatar Apr 14 '23 15:04 adamziel

Here's a bit more info:

; /usr/bin/time -l wrangler dev  --experimental-local
(...)
            15798208  peak memory footprint

According to time, the web build running in a worker seems to peak around 15MB, far from the 128MB required for the node.js-based CLI.

However, maybe it's somehow off by one digit. Mac process monitor says 154.8 MB of real memory consumption.

adamziel avatar Apr 15 '23 10:04 adamziel

Seems the max size for a worker is now 10MB, so that bit’s solved. Memory limit still seems to be 128MB though.

jdevalk avatar Aug 03 '23 13:08 jdevalk

lowercase-f-dangit πŸ˜‰

bdurette avatar Dec 14 '23 21:12 bdurette

https://github.com/cloudflare/php-worker-hello-world

fernandodilland avatar Apr 26 '24 00:04 fernandodilland

This project uses babel-preset-php to convert PHP to JavaScript.

Nice!

adamziel avatar Apr 30 '24 12:04 adamziel