← All posts

How to host an API or Web Server in Oracle Cloud 100% Free

At least, the way I do it.

hostingOracle Cloud
How to host an API or Web Server in Oracle Cloud 100% Free

Introduction

I started using Oracle Cloud in college thanks to a student account one of my professors gave me which had 250$ of credits, but in this case we are doing it with a normal account. I mainly used it to host Minecraft servers with 300 mods in machines with 40GB of ram, and that allowed me to understand the basics of cloud operations and systems administration. Things like SSH, cron jobs, leaving things on background...

In this article I will explain how I would deploy a server for a side project or a web. I believe this is specially useful for people starting with this that don't want to or are afraid of being billed randomly by AWS or other providers.

First step: The account

Oracle Cloud has an awesome free tier, allowing you to have always free resources like a couple of machines and networks. For our case, we need a single machine. To register just go to https://signup.cloud.oracle.com and create a free account. I believe in the past it was possible to create accounts without a credit card, but that is not possible anymore by normal means. But don't worry, we won't be charged for the use we will have. If you are still worried, you can always use a card with 5 euros inside (Oracle will test if the card can pay at least some money at first and then refund it, so we need a little bit).

Important you will be asked which region you want your account to be located at. I recommend using one close to your home, but if there is a big region close enough choose one of those. For example I live in Spain, but the Spanish server has a very small data center, so it is harder to get machines. In my case I selected London South. In America I would select US East for example.

When we finish the sign up flow, we will be presented with the Oracle Cloud Infrastructure Console. OCI from now on.

Next: Provisioning the instance

Just go the top left hamburger menu -> compute -> instances -> create instance.

Before starting configuring, some important info: Oracle cloud always free instances have 2 types: ARM and AMD x86. For this tutorial I would say the best option is the ARM since we get up to 24GB of ram, and 4 OCPUs. Before it was a bit risky to go with ARM as a lot of programs and tools were not compiled for this architecture, but that is not the case, and that difference in ram is going to show for good.

Here we have some settings to select:

  1. Put a name to the instance, something like WebServer can work.
  2. From Images we can leave Oracle Linux, but I prefer Ubuntu so lets select Canonical Ubuntu 24.04 Minimal aarch64
  3. In Shape we select VM.Standard.A1.Flex with 4 CPUs and 24 GB and go to the next section.
  4. In Security we don't touch anything and go next.
  5. In Network just ensure that Automatically assign public IPv4 address is on.
  6. To Add SSH keys you can use your preferred method. In linux I recommend downloading directly both keys. In windows, with Putty it is easier to generate it via PuttyGen and paste it in the UI.
  7. Now we can just continue until the end and try to create it.

DISCLAIMER, it is possible that you get an error saying that there are not available machines for the shape requested. This is typical because Oracle has to make money so the free instances are limited. Some tips to get a machine is to be insistent (it can take some days to get it), have selected a good region at the start and upgrade the account to a paid as you go account. This will make Oracle prioritize your orders.

Okay now I have a machine, what now?

At first you will see the machine with the status provisioning or maybe starting. We have to wait until it is ready and then we need to copy the public ip, this will be our endpoint. Now we will leave the OCI console for a little bit.

Let's ssh to the machine, we can use the linux command

ssh -i ssh_key_XXXX.key ubuntu@<public_ip> 

On windows we can use Putty with the private key we generated before and with ubuntu@<public_ip>

Now that we are in the terminal we can do literally anything, but for me the easiest way is this:

# Install latest deps
sudo apt update && sudo apt upgrade -y

sudo apt install git make build-essential nginx

Also install any languages or tools you need for your server like nvm for example

# This is just an example, get the latest version of nvm if you need it
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.4/install.sh | bash

Note: for docker and docker compose we might need to follow the official way.

Great, now we can pull our web server and just run it, obviously this is production, so try to not run it in dev mode. Once it is running we can test it by doing a curl in localhost. Ah but wait, if I close the terminal the process stops right? There are a lot of options to make that not happen. The easiest one in my opinion is just using tmux or screen commands. Lets use tmux for this:

sudo apt install tmux

And now we just start it:

tmux

While inside tmux, we can run a command, close the terminal and whenever we ssh again, we can just tmux a and it will be exactly where we left it. Obviously tmux does a lot more, but I leave that for the reader to investigate.

Making it accessible

Okay great, it is running, but it is not working from my machine, I cannot navigate to that ip.

We need to create a rule in Oracle Cloud to allow traffic to our ports. We go to the hamburger menu again then Network -> VCN -> Security Lists - > Default Security List.

Here we will create a rule accept all incoming tcp traffic to ports 80 (HTTP) and 443 (HTTPS) from the ip range 0.0.0.0/0 (One per port). But my app is running in port 8080! Yeah, but browsers target the default ports, don't worry you don't have to change your port.

Great now we need to open the machine firewall too. Let's use ufw since we installed Ubuntu it is probable that is the firewall we want to use.

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable

Hurray! We have both ports accessible from the internet!

Before continuing, we need to point our domain to the public ip of our server. In your dns provider, probably the one where you bought your domain from, you can create an A RECORD pointing to our ip. It will take 5 mins to apply which is the time needed for the last step.

Nginx and certbot

We want to support HTTPS, right? Let me answer for you: YES. The easiest way to get https certificates is through Let's Encrypt. This organization provides free SSL certificates through a tool called certbot. To get those certs, we must demonstrate that we own that domain and the web server in that domain. There are some ways to do this, certbot provides different types of challenges and configuration but the easiest way is its integration with nginx.

Nginx is one of the most extended and used http server in the world, it is incredibly performant and easily configurable. But the feature we need today is the reverse proxy. We will instruct nginx to serve the http and https requests forwarding them to our server http port. This way we dont have to modify our server to add support for https and certbot can integrate automatically.

We already installed nginx with the first apt install, lets configure it now. We first need to create a configuration file.

sudo nano /etc/nginx/sites-available/<name of my webserver>

Add the following code. Change the domains to the ones you want to serve and the localhost port to the one you are using.

server {
    listen 80;
    server_name yourdomain.com www.yourdomain.com;

    location / {
        proxy_pass http://localhost:8080;
        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_set_header X-Forwarded-Proto $scheme;
    }
}

Great we now need to enable nginx:

sudo ln -s /etc/nginx/sites-available/<name of my webserver> /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-enabled/default
sudo nginx -t
sudo systemctl reload nginx

The first command creates a symlink between the file you created and the enabled sites folder, if we want to disable it we can just remove the link. The second one removes the default placeholder site. the third is to test the config and the last one is to restart it. Btw we need to use sudo because the port 80 is restricted.

And now the moment of truth, try going to a browser and navigating to your domain http://<your_domain>, the browser might say it is not protected since it is not https, but it is fine for the moment, we should be able to see the home page.

The last part: securing it with a SSL cert. Just paste this command replacing the domains for the ones you want to get the ssl cert.

sudo apt install certbot python3-certbot-nginx 
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com

Follow the prompts and give your email for contact. This will modify your nginx config to serve https, if it asks to redirect http to https say yes. It will also set up a timer to renew the certs when they are about to expire.

And... We are done!

Enjoy your deployment and share it with your friends!