Crossroad Development

two roads crossed to make an X

Creating a Web Server with Oracle Cloud Infrastructure

2023-06-05

I have been a customer of Amazon Web Services for hosting my development site. In the process of the significant updates, like these blog posts, I stumbled upon another cloud provider that threatens every other player in the market. Actually, I encountered this while watching Some Ordinary Gamer’s video on creating your own VPN with Oracle Cloud Infrastructure. 

So, getting a comparison between major players is a little difficult as they are not apples-to-apples comparisons, however, I will try to represent the options as fairly as I understand them. Starting with AWS, you get a year of free-tier service which gives you some compute hours and bandwidth for free, but I will say on a small t3.nano instance that is running on a shared AMD CPU with less than 500MB of RAM and using very little bandwidth, the cost will run just under 5 dollars a month. Although after some research it seems they do have an always free option, I still think you get more for free from OCI. Lindode from Akamai is very competitive with a similar price with approximately twice the RAM. A droplet from Digital Ocean also falls around the same monthly price, with the notable exception of unlimited bandwidth. All of these providers do offer free incoming bandwidth meaning any traffic that the instance is requesting will not count against bandwidth pricing. Oracle however offers a really generous always-free option that looks like a great option for start-ups or mid-level operations. These options allow you to have up to 4 instances in a mix-and-match fashion including two AMD shared CPU instances with 1GB RAM each or up to 4 ARM Ampere A1 instances with 4 cores and 24 GB RAM allocated between the instances. Personally, I have had good luck with ARM web servers and haven’t run into any compatibility issues with a Debian-based OS. Also, the bandwidth limits are genuinely lofty and then affordable at scale. The first 10 TB of outbound traffic is free, then every GB after costs $0.0085 compared to AWS which starts at $0.09 per GB and goes down to $0.05 per GB after 150 TB of traffic a month. Oracle also offers 200 GB of free block storage and automatically assigns each instance 49 GB, if you don’t specify the amount. I know I’m not a sysadmin or do anything professionally, and I’m just a student, so take any of this advice with some perspective. I just know this can be a great solution. Also, I live in the US, I know some of the bandwidth pricing is different on other service areas and I don’t know how affordable or practical it would be to set up instances in enough global service areas.

Now, we will step through the process of spinning up a simple web server, since I had a few hiccups from being used to Amazon’s system. After you’re set up with an account, you will have to provide a valid credit card even though you likely won’t incur a charge, you will want to navigate to the instances under the compute tab in the hamburger menu. You may have to set up a compartment by going to the compartments page under Identity and Security then identity. Then when you begin the process of creating an instance, you will want to give it a name to easily identify it amongst the other instances you create. I chose the A1 Ampere shape, with 2 cores and 12 GB of RAM for a middle-of-the-road production server. As for the OS, I picked Ubuntu mostly for the Debian package manager and how comfortable I am with it. Also, before you finalize the instance make sure to download your private key, and set the public IP to none since we will be assigning a static IP later which is important if you want to associate your domain name with it. 

After you are greeted with the dashboard for your new instance use the hamburger menu again and under the Networking tab under the IP Management subtitle you will find Reserved IPs. Name something you would associate with the project and select the compartment that you used to create your instance. Now back to the hamburger menu to select Virtual cloud networks under the Networking tab. Then create a VNC, keeping naming and compartment consistent of course, and pick a simple local IP block like 10.0.0.0/16 or something similar. Then once in the dashboard for the VNC, you will find a button that says Create Subnet. Keep your naming scheme and the IP block you used when creating your subnet.

Then go back to your instance’s dashboard by navigating to instances under compute, then select the name of your instance. In the dashboard on the navigation bar to the left, you will find Attached VNICs, from there select Create VNIC. This creates a subnet where you can control the ingress and egress rules, set IP values, and any other networking options. Of course keep your naming convention, compartment, the VNC we just created, the subnet in the VNC, and leave everything else as it comes. Then you can navigate to the dashboard of the VNIC that was just created, and on its left navbar, you will find IPv4 Addresses. There, you will find a table of IPv4 Addresses, probably just one labeled Primary IP, on that one you should see a meatball menu all the way to the right on that row. Select edit in that menu, then select Reseved IP under Public IP Type and select the IP we reserved earlier. The final step in networking setup is to select the name of the subnet you created in the dashboard you are already in, which will redirect you to the subnet’s dashboard. There you can select the security rules link where we can begin to add ingress rules by clicking on the button that indicates that. In this form, you set the IP to 0.0.0.0/0 to hit every IP that’s listening at the destination ports which should be 80,443 for the web server and SSL respectively.

At this point, we should SSH into the system and configure some settings on the instance. I won’t go into how to do this, because it should be available already installed on every major OS, but you will need that private key we downloaded earlier. Once in, you should use sudo apt update and then sudo apt upgrade to make sure your security patches and software are up to date this may require a reboot which I recommend doing from the instance dashboard, not the shell. Actually, at this point, we do have another networking setting we change in this shell by using the sudo nano /etc/iptables/rules.v4 to edit that file. I like to add the next lines below the rule for port 22 that looks like this

-A INPUT -p tcp -m state –state NEW -m tcp –dport 80 -j ACCEPT 
-A INPUT -p tcp -m state –state NEW -m tcp –dport 443 -j ACCEPT 

Press control+O to write the file to disk, then control+X to exit nano. Use the command sudo su to get into a full root shell, where you use the command iptables-restore < /etc/iptables/rules.v4 Then you should close out of that ssh session and start a new one to be back in the Ubuntu user shell in the home directory.

Finally, we can start setting up Node.js to test our web server. I use a newer version of node than apt installs, but for the proof of concept, sudo apt-get install nodejs should be fine. Create a directory in your home directory for the project, and use npm install fastify -g to get a global install of Fastify for any project in the system. At this point copy in a hello world or whatever node project you like, then navigate to your reserved public IP to see your success.

const path = require("path");

// Require the fastify framework and instantiate it
const fastify = require("fastify")({
  // Set this to true for detailed logging:
  logger: false,
});

//The root where we serve one line of text
fastify.get("/", function (request, reply) {
reply.send("Hello World");


});


// Run the server and report out to the logs
fastify.listen(
  { port: 80, host: "0.0.0.0" },
  function (err, address) {
    if (err) {
      console.error(err);
      process.exit(1);
    }
    console.log(`Your app is listening on ${address}`);
  }
);

Comments