Announcing WCGI: WebAssembly + CGI
WCGI - Revolutionizing Server Development with WebAssembly and CGI
Founder & CEO
April 6, 2023
Welcome to the future of server-side development with WebAssembly!
Today we are introducing WCGI, a technology that marries the power of WebAssembly with the
versatility and simplicity of CGI.
Here are some of WCGI's highlights:
- You can reuse your existing CGI applications by compiling them to WASI (AssemblyScript, C, C++, Go, PHP, Python, ...)
- Ship ultra-small packages that will only contain your business logic and static assets, no HTTP stack or bulky Docker containers
- Completely sandboxed execution: WebAssembly code runs in a sandbox, with one isolated instance per request
Picture running Wordpress and not having to worry about attackers breaking into your system. With WCGI, now this a reality!
Try Wordpress locally with Wasmer
Edit (March 2024): Since the publish this of this article we have released a full PHP implementation that is able to run any PHP apps thanks to WASIX, we recommend using this instead. Read more about it here: https://wasmer.io/posts/running-php-blazingly-fast-at-the-edge-with-wasm
# Install wasmer
curl https://get.wasmer.io -sSfL
# Execute Wordpress
mkdir db
wasmer run-unstable wasmer/wcgi-wordpress-demo --mapdir=/db:db
We are trialing the new runner architecture via
wasmer run-unstable
. In the future you would simply usewasmer run
The Why Behind WCGI
When venturing into serverless solutions at Wasmer, we faced a crucial question: should we create our own framework and risk locking developers into a walled garden, or should we adopt an open standard that allows them to utilize existing code?
CGI's alignment with the goal of executing a program per HTTP request makes it a compelling choice. Interestingly, CGI can outperform many other solutions (such as WSGI in Python/Ruby or NodeJS) in terms of scalability and latency in serverless environments.
Furthermore, it also closely mirrors the workers proposal from the Winter Community Group.
Consider the challenge of running PHP programs on servers. We have two primary options:
- Wrap the PHP interpreter with a layer that instruments each HTTP call
- Use the existing
php-cgi
program and simply compile it to Wasm
Option 2 is not only faster, but it also enables any web application on Wasmer more efficiently.
By embracing WCGI, those seeking to achieve greater efficiency, security, and flexibility in server-side development can truly benefit from this approach.
Creating a WCGI Application with Rust
To create a WCGI application using Rust, first add the cgi
crate as a
dependency in your Cargo.toml
file:
$ cargo add cgi
Next, write your Rust server, like the example below:
// src/lib.rs
use cgi::{http::StatusCode, Request, Response};
fn main() {
cgi::handle(handler);
}
fn handler(request: Request) -> Response {
let who = String::from_utf8_lossy(request.body());
let who = if who.trim().is_empty() {
"World"
} else {
who.trim()
};
cgi::text_response(StatusCode::OK, format!("Hello, {who}!"))
}
After writing your implementation, compile it to the wasm32-wasi
target.
You may need to install the WASI target if you haven’t already (rustup target add wasm32-wasi
).
$ cargo build --target wasm32-wasi --release
Create a wasmer.toml
file that describes your package and contains a WCGI
command that the wasmer
CLI will execute.
[package]
name = "wasmer/wcgi-rust-template"
version = "0.1.0"
description = "A template for WCGI applications"
license = "MIT OR Apache-2.0"
readme = "README.md"
repository = "https://github.com/wasmerio/wcgi-rust-template"
[[module]]
name = "server"
source = "target/wasm32-wasi/release/wcgi-rust-template.wasm"
abi = "wasi"
[[command]]
name = "server"
runner = "wcgi"
module = "wcgi"
annotations = { wcgi = { dialect = "rfc-3875" } }
Now you can start the server and browse to http://localhost:8000/ to see it in action:
$ wasmer run-unstable .
Creating a WCGI Application in PHP
PHP-CGI was first introduced by Rafael Fernández López.
Thanks to his original version of php-cgi
compiled to WebAssembly & WASI,
Wasmer can now run PHP websites using WCGI.
First, create a new repository and copy
php-cgi.wasm
into it. Then, create an app/
directory and add some PHP code to it.
$ mkdir app
$ echo '<? print("Hello, World!"); ?>' > app/index.php
Now we need to create a wasmer.toml
file.
This is a bit longer than the Rust one because we need to set some environment
variables that tell php-cgi
which script to invoke. We also want the app/
folder to be bundled with the package when we publish it.
[package]
name = "wasmer/wcgi-php-template"
version = "0.1.0"
description = "A PHP template for WCGI applications"
license = "MIT OR Apache-2.0"
readme = "README.md"
repository = "https://github.com/wasmerio/wcgi-php-template"
[[module]]
name = "php"
source = "php-cgi.wasm"
abi = "wasi"
[[command]]
name = "php"
runner = "wcgi"
module = "php"
[command.annotations.wcgi]
dialect = "rfc-3875"
[command.annotations.wasi]
atom = "php"
env = ["DOCUMENT_ROOT=/app", "SCRIPT_FILENAME=/app/index.php"]
[fs]
"app" = "app"
You can now run this with wasmer run-unstable
:
$ wasmer run-unstable .
Opening up our web browser shows the “Hello, World” message as expected.
You can also use the wasmer
CLI’s --mapdir
flag to make specific directories
on your host machine available to the WebAssembly application.
This is really useful during development because it means you can mount your
app/
directory and make changes on the fly without needing to restart the WCGI
server.
First, start the WCGI server and tell it that the /app
directory inside the
WebAssembly application corresponds to the ./app
directory on your host.
$ wasmer run-unstable --mapdir /app:./app .
If you open http://localhost:8000/ up in your browser, you should see the “Hello, World!” from before.
Next, modify app/index.php
to print phpinfo()
, hit save, and refresh your
browser.
This package is also available on WAPM.
$ wasmer run-unstable wasmer/wcgi-php-template
You can find in Github the source code for the Wordpress Wasmer pacakage, and the PHP WCGI template.
We can't wait to see what you create next with WCGI!
In Summary…
WCGI represents a refined approach to server-side development, integrating the flexibility, security, and performance of WebAssembly. This innovative technology has the potential to reshape the landscape of serverless applications, providing developers with a powerful and versatile solution for their projects.
Watch this space 😉
About the Author
Syrus Akbary is an enterpreneur and programmer. Specifically known for his contributions to the field of WebAssembly. He is the Founder and CEO of Wasmer, an innovative company that focuses on creating developer tools and infrastructure for running Wasm
Founder & CEO
Try Wordpress locally with Wasmer
Install wasmer
Execute Wordpress
The Why Behind WCGI
Creating a WCGI Application with Rust
Creating a WCGI Application in PHP
In Summary…
Read more
wasixengineeringepollruntime
Boosting Performance: Integration of epoll syscall in WASIX
RudraAugust 8, 2023