JVM Advent

The JVM Programming Advent Calendar

Running your JuPyTeR notebooks on the cloud


On the back of my previous share on how to build and run a docker container with Jupyter, I’ll be taking this further on how we can make this run on a cloud platform.

On the back of my previous share on how to build and run a docker container with Jupyter, I’ll be taking this further on how we can make this run on a cloud platform.

We’ll try to do this on Oracle Cloud Infrastructure (OCI). In theory, we should be able to do everything in the blog on any VM or Baremetal instance. If you are new to Oracle Cloud, I would suggest getting familiar with the docs and Getting Started sections of the docs. You will also find several informative links at the bottom of this post, in the Resources section.

I found the tutorial to setup a VM instance simple and useful — I recommend having a glance and following the steps. Take note of the pre-requisites before actually getting downing to creating a VM instance and ssh-ing into it — it will involve Creating Compartments, Subnets, Security Lists, among other things before you can create a VM.

Signing up

You will have noticed you have to have an account to be able to get access to the Cloud Dashboard and proceed.

You can sign up by going to oracle.com and also to cloud.oracle.com — recommend signing up via these portals. You might even be eligible for FREE credits once you do that (enough to spend your weekend running your favourite instances).


Dashboard — sign-in

Once you are signed up, you sign-in via cloud.oracle.com/sign-in which will take you to a page like this

Follow the instructions as described in the tutorial to setup a VM instance and give your VM and other resources names (use initials as a prefix) you can identify easily. This will kick off the request to create the VM (if all your entries are valid) — and in less than 15 seconds you should have a VM ready to be used.

Once the VM instance is created, make a note of the Public IP Address of the instance. All running VMs can be found on by going to the Compute > Instance on the navigation menu on the left:

Select the running VM by clicking it:

which will take you to the VM details page, where you can spot the Public IP Address:

Note: the Public IP Address will be different for every VM created, the above is temporary.


OCI can be accessed with a command-line tool called oci-cli which can be installed by following instructions mention in the CLI docs. Once installed the command to invoke it is called oci and you can invoke it by doing the below:

Actions to get on the cloud

$ oci --helpUsage: oci [OPTIONS] COMMAND [ARGS]...Oracle Cloud Infrastructure command line interface, with support for
Audit, Block Volume, Compute, Database, IAM, Load Balancing, Networking, DNS, File Storage, Email Delivery and Object Storage Services.Most commands must specify a service, followed by a resource type and then an action. For example, to list users (where $T contains the OCID of the current tenant):oci iam user list --compartment-id $TOutput is in JSON format.For information on configuration, see
<-- snipped -->Commands:
<-- snipped -->

As such we won’t need the dashboard for the most part here onwards. We will also NOT be covering the use of the CLI tool in this post.

Logging into the VM instance

You can then ssh into the box (see docs on connecting via ssh) and proceed with rest of the actions below:

### Oracle Linux and CentOS images, user name: opc
### the Ubuntu image, user name: ubuntu$ ssh -i ~/.ssh/id_rsa ubuntu@$ ssh ubuntu@

Installing git

For this blog post, we selected the Canonical Ubuntu Linux (Canonical-Ubuntu-16.04–2019.08.14–0) as our OS image, which comes with apt-get and git installed so we don’t need to do anything there.

Running Jupyter Notebooks

Cloning our repo

We can clone our repo and perform the rest of the steps:

$ git clone https://github.com/neomatrix369/awesome-ai-ml-dl
$ cd awesome-ai-ml-dl/examples/JuPyteR

Installing Docker

The Docker docs for installing Docker on Ubuntu can be found on the Docker site. A bash-script has also been provided to quicken the process, although the target OS here is Ubuntu 16.04 or higher:

$ cd build-docker-image
$ ./installDocker.sh

Note: in case you choose another OS image during VM creation, you will have to install Docker manually with the docs from Docker or modify the above script to make it work for the target OS.

Building the Jupyter Docker Image

$ cd build-docker-image
$ sudo ./buildDockerImage.sh

In this specific environment, we need to pass the sudo keyword before every docker command. You may not have to do that in your local environment or elsewhere.

Running the Jupyter notebook as a Docker container

$ cd [back into the project root folder]
$ sudo ./runDockerContainer.sh

This will show you a console like this:

<--- snipped --->OpenJDK Runtime Environment (build 9.0.4+11)
OpenJDK 64-Bit Server VM (build 9.0.4+11, mixed mode)
PATH=/home/jupyter/.local/bin:/opt/java/openjdk/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin~~~ JDK9, Linux only: We are enabling JVMCI flags (enabling Graal as Tier-2 compiler) ~~~
~~~ Graal setting: please check docs for higher versions of Java and for other platforms ~~~
JAVA_OPTS=-XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:+UseJVMCICompiler
JAVA_TOOL_OPTIONS=-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:+UseJVMCICompilerAvailable kernels:
python2 /home/jupyter/.local/share/jupyter/kernels/python2
java /usr/share/jupyter/kernels/java[I 13:39:35.993 NotebookApp] Writing notebook server cookie secret to /home/jupyter/.local/share/jupyter/runtime/notebook_cookie_secret
[I 13:39:36.293 NotebookApp] Serving notebooks from local directory: /home/jupyter
[I 13:39:36.294 NotebookApp] The Jupyter Notebook is running at:
[I 13:39:36.295 NotebookApp] http://(81dde8675279 or
[I 13:39:36.297 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
[C 13:39:36.310 NotebookApp]To access the notebook, open this file in a browser:
Or copy and paste one of these URLs:
http://(81dde8675279 or

Make a note of the URL, and replace the with your Public IP Address i.e.

You can also see from the above logs we are using Java 9 (built on the AdoptOpenJDK farm) and enabling the GraalVM compiler as HotSpot’s C2 compiler (see Switches to enable the GraalVM compiler in Java 9 to enabled the GraalVM compiler). It’s also because the Java extension for Jupyter requires Java 9 or higher to work.

Opening the Jupyter notebook in your browser

Go to the browser and try to open this:

Aargh! It does NOT work!

That is because we haven’t opened up the port 8888 from within our cloud network (via Ingress Rules, read more about it here) to the outside world (public):

We would need to add the above entry to the Ingress Rules section, you can get to Ingress Rules page via the navigation menu: Networking > Virtual Cloud Networks > Virtual Cloud Network Details > Security Lists, which brings you to the page with the Default Security Lists.On clicking the Security List that corresponds to your Virtual Cloud Network (VCN) you will land on the above Ingress Rules page.

In case, you are still not able to find it, search for the term securityusing the search facility on any page in the Cloud Console (see the magnifying glass 🔍at the top of the page). This will show you all the Default Security Lists and clicking on it will bring you to the Ingress Rules page above (you might have just one Security List entry). Note: Ingress means traffic coming into the network/VM instance.

Why port 8888, that’s because we set it up like that in the docker scripts, have a look at the sources to find out why and how.

Having done all of the above: voila! We see the Jupyter startup page in the browser:

And you can see a Java-based notebook is available to play with! Try out the below by creating a new Java notebook in the browser:


You are free to create Python notebooks as well, not just Java ones — this is the beauty of Jupyter notebooks.

Installing Jupyter on a bare-metal or VM environment

For brevity, we didn’t cover this aspect, but if you look at the scripts associated with building and running the Jupyter instance, you will see that the docker build scripts build and run the instance with the help of individual scripts that can be executed on its own in this order:

$ cd build-docker-image
$ [install Java 9 SDK and set the PATH and JAVA_HOME]
$ ./install-jupyter-notebooks.sh
$ ./install-java-kernel.sh
$ ./runLocal.sh

If you want to see how this would work, run the above scripts in the local environment of the instance, the rest of the instructions should work as expected.

Create custom image for reuse

As we have been able to successfully run Jupyter Notebook from inside a VM instance, we can save this image for future re-use or share with others. Creating an image of the VM instance can be done via Compute> Instances > Instance Details the navigation menu, and Create Custom Image from the Actions drop-down menu:

Note: whilst in the process of creating a custom image, your original VM instance is shut-down. This can take under a couple of minutes to complete depending on the size of the original VM instance.

When successfully created, it becomes available among the list of Custom Images to choose from, the next time we go to create a new VM instance:


If all of this was piece of cake for you or you have survived without much hassle, then try out all the deep-dive stuff mentioned in the README page here.

To be able to code in other languages in the Jupyter environment all you need is a Jupyter extension — it’s only a matter of installing and configuring. You can learn all about this here.

Signing off

In case you have created a notebook, it gets saved in the sub-directory called jupyter/notebooks, you can retrieve this using scp from your local machine (see here on how to do that).

Make sure you have signed out of both the oracle.com and cloud.oracle.com login sessions, it’s easy to forget one or the other. But before doing that please also have a look at the Cleaning up of resources page in the docs — you don’t want your instance running forever while you are not looking at it!


A good set of scripts (including Docker) and an easy-to-use cloud environment can help in many ways. In this case, enabling us to run a Jupyter notebook instance that can be shared publicly or privately depending on your network security settings.

The Jupyter environment is flexible and allows extending functionality via configurations and extensions.

We didn’t cover things like cloud security and partitioning of user instances — which is sort of out of scope for this post. Please look into this further, if they are important to you. Please do ensure it meets the necessary levels of security for your application or use-case. Check out the docs on Security on the OCI docs page to learn more.






Author: Mani Sarkar

I have been posting articles on the Java Advent calendar for some years. A passionate developer mainly in the Java/JVM space, based out of London, UK. A JCP Member, OpenJDK contributor, involved with LJC and other developer communities, @adoptopenjdk and other F/OSS projects. Writes code, not just in Java/JVM hence likes to call himself a polyglot developer. He sees himself working in the areas of core Java, JVM, JDK, Hotspot, Graal, GraalVM, Truffle, VMs, and Performance Tuning. An advocate of a number of agile and software craftsmanship practices and a regular at many talks, conferences and hands-on-workshops – speaks, participates, organises and helps out at many of them. Expresses his thoughts often via blog posts, microblogs (tweets) and other forms of social media. —– Twitter: @theNeomatrix369 Slideshare: http://www.slideshare.net/neomatrix369/ —–

Next Post

Previous Post

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

© 2024 JVM Advent | Powered by steinhauer.software Logosteinhauer.software

Theme by Anders Norén