Tutorial: Deploying an Oxygen.jl app to Microsoft Azure

Hi everyone,
I’ve recently been working on a web app in Julia and wanted to share what I’ve learned as it may help those in the future. In particular, deploying an API is a new skill for me and so I thought I’d help out the Julia ecosystem by writing a short tutorial.

BUT FIRST!
Big shout out to @ndortega who very kindly answered all my dumb questions as I learned my way around api’s, web apps, julia, etc. And secondly, join us on the Oxygen Discord! if you’re actively using Oxygen to develop any web apps!
Lastly, I am still very new to this and I wrote this tutorial over the course of several months as I had time (and motivation), so if I am unclear on any steps, could add more information, etc. Please do not hesitate to ask for more information or provide suggestions! It will not offend me at all.
Code on Github: GitHub - snowysnowcones/Oxygen_Tutorial: This is a oxygen.jl tutorial for Julia users

Tutorial Start:

This tutorial makes use of the following packages:
Oxygen.jl
Html.jl

Written / tested with Julia version 1.9.3

This tutorial covers creating a basic API with Oxygen, writing a Docker file, deploying on Azure, then testing with Postman. I don’t really go too much into detail on the code itself or all the intricacies of Docker, this is a little more “bare bones” just designed to get one’s feet wet.

Prerequisites:

Let’s get the basics out of the way. This tutorial assumes you have at least very basic understanding of Julia. For this tutorial you’ll need:

  • The Julia Language installed
  • VSCode (with Julia extension and Docker extension)
  • A Docker Hub account
  • Docker Desktop installed
  • A Microsoft Azure account
  • Postman

We begin the tutorial by creating a new workspace / environment for our files to live. Create a new directory wherever you please, I created a folder in my GitHub library called “Oxygen_Tutorial”.


Next, start VSCode and open this location by going to File → Open Folder → [choose the folder you just created]

The next step is to create the environment. Open the Julia REPL in VSCode (ctrl + shift + p → Julia:Start REPL)
With the REPL open, navigate to pkg by pressing “]” on your keyboard. Type “generate” followed by your environment name. In this case, I chose to call the environment “tutorial”:


Once the environment is generated, activate it:

After the environment is activated, we need to add our dependent packages. This will add the packages to the Manifest.toml and Project.toml. Having the Manifest.toml and Project.toml is important for properly building your Docker file later in the tutorial.
Add the packages through the REPL with the “add” command. Add HTTP and Oxygen…
image

After adding the packages your workspace should look something like this:
image
And you can see the dependencies in Project.toml:
image

At this point we need to add our code. This tutorial is not really going to cover the code in-depth, since it’s more about deployment, but the API consists of two files: main.jl and utils.jl
main.jl consists of the code that gets the Oxygen app running, while utils.jl consists of the code that actually performs the task. In this case, the API is going to just take input from a user and sum the data.

Both files I am placing in the “src” folder, and am deleting tutorial.jl which was auto created when the environment was set up.
Here is the code:
main.jl:

module Main 

using Oxygen, HTTP

# import your file with your custom module.
include("./Utils.jl")
# Make sure to import your module with a "." char in front, this tells julia it's a custom module
using .Utils

# Use a POST request route, because we need to send data t our api 
@post "/api_test" function(request)

    # extract the body of a HTTP Request and parse it to a JSON object 
    json_body = json(request)

    # extract the values inside the "data" key of our body
    data = json_body["data"]

    # call the external "sum_values" function with the "data" passed inside the body of the request
    return sum_values(data)
end

# start the server
serve(host="0.0.0.0", port=5050) #choose whatever port you want here

end

util.jl:

module Utils 

export sum_values

function sum_values(data_input)
    return sum(data_input)
end

end

Execute the files to make sure they run properly.

Next let’s focus on Docker. Start Docker Desktop.
Open your terminal on your machine and pull the Julia image into Docker with the following command: docker pull julia
This is essentially a way for Docker to use Julia when it runs


Typing “docker images” should yield a result that shows the image was successfully downloaded.

Now we need to build our own docker image that encapsulates everything in our source folder.
Start by creating a Dockerfile. In “src” right click, New File, and type “Dockerfile”
image

FROM julia:1.9.3

WORKDIR /app
COPY Project.toml Manifest.toml ./
RUN julia --project -e 'using Pkg; Pkg.instantiate()'
COPY src/ ./src/

EXPOSE 5050 #this port must match the port in main.jl

ENTRYPOINT [ "julia", "--project", "src/Main.jl" ]

Next, open a new terminal and login with docker using: Docker login
Type your username then your password.


Once successfully logged in, it’s time to build the image!

Right click on the Dockerfile in VSCode and choose “Build Image”. VSCode will ask for a name, which you can provide whatever you like. I named mine, “oxygentutorial”.
Once built, go to Docker Desktop and run your image:


In optional settings, make sure to bind the port to whatever you had in your code (in this case, 5050)

After it’s running, verify by navigating to localhost:5050/docs:

You can see that Oxygen is now running and we can see our POST function “/api_test” available. To further test, we will now use Postman to send data through the body of the request to make sure our function sums the information correctly.

In Postman, open a new Tab and create a POST request. In the URL type: localhost:5050/api_test. Then choose “Body” and put in your data:

{
	“data”:[5,3,2]
}

This is what will be sent to the server to be summed. You can put any combination of numbers within the square brackets. In my result, I correctly got back the number 10 as a response. Pretty cool! Now, let’s get it running on a server in the cloud.

But before we can put our API on a server in the cloud, we need to push our newly created Docker Image to Docker Hub. We do this because Azure is well integrated with Docker and having it already on the Hub will make the process of starting the App server a lot easier.

Navigate to the Docker Hub at https://hub.docker.com Log in.
Create a new repository


Click “Create”. This repository is where your image will live.
However, prior to pushing to the Hub, the image must also be tagged.

As far as I can tell, tagging the image essentially creates a copy and tells Docker where to push it to. Open up a command window and type:

docker tag [image name] [docker username]/[repository]
For example:
docker tag oxygentutorial snowysnowcones/oxygen_tutorial
Once tagged, you can choose Action and “Push to Hub” in Docker Desktop:


In Docker Hub you will now see your image:

Now it’s time to create the App Service.
Navigate to your Azure Portal (https://portal.azure.com)
Choose Create a resource


And choose “Web App” from the list

Fill out all the Project details, and choose “Docker Container” under “Instance Details”


Once all the details have been filled out, click on the “Docker” tab.
Choose Image Source as “Docker Hub” and put in the image and tag you just created:

Once done, choose “Review + create”
And finally, “Create” if everything looks good.

Next your app will Deploy…

Once the application has successfully deployed, we can now go back to Postman and create a new POST request. This time though, instead of sending the data to localhost, we’ll send it to the Web App we just created! (Note that even after Azure says “Deployment Successful”, it still may take 5 – 10 minutes before you can access the URL.)

In Postman change the URL to the Azure Web App you just created (e.g. https://snowys-oxygen-tutorial.azurewebsites.net/api_test)
Add data to the Body of the request (I’d recommend using different numbers this time) and hit “Send”. The data is sent to the server, summed up, and returned!


Yay!

Here’s another example, this time using the no-code/low-code web app service, Drap Code (https://drapcode.com) [you could also use bubble.io, webflow, backendless, etc]


And that’s it! You’ve now successfully deployed a web api! Yippee!

9 Likes

Thanks for this. I might be blind, but is there a link to the final webapp available? Would love to see what a WebApp based on Julia looks/feels like.

EDIT: Sorry I’m stupid, this seems to be an API only, not a “website” in the common sense.

@Snowy Awesome write-up!