running Function as a Service on Oracle Cloud Infrastructure – fnproject.io

This blog will cover running function as a service specifically on Oracle cloud infrastructure

Following Steps are required to get this done

  1. Run Ubuntu Instance or any Linux Instance on Oracle Compute Infrastruture
  2. Upgrade Ubuntu instance to 16.04
  3. Install Docker Container
  4. Install Function as a Service Packages from fnprojects.io
  5. Open security port 4000 on Oracle Compute Infrastructure
  6. Deploy Run Functions
  7. Monitor function success and failures

Setup Ubuntu or Oracle Linux Instance on Oracle Cloud Infrastructure ,

Here i would prefer running a VM that has pre configured LAMP ( Linux Apache MySQL and PHP ) , if you go to bitnami library you can Select LAMP image running Ubuntu 14 Operating System, I was not able to find Ubuntu 16.04 in Bitnami library so I had to upgrade the Ubuntu Operating System to 16.04 after gaining terminal access.

login to https://oracle.bitnami.com/ select Library Option and Spin up LAMP image https://bitnami.com/stack/lamp

Upgrade Ubuntu to 16.04  on Oracle Cloud Infrastructure ,

SSH to the Bitnami Image from your windows or linux machine

chmod 700 bitnami-opc-idmdomain.pem

ssh -i bitnami-opc-idmdomain.pem bitnami@ipaddress

sudo apt-get update
sudo apt-get upgrade
sudo apt-get dist-upgrade
sudo apt-get install update-manager-core
sudo do-release-upgrade -d

please refer this Article for more details on How to Upgrade Ubuntu to 16.04

Check Ubuntu Version

bitnami@ubuntu:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 16.04.3 LTS
Release: 16.04
Codename: xenial

Install Docker Container of latest version

Official Documentations link

sudo apt-get remove docker docker-engine docker.io
$ sudo apt-get update

$ sudo apt-get install \
linux-image-extra-$(uname -r) \
linux-image-extra-virtual
sudo apt-get update
$ sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
software-properties-common
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo apt-key fingerprint 0EBFCD88
pub 4096R/0EBFCD88 2017-02-22
Key fingerprint = 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
uid Docker Release (CE deb) <docker@docker.com>
sub 4096R/F273FCD8 2017-02-22
$ sudo apt-get update
$ sudo apt-get install docker-ce

Check Docker Version and Add user

$ curl -fsSL get.docker.com -o get-docker.sh
$ sudo sh get-docker.sh
project/hello$ sudo usermod -aG docker bitnami
bitnami@ubuntu:~/htdocs/fnproject/hello$ sudo sh get-docker.sh
bitnami@ubuntu:~/htdocs/fnproject/hello$ docker --version
Docker version 17.10.0-ce, build f4ffd25

Install CLI tools from fnproject.io

Official documentation link

curl -LSs https://raw.githubusercontent.com/fnproject/cli/master/install | sh
fn start

Install Function Web User Interface

docker run --rm -it --link functions:api -p 4000:4000 -e "
API_URL=http://api:8080"
fnproject/ui

Open Port 4000 on Oracle Cloud Infrastructure as this would be needed to web UI

Access Oracle Compute Instance that we now have installed Functions , make note of Security List Name bitnami-lampstack-7331 , we need to Open port 4000 on it

Click on Network Tab, Security Application to Open port 4000,

Create Security Application , Type TCP . Port 4000 , name it as bitnami_lamp_4000_sc

Access Security Rules , Attach this newly created Application

Note we have selected Security Application bitnami_lamp_4000_sc and attach it to bitnami-lampstack-7331

This should open port 4000 on our newly created Server that is running Function as a Service

now from the browser access functions web user interface

http://your-public-ip:4000/

Reality Check , creating first application , deploying and running as a function as a service

create folder helloubuntu , write a simple go lang code in that folder

bitnami@ubuntu:~/htdocs/fnproject/hello$ cd ..
bitnami@ubuntu:~/htdocs/fnproject$ cd helloubuntu/
bitnami@ubuntu:~/htdocs/fnproject/helloubuntu$ ls
bitnami@ubuntu:~/htdocs/fnproject/helloubuntu$ vi func.go
bitnami@ubuntu:~/htdocs/fnproject/helloubuntu$ fn init

______
/ ____/___
/ /_ / __ \
/ __/ / / / /
/_/ /_/ /_/

Found go function, assuming go runtime.
func.yaml created.
bitnami@ubuntu:~/htdocs/fnproject/helloubuntu$

where func.go code will be as shown below

package main

import "fmt" 

func main() {
  fmt.Println ("Hello Ubuntu by Madhusudhan Rao ! ")
}

fn init generates an func.yaml file which looks like this

version: 0.0.1
runtime: go
entrypoint: ./func

Running the code using fn run

You can see my message Hello Ubuntu by Madhusudhan Rao , printed , now its time to deploy the function so that its publicly available

fn deploy --app helloubuntu --local 

Check the newly deployed application on functions web UI

Run the function directly from web UI

Using fn route and fn call to invoke function from internal application

Going Beyond Opening Security Port 8080 from Oracle Cloud Infrastructure

Directly access the Function from Web Browser

Monitoring Server-less Functions on web ui , whats success what failed , how many times it got executed

Running Java Function as a Service 

let us create a directory hellojava , and let a boilerplate / basic code be generated

bitnami@ubuntu:~/htdocs/fnproject/helloubuntu$ fn version
Client version:  0.4.12
Server version:  0.3.169
bitnami@ubuntu:~/htdocs/fnproject/helloubuntu$ fn init --runtime=java

this will create project structure , yaml file and a place java code along with test code

this generates following tree structure

if you look at func.yaml file that has been auto generated, it basically shows the package name, class name and method to be executed

let us look at pom.xml 

Running the Java Function

We can now run the function / app by fn run command , this will automatically load the required JDK 9 libraries 

bitnami@ubuntu:~/htdocs/fnproject/hellojava$ fn run
Building image hellojava:0.0.1
Sending build context to Docker daemon  13.82kB
Step 1/11 : FROM fnproject/fn-java-fdk-build:jdk9-latest as build-stage
jdk9-latest: Pulling from fnproject/fn-java-fdk-build
3f84388a3335: Pull complete
5af7807a0ec3: Pull complete
09d580f15c0b: Pull complete
23a3b03fc984: Pull complete
08022c1872b4: Pull complete
ea733b0154e4: Pull complete
eb337c138275: Pull complete
713f0a7fd50b: Pull complete
0d5d9b25d97b: Pull complete
b6d0604a0963: Pull complete
88acd6cb378b: Pull complete
e9282c69b34e: Pull complete
6cf102986835: Pull complete
6306eed898fc: Pull complete
Digest: sha256:e2ad478ccbb4ceba397707ad75fcce89f561e95dce9529454b0b7cf6ef27e2aa
Status: Downloaded newer image for 
fnproject/fn-java-fdk-build:jdk9-latest ---> 1a2b57e6ee22 Step 2/11 : WORKDIR /function ---> e718d839e3b8 Step 3/11 : ENV MAVEN_OPTS -Dhttp.proxyHost= -Dhttp.proxyPort=
-Dhttps.proxyHost= -Dhttps.proxyPort= -Dhttp.nonProxyHosts=
-Dmaven.repo.local=/usr/share/maven/ref/repository ---> Running in d965db9e050e ---> 9556c0610b5b Step 4/11 : ADD pom.xml /function/pom.xml ---> 8e06d1510c50 Step 5/11 : RUN ["mvn", "package", "dependency:copy-dependencies",
"-DincludeScope=runtime", "-DskipTests=true", "-Dmdep.prependGroupId=true",
"-DoutputDirectory=target", "--fail-never"] ---> Running in ca13af0ab2de [INFO] Scanning for projects... Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/
plugins/maven-deploy-plugin/2.7/maven-deploy-plugin-2.7.pom Downloaded: https://repo.maven.apache.org/maven2/org/apache/maven/
plugins/maven-deploy-plugin/2.7/maven-deploy-plugin-2.7.pom (5.6 kB at 11 kB/s) Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/
plugins/maven-deploy-plugin/2.7/maven-deploy-plugin-2.7.jar Downloaded: https://repo.maven.apache.org/maven2/org/apache/maven/
plugins/maven-deploy-plugin/2.7/maven-deploy-plugin-2.7.jar (27 kB at 258 kB/s) [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building hello 1.0.0 [INFO] ------------------------------------------------------------------------ Downloading: https://dl.bintray.com/fnproject/fnproject/com/fnproject/
fn/api/1.0.45/api-1.0.45.pom Downloaded: https://dl.bintray.com/fnproject/fnproject/com/fnproject/
fn/api/1.0.45/api-1.0.45.pom (0 B at 0 B/s) .... [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ hello --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] skip non existing resourceDirectory /function/src/main/resources [INFO] [INFO] --- maven-compiler-plugin:3.3:compile (default-compile) @ hello --- [INFO] No sources to compile [INFO] [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ hello --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] skip non existing resourceDirectory /function/src/test/resources [INFO] [INFO] --- maven-compiler-plugin:3.3:testCompile (default-testCompile) @ hello --- [INFO] No sources to compile [INFO] [INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ hello --- [INFO] Tests are skipped. [INFO] [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ hello --- [WARNING] JAR will be empty - no content was marked for inclusion! [INFO] Building jar: /function/target/hello-1.0.0.jar [INFO] [INFO] --- maven-dependency-plugin:2.8:copy-dependencies (default-cli) @ hello --- [INFO] Copying api-1.0.45.jar to /function/target/com.fnproject.fn.api-1.0.45.jar [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 3.251 s [INFO] Finished at: 2017-10-30T09:59:36Z [INFO] Final Memory: 18M/62M [INFO] ------------------------------------------------------------------------ ---> eef9400ff891 Step 6/11 : ADD src /function/src ---> a7e901be0a39 Step 7/11 : RUN ["mvn", "package"] ---> Running in 1f21c292e5dc [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building hello 1.0.0 [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ hello --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] skip non existing resourceDirectory /function/src/main/resources [INFO] [INFO] --- maven-compiler-plugin:3.3:compile (default-compile) @ hello --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 1 source file to /function/target/classes [INFO] [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ hello --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] skip non existing resourceDirectory /function/src/test/resources [INFO] [INFO] --- maven-compiler-plugin:3.3:testCompile (default-testCompile) @ hello --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 1 source file to /function/target/test-classes [INFO] [INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ hello --- [INFO] Surefire report directory: /function/target/surefire-reports ------------------------------------------------------- T E S T S ------------------------------------------------------- Running com.example.fn.HelloFunctionTest Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.326 sec Results : Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 [INFO] [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ hello --- [INFO] Building jar: /function/target/hello-1.0.0.jar [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 2.928 s [INFO] Finished at: 2017-10-30T09:59:42Z [INFO] Final Memory: 14M/47M [INFO] ------------------------------------------------------------------------ ---> 19b782a7f7df Step 8/11 : FROM fnproject/fn-java-fdk:jdk9-latest jdk9-latest: Pulling from fnproject/fn-java-fdk 3f84388a3335: Already exists 5af7807a0ec3: Already exists 09d580f15c0b: Already exists 23a3b03fc984: Already exists 08022c1872b4: Already exists 662015d6d045: Pull complete 5753a0b0335b: Pull complete Digest: sha256:2f29eaae3c3d20857ef8c73f93367a846516749cb152febd118e054bfeada71a Status: Downloaded newer image for fnproject/fn-java-fdk:jdk9-latest ---> 24f20308f328 Step 9/11 : WORKDIR /function ---> 227d6e0f2838 Step 10/11 : COPY --from=build-stage /function/target/*.jar /function/app/ ---> f72b37f5540d Step 11/11 : CMD ["com.example.fn.HelloFunction::handleRequest"] ---> Running in 69d9f493605f ---> 23c5adcbcae4 Removing intermediate container 1f21c292e5dc Removing intermediate container 907bf1c247fa Removing intermediate container 69d9f493605f Removing intermediate container b6cde3b62137 Removing intermediate container d965db9e050e Removing intermediate container ca13af0ab2de Successfully built 23c5adcbcae4 Successfully tagged hellojava:0.0.1 Hello, world!

Running the Function from Web Browser Interface

Thanks for visiting the Blog ..

Regards

Madhusudhan Rao