Run Fn Project on your Raspberry Pi

Pavel Varchenko
4 min readFeb 6, 2018

--

I have a cluster of Raspberry Pi for my pet-projects and believe that serverless is very good for home automation. Couple months ago I started to use Fn Project. But currently we can’t use standard way to install it on computers with arm32 architecture. Next I’ll explain some custom steps to run Fn on your Raspberry Pi and call Java function.

Step 1: Prepare environment

As you might know Fn consists of several components. To run Java-function we’ll use following:

  • Fn Server;
  • Command line interface;
  • Java function development kit.

To run functions you have to install docker

curl -sSL https://get.docker.com | sh

We will build Fn by ourselves. Fn developers recommend to use go lang version ≥ 1.9.1. At this moment latest version is 1.9.2. So let’s install it.

$ wget https://dl.google.com/go/go1.9.2.linux-armv6l.tar.gz
$ sudo tar -C /usr/local -xzf go1.9.2.linux-armv6l.tar.gz

Add /usr/local/go/bin to the PATH environment variable. You can do this by adding this line to your /etc/profile (for a system-wide installation) or $HOME/.profile:

export PATH=$PATH:/usr/local/go/bin

Check that go is installed

$ go version
go version go1.9.2 linux/arm

Next install dep — package manager for go and check it.

$ go get -u github.com/golang/dep/cmd/dep
$ sudo cp ~/go/bin/dep /usr/local/bin/
$ dep version
dep:
version : devel
build date :
git hash :
go version : go1.9.2
go compiler : gc
platform : linux/arm

Step 2: Install Fn Server

For simplicity Fn server will be started not in Docker. Build it form sources:

$ mkdir -p go/src/github.com/fnproject && cd go/src/github.com/fnproject
$ git clone https://github.com/fnproject/fn.git
$ cd fn/

Install dependencies (it may take a few minutes), build from sources and run it:

$ make dep
$ make build
$ sudo ./fnserver

Now we that server is running =)

$ curl localhost:8080
{“goto”:”https://github.com/fnproject/fn","hello":"world!"}

I advice to use server via systemd

$ sudo cp ~/go/src/github.com/fnproject/fn/fnserver /usr/local/bin/
$ sudo touch /etc/systemd/system/fnserver.service
$ sudo systemctl enable fnserver
$ sudo systemctl start fnserver
$ systemctl status fnserver

Now Fn server will start automatically.

Step 3: Install command line interface

The command line tool isn’t required, but it sure makes things a lot easier. There are a few options to install it:

$ cd go/src/github.com/fnproject
$ git clone https://github.com/fnproject/cli.git
$ cd cli/
$ make dep
$ make build
$ sudo cp ~/go/src/github.com/fnproject/cli/fn /usr/local/bin/
$ fn version
Client version: 0.4.37
Server version: 0.3.297

Nnnice! We now have CLI tool!

Step 4: Make Java function

Finally let’s build Java function. As a progressive developers we’ll use Java 9 (Java 10 already on the way).

$ mkdir hello-java-function-rpi && cd hello-java-function-rpi
$ fn init --runtime=java9 --name {your_dockerhub_account}/hello-fn-rpi
Runtime: java9
Function boilerplate generated.
func.yaml created.

File func.yaml contains configuration for your function. As you can see it use two docker images: for build and runtime. We’re not available to use them because root docker image is incompatible with arm32. So we will use other images.

Build image fnproject/fn-java-fdk-build:jdk9–1.0.56 contains jdk 9, maven 3 and instructions to add project dependency cache. It allows to reduce assembly time.

Runtime image fnproject/fn-java-fdk:jdk9–1.0.56 contains jdk 9 and instructions to run your java-function.

I use arm32v7/maven:3.5-jdk-9-slim for build image. By the way, the repository arm32v7 contains many useful images for Raspberry Pi

For runtime image I wrote different Dockerfile

In addition to changing the parent image, there is one more nuance. The option -Xshare is disabled, which allows us to speed up the start of our application. The option is disabled, as it is not supported on the arm32 architecture. Here is an interesting blog about class data sharing and the official documentation.

That’s all. The infrastructure for the launch is ready. Change your func.yaml and build the project

$ sudo fn build
Building image varpa89/hello-fn-rpi:0.0.1
$ sudo fn run
Building image varpa89/hello-fn-rpi:0.0.1
Hello, world!
$ sudo fn deploy --app java-app --local
Deploying varpa89/hello-fn-rpi to app: java-app at path: /hello-java-function-rpi
Bumped to version 0.0.3
Building image varpa89/hello-fn-rpi:0.0.3
Updating route /hello-java-function-rpi using image varpa89/hello-fn-rpi:0.0.3…

So now you can check that java function of Fn Project can run on Raspberry Pi!

$ curl http://localhost:8080/r/java-app/hello-java-function-rpi
Hello, world!

Conclusion

Here is only proof of concept of usage Fn Project on Raspberry Pi and especially not official documentation. But here is the first step to adaptation it for arm32 processors.

--

--