You are currently viewing Setup Development Environment for Serverless Apps with OCI Functions

Setup Development Environment for Serverless Apps with OCI Functions

I’m going to set up my development environment for Oracle Cloud Infrastructure Functions in an OCI Compute Instance. This article is more of a note to myself with the steps I went through – but it can also help somebody else.

Now, you can do this on a local machine as well, but I prefer doing this on a compute for the demo.

If you want to set up your development environment to a local machine – you can follow this Oracle Functions Quickstart.

OCI Functions is based on the open-source Fn Project and each function will be deployed in a Docker container on OCI.

Prepare tenancy

I will not go into too many details about this as there are already many resources available on this.

Please follow the steps from this document: Configuring Your Tenancy for Function Development  or Step A from Oracle Functions QuicStart

Create a Compute Instance

I’m going to create an Ubuntu 18.04 Instance that I’m going to put in a public subnet.

You can choose any OS image you’d like for your development environment.

Note down your instance OCID (you’ll need it for creating Policies):  


Create a Dynamic Group

Under Identity – Dynamic Groups – Click on Create Dynamic Group


I’ve used in my case the Instance OCID but also the Compartment OCID in which I’ve provisioned the Compute Instance. Maybe I’ll provision other instances as well and I’d like to give access to those as well – you can use which one works the best for you or both.

Create Policies

Once the Dynamic Groups is created, we need to give the right access to the group.

Under Identity – Policies –  Click on Create Policy: 


Copy-paste those and replace with your values:

Allow dynamic-group <dynamic-group-name> to manage functions-family in compartment <compartment-name>

Allow dynamic-group <dynamic-group-name> to use virtual-network-family in compartment <compartment-name>

Allow dynamic-group <dynamic-group-name> to read repos in tenancy

Generate Authentication Token

Click on your Profile Icon (Top Right Corner) and then your User Name.

Under the Resources menu, click on Auth Tokens and then Generate Token.


Copy the token and put it somewhere safe as you cannot see it again.

Prepare Environment

Install Docker

The first step in preparing the environment would be to install Docker.

Follow these steps from the Docker Documentation for your Linux flavor.

Login to OCI Registry (OCIR)

Log in to your instance and execute:

docker login <region-key>

The region key is the 3-letter representation of your region – In my case is Frankfurt, so it is fra.

When prompted, enter the name of the user you will be using with Oracle Functions to create and deploy functions, in the format <tenancy-namespace>/<username>, where <tenancy-namespace> is the tenancy’s auto-generated Object Storage namespace string shown on the Tenancy Information page.  For example, ansh81vru1zp/

If your tenancy is federated with Oracle Identity Cloud Service, use the format <tenancy-namespace>/oracleidentitycloudservice/<username>.

Then, when prompted for a password – copy-paste the Token we generated earlier.

Install Fn CLI

You can follow the installation steps from their GitHub Repo.

Test the installation:

ubuntu@fn-dev:~$ fn version
Client version is latest version: 0.5.96
Server version:  ?

Setup Fn Project Context

Create a new Fn CLI Context by executing:

fn create context <my-context> --provider oracle-ip

Note that you specify –provider oracle-ip to enable authentication and authorization using instance OCIDs, dynamic groups, and policies granting permissions to those dynamic groups.

Use the new context:

fn use context <my-context>

Finish Fn Project Setup

Provide your Compartment OCID – where you want to deploy the functions:

fn update context oracle.compartment-id <compartment-ocid>

Configure OCI API Endpoint URL:

fn update context api-url <api-endpoint>

In my case, for Frankfurt, the api-url is:

Configure the new context with the address of the registry and repository that you want to use with Oracle Functions by entering:

fn update context registry <region-key><tenancy-namespace>/<repo-name>

Where region-key is the 3-letter representation of your region (fra in my case), the tenancy-namespace can be found if you click on your Profile, then Tenancy and repo-name is a name you can give to your repository.

Create & Deploy Function

Create an Application

In the OCI Console, go to Developer Services – Functions and click on Create Application. 

We’ll use this application to deploy our functions to it.

Create a Hello World Function

I’m going to create a python Hello World function by using:

fn init --runtime python python-demo-function

Creating function at: ./python-demo-function
Function boilerplate generated.
func.yaml created.

A new folder was generated with the name of the functions python-demo-function. 

Inside, there is a sample Hello World script, a function definition file func.yaml and a text file with the requirements requirements.txt.

ubuntu@fn-dev:~/python-demo-function$ ll
total 20
drwxr-xr-x  2 ubuntu ubuntu 4096 Apr 12 14:59 ./
drwxr-xr-x 10 ubuntu ubuntu 4096 Apr 12 14:59 ../
-rw-r--r--  1 ubuntu ubuntu  574 Apr 12 14:59
-rw-r--r--  1 ubuntu ubuntu  149 Apr 12 14:59 func.yaml
-rw-r--r--  1 ubuntu ubuntu    3 Apr 12 14:59 requirements.txt

Deploy the function

Execute the following command to deploy the function to OCI, while being inside the function folder:

ubuntu@fn-dev:~/python-demo-function$ fn -v deploy --app ivl-demo-app

Note: ivl-demo-app is the name of the application that I’ve created in OCI under Developer Services – Functions

Each function will be deployed under a Docker Container.

The way this works is like this:

  • You deploy a function – the function is packaged as a docker container
  • The docker container is then published in the OCI Registry in your repository
  • When the function is called – the docker container is started and it will execute your code
  • The docker container will then remain in a paused status for a couple of minutes
  • If the function is not called again until the timeout, the container will be removed

This diagram shows the whole process of invoking a function:


Diagram source: OCI Functions Documentation


If you end up having this error when deploying your function:

Fn: Image does not exist or you do not have access to use it

You can go to the OCI Console, Developer Services – Registry (OCIR) – Registry and select your repository, then click on the Actions button on the right side and make it Public.


You should check that all the necessary Policies are correctly created.

Invoke Function

Invoke the Function from command-line:

ubuntu@fn-dev:~/python-demo-function$ fn invoke ivl-demo-app python-demo-function
{"message": "Hello World"}

ivl-demo-app – The name of the application created in OCI under Functions

python-demo-function – The name of the Hello World Python function

Of course, the Function can be called through many other ways like API Gateway, OCI Streaming, OCI Events, etc.


OCI Functions Quickstart

Fn Install

OCI Functions Documentation

Image Rights

Ionut Adrian Vladu

I enjoy building python scripts for…everything! I am a Cloud enthusiast and I like to keep up with technology. When I'm not behind a computer, I like taking photos -- Visit My 500px profile -- or sit back and enjoy Formula 1 race weekends. Currently, working as a Tech Cloud Specialist @ Oracle
Notify of

Inline Feedbacks
View all comments