September 14, 2020 By Matthew Rathbone

Beekeeper Studio is an open source SQL editor and database manager built with Vue.js and Electron. Thanks to Electron it works the same on Mac, Linux, and Windows.

Part of our mission is to improve technology accessibility, so we want to make sure Beekeeper Studio runs on as many devices as possible.

Now when I think of accessible computing, one device in particular comes to mind. That device is the Raspberry Pi.

Surely it couldn’t be that hard to get Beekeeper running on the Raspberry Pi?

Electron Builder and ARM

We build Beekeeper Studio using Electron Builder, a fantastic project that greatly simplifies Electron building, packaging, and updating.

Electron builder has built-in flags for building arm64 and armv7l binaries. But alas, it’s not as simple as just setting those flags.

ARM apps have to be built on ARM machines

Because Electron apps require a bunch of native binaries, if you want to run an ARM build, you have to run it on an ARM box, so that you can build-in the right versions of the binaries.

Technically this isn’t always true if there are pre-packaged versions of libraries to link against, but in reality best to just assume this is a fact.

So step 1: Get hold of an ARM machine. We use a Raspberry Pi 4 (8gb) running Ubuntu 20.04 for testing and ad-hoc builds, and also an a1.large ARM instance on Amazon Web Services (also running Ubuntu) for our build pipeline, but you can just use a Raspberry Pi if you like.

Are we done?

In theory (THEORY) you should be able to just run yarn run electron:build to create deb, rpm snap, and AppImage builds right now.

AppImage builds WILL work right out of the gate, for both arm64 and armv7l architectures, but the others will not.

Fixing DEB and RPM Builds for ARM

Electron Builder uses FPM to build DEB and RPM files. Typically Electron Builder will download Ruby and FPM to a local directory automatically to make it work.

When you try to build you’ll get the following error:

Cannot execute  cause=exit status 1
  errorOut=/home/rathboma/.cache/electron-builder/fpm/fpm-1.9.3-2.3.1-linux-x86/lib/ruby/bin/ruby: line 6: /home/rathboma/.cache/electron-builder/fpm/fpm-1.9.3-2.3.1-linux-x86/lib/ruby/bin.real/ruby: cannot execute binary file: Exec format error

If you look closely at the error you can see that electron-builder is trying to use an x86 version version of FPM. This is [hard coded][https://github.com/electron-userland/electron-builder/issues/5154], and so does not work on an ARM box.

Luckily there is a workaround - Install Ruby, Rubygems, and FPM, then set the totally undocumented USE_SYSTEM_FPM environment variable to true.

sudo apt install ruby ruby-dev
sudo gem install fpm

Then when you run your build:

USE_SYSTEM_FPM=true yarn run electron-builder build --linux deb rpm --arm64 --armv7l

You should now have some lovingly crafted DEB and RPM files.

Fixing Snap Builds for ARM

The snap store supports distributing both x86 and ARM binaries (yay), but unfortunately the build chain for snaps is totally broken on ARM devices right now. There’s a work around, but it probably won’t work on all ARM devices.

The short version is that snap packages are build using the snapcraft binary (provided by a snap named snapcraft), but that depends on a virtualization packages called Multipass.

Guess what doesn’t work on most ARM devices (hint: It’s multipass).

Here’s the error if you try to run a snap build straight off:

Launching a VM.
Build environment is in unknown state, cleaning first.
delete failed: The following errors occurred:
instance "snapcraft-beekeeper-studio" does not exist
An error occurred with the instance when trying to delete with 'multipass': returned exit code 2.
Ensure that 'multipass' is setup correctly and try again.

In fact, we can check if Multipass will work by running multipass launch. On my ARM boxes I get the following error.

launch failed: Cannot check BIOS for determining KVM extensions support.        
Unable to load KVM support. Please ensure KVM is installed on your machine.

There’s some fancy way to get snapcraft using LXD instead of Multipass or something like that, but it’s all terribly confusing.

The workaround I found was to use the (also undocumented) environment variable SNAPCRAFT_BUILD_ENVIRONMENT, and set it to host. This tells the snapcraft binary to not spin up a VM, but to just build the snap on the local host, thank you very much.

SNAPCRAFT_BUILD_ENVIRONMENT=host yarn run electron-builder build --linux snap --arm64 --armv7l

Creating our Final ARM Packages

We can combine these flags together to create all of our linux packages in one swoop:

export SNAPCRAFT_BUILD_ENVIRONMENT=host
export USE_SYSTEM_FPM=true
yarn run electron:build --arm64 --armv7l --linux

We’re finally ready to upload our snaps to Snapcraft, create Apt and Yum repos, and distribute AppImages.

Beekeeper Studio, Coming to a Raspberry Pi Soon

I hope this helps you build your Electron apps for Raspberry Pi and ARM. As you read this we’re preparing for our next release of Beekeeper Studio with full Raspberry Pi and ARM support.

We hope more Electron developers will join us on an ARM device soon! (especially you Signal!).