How to deploy quickly a webapp from a Jupyter Notebook to GCP

Maurizio Santamicone
5 min readApr 10, 2021

A guide to set up your web app in the cloud in 15 minutes

Photo by SpaceX on Unsplash

In this post, I want to explain my favourite procedure to deploy python webapps into Google Cloud Platform (GCP). I write my code using Jupyter Notebooks, an interactive programming environment for data science. Notebooks allow to develop on the prompt (or REPL) and are great at exploratory data analysis, testing ML models, experimenting with different algorithms, and so on. However, recently notebooks have become much more than an exploratory programming tool: with the addition of a module like nbdev, we now have a complete IDE editor/development that supports the creation of modular, reusable code, automatically generates documentation, handles testing and version control. The only part that was missing is a tool to turn a notebook into a webapp: enter Voilà.

Voilà turns Jupyter notebooks into standalone web applications.

Once installed, Voilà can either be launched from the command line or be used as a Jupyter server extension, thereby launching it with a click from the notebook itself.

When Voila runs on the notebook, this is what will happen:

  1. Voilà runs the code in the notebook and collects the outputs.
  2. The notebook and its outputs are converted to HTML. By default, the notebook code cells are hidden.
  3. This page is served either as a Tornado application or via the Jupyter server.
  4. When users access the page, the widgets on the page have access to the underlying Jupyter kernel.

So once we have turned a notebook into a working web app, how do we deploy it to the cloud?

The recommended procedure in the Voila documentation suggests using Google App Engine “flexible environment”. The flexible environment runs your application in Docker containers on Google Compute Engine virtual machines (VMs), as opposed to a standard environment, where your application runs on a lightweight instance inside of a sandbox. The sandbox comes with some restrictions, as you can only use a limited set of libraries, you have a limited choice of CPU and memory options, and your app cannot write to disk. Because of these restrictions, App Engine standard applications are mostly used for stateless web applications that respond to HTTP requests quickly.

Moreover, Google App Engine’s “standard” environment does not support websockets, which is a requirement for voilà. So we need a flexible environment, meaning that the underlying machine will always run. Why not have a full-fledged Linux machine underneath where we can do or add what we want? I also found it annoying that with Google App Engine deployment, each time you change anything in the code or in any of the configuration files you need to re-deploy the app completely, a process that usually takes few minutes. So I chose to deploy on a custom server running Ubuntu 18.04 or later.

If you are new to GCP, you must know that it comes with 300 USD free credit once you register. If you choose a small virtual machine to run your notebook, like a one vCPU/3.75GB of RAM, it will last you for the free trial duration. However, should you exceed your limit, no worries. You will not be charged until you activate automatic billing.

Notebooks on GCP AI platform come with a pre-set of packages installed, including Numpy, pandas, scikit-learn and others. In order to launch as a webapp, you must add voilà and set up an nginx server on the underlying virtual machine. The nginx server will proxy to the voilà server. This setup gives us greater flexibility than an app engine and makes debugging easier. Any change to the code will be instantly live, with no need to re-deploy the web app, a process that usually takes few minutes.

So let’s have a look at the steps required to deploy our webapp to GCP.

Create an instance of Notebooks on GCP with the following:

  1. Python 3 (incl scikit-learn, pandas and more)
  2. Click on Advanced Options and change the operating system to Ubuntu 18.04
  3. select the machine type (default: n1-standard-4). Don’t overdo it, you might finish your credit very soon!
  4. Select Extensions to add if you need like BigQuery
  5. Create the instance

Install a web server (nginx) on the underlying virtual machine with a proxy for voila

Once your instance is up and running, open JupyterLab and launch a terminal window. You can now proceed to install and configure nginx:

sudo apt install nginx

then edit the config file /etc/nginx/sites-available/default and change as follows to enable the server to proxy to the voila server:

server {listen 80;server_name _;proxy_buffering off;location / {proxy_pass http://localhost:8866;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection “upgrade”;proxy_read_timeout 86400;}client_max_body_size 100M;error_log /var/log/nginx/error.log;}

You can now restart the server:

sudo systemctl stop nginx.servicesudo systemctl start nginx.service

To make sure nginx is started each time the server is rebooted:

sudo systemctl enable nginx.service

Install voila (and other packages that you need in your webapp)

pip install voilapip install …

Create a new systemd service for running Voilà in /etc/systemd/system/voila.service. The service will ensure Voilà is automatically restarted on startup and will execute the notebook.ipynb in your home directory:

[Unit]Description=Voila[Service]Type=simplePIDFile=/run/voila.pidExecStart=/opt/conda/bin/voila — no-browser — theme=dark — enable_nbextensions=True — VoilaConfiguration.file_whitelist=”[‘.*\.(png|jpg|gif|svg|mp4|avi|ogg|csv|js)’]” /home/jupyter/Notebook.ipynbWorkingDirectory=/home/jupyter/Restart=alwaysRestartSec=10[Install]WantedBy=multi-user.target

In this example Voilà is started with

voila --no-browser/home/jupyter/Notebook.ipynb

to serve a single notebook. You can edit the command to change this behavior and the notebooks Voilà is serving. If you don’t specify which file you want to serve you will be able to run any notebook in the working directory.

You can now test it:

sudo systemctl start voila.service

To enable start at boot:

sudo systemctl enable voila.service

You can check your logs:

sudo journalctl -u service-name.service -b

And that’s it!

Now you can access your webapp at the IP address of your virtual machine. You can debug, change your code or deploy new notebooks in seconds without having to re-deploy the app each time you change anything.

--

--

Maurizio Santamicone

AI and Web3 Expert @ Netmind.Ai Founder at Fliptin Technologies, Soulstice Consulting. Investor. Startups. AI, Machine Learning.