Crazy Idea to Postgres in the Browser
We just launched our Postgres Playground. Running Postgres in the web browser was not exactly commonplace before, so naturally, people are wondering how it works.
It actually started as a fun weekend experiment. Here's a screenshot I saved, just moments after recovering from the initial "whoa, it's working!" effect.
The next morning, I shared this screenshot in our internal Slack channel for web frontend engineering. Our mental gears began to turn as we imagined what might (and might not) be possible. After a bit of work, we built upon some interesting ideas, and this fun weekend hack evolved into what is now the Postgres Playground!
This blog post focuses on how to run PostgreSQL in the web browser, but there are other interesting pieces involved in the playground as well. For example, the content in the tutorials actually lives in Notion documents. There may be a blog post about that in the near future from one of my colleagues, so stay tuned!
I stumbled upon an interesting blog post about how Wasmer has a "Run in Playground" link for some Markdown fenced code blocks for a few of their WAPM packages. There was one in particular that really got my attention: SQLite. On that page, there is a fenced code block with some SQL queries inside. If you click the "Run in Playground" button, it runs the query right there in the web browser with SQLite compiled to WebAssembly.
After running that SQLite query in my browser, I thought, "Can I do this with Postgres?".
The modern web browser is a very powerful platform, and this platform's capabilities are constantly increasing. However, WebAssembly still has some growing to do in some areas. After some quick research, I found that the web browser simply does not offer the networking features that Postgres needs. That would seem like a pretty big obstacle.
As I mentioned, the modern web browser is a very powerful platform. Let's just change the target platform to something other than WebAssembly, then run it in WebAssembly anyway like a rebel. 😎
Virtual machines in the browser
|JSLinux||x86 and RISC-V|
I ended up choosing v86 for this. The author started the project in 2011, and it's still active. Many questions have been answered in the GitHub issues and discussions over the years. I'm definitely not an expert in Linux or virtualization, so being able to search the repo for answers was very helpful.
For this blog post, we'll use Alpine Linux. It's a lightweight Linux distribution and a very popular base for many Docker images. They also have a version with a slimmed-down kernel, optimized for virtual machines.
Install Alpine Linux
Note: You'll need to have QEMU installed.
Download the Alpine image that is optimized for VMs. We'll need the x86 (not x86_64) build.
Create a disk image for the VM. I chose my disk size somewhat randomly, so feel free to make it larger if you'd like. You could probably make it smaller, but I'm not sure what the minimum size limit would be here.
qemu-img create alpine.img 512M
Start the VM
qemu-system-x86_64 \ -m 256M \ -cdrom alpine-virt-3.16.0-x86.iso \ -drive file=alpine.img,format=raw
Note: Depending on your host machine, you may be able to get a performance boost by appending another argument to the command:
|Linux with x86 CPU||
|macOS with x86 (Intel) CPU||
|macOS with Apple Silicon||None, but your CPU is a beast anyway.|
When the VM has finished booting, log in as 'root'.
setup-alpine. For most of the setup questions, you can configure things to
your liking, but these are important:
After the installation has finished, use the
reboot command to reboot the VM
from the virtual hard disk image.
After the VM has rebooted, log in as
root again. We can now install and
apk add postgresql --no-cache /etc/init.d/postgresql setup /etc/init.d/postgresql start rc-update add postgresql
Now, a quick smoke test:
su - postgres -c 'psql -c "SELECT version();"'
If it worked, you should see something like this:
version ---------------------------------------------------------------------------------------------------------------- PostgreSQL 14.4 on i586-alpine-linux-musl, compiled by gcc (Alpine 11.2.1_git20220219) 11.2.1 20220219, 32-bit (1 row)
Note: On my machine,
psql opened the version information in
less, so I had
q to exit that.
Now we can shut down the VM.
Run the VM in the web browser
- Go to v86's site.
- Scroll down to the "Setup" section.
- For "Hard disk drive image", select the
alpine.imgfile you created earlier.
- Adjust "Memory size" to your liking. (I used 256 MB)
- Click the "Start Emulation" button.
Note: It will take a bit longer for the VM to boot. Running the VM in the web browser will not be as fast as it was in QEMU.
After it has finished booting, log in as root, then open
su - postgres -c psql
Congratulations! You are now running Postgres in your web browser.
Things to keep in mind:
- There is no internet access from inside the VM.
- There is no data persistence, so changes are lost when leaving or refreshing the page.
August 24, 2022 •More by this author