WordPress / wordpress-playground

Run WordPress in the browser via WebAssembly PHP
https://w.org/playground/
GNU General Public License v2.0
1.58k stars 222 forks source link

Run on Cloudflare Workers #69

Open batonac opened 1 year ago

batonac commented 1 year ago

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

adamziel commented 1 year ago

+1, I'd love this to happen!

adamziel commented 1 year ago

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 commented 1 year ago

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:

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 commented 1 year ago

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.

jdevalk commented 11 months ago

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

bdurette commented 6 months ago

lowercase-f-dangit πŸ˜‰

fernandodilland commented 2 months ago

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

adamziel commented 2 months ago

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

Nice!