Let me start by saying, I really love Microsoft Azure and my brain is currently flooded with plenty of Azure goodness after earning my Azure Admin certification. Therefore I was surprised to find myself working on the Oracle Cloud Infrastructure (OCI) platform less than a week after passing the AZ-104. I find that my professional life is focused on Microsoft, Windows Server, Hyper-V, Powershell, IIS, Storage Spaces, etc. but the technical tinkerer in me is always working in the world of Linux. Additionally, my personal pet projects have personal pet budgets. So that means Apache, MySQL, PHP, BASH, Drupal, and WordPress.
I also delight in most things open-source. The first time I SSH’d into my hacked Western Digital “WDTV” media player well over a decade ago I was enchanted by the incredible things that can be done with Linux on not-so-incredible hardware and non-existent budgets.
Had you told me a month ago this blog would be running on Oracle hosted infrastructure supported by hardware released within the last three years I believe I would have laughed. First, I am familiar with Azure and genuinely like the platform. Second, “Oracle” and “Budget” are typically diametrically opposed concepts. And yet… here we (literally) are.
It’s REALLY Free
The Oracle Cloud Infrastructure platform has what they call a “Forever Free” usage tier. It is one of the most generous hosting offerings I have ever come across. It is also incredibly easy to get started with. After I made the decision to give OCI a try, I had an account in about 15 minutes… I had a completely-free-for-life Ubuntu server spun up about 20 minutes after that. I spun up a second free VM a couple of days later to spread out my database and web application loads. Yesterday, I finished migrating my WordPress Site and Database over to the new VM’s and then set up my 20 GB of free-forever Object Storage. That object storage is the target for daily website and database backups (automated with BASH scripts and CRON naturally…). Finally, I setup some forever-free block storage backups of my virtual machines as another safety layer.
It REALLY Works
The beautiful thing is that with absolutely no money spent and no expectation of spending any in the future, my site seems a good tick faster! Furthermore, the more time I spend on the OCI platform, the more I have come to enjoy using it. There were however a few bumps I ran into which I will discuss later on.
How Did It Come to This?
I typically host my sites on a dedicated server from ultra-cheap hosting provider KimSufi. If you need a small server with a little bit of kick that won’t break the bank, it’s hard to go wrong with KimSufi. Recently however I stumbled across a short article about running a PiHole server on a mysterious “Forever Free Tier” from Oracle. There were a few reasons this intrigued me. When I think of public cloud, Oracle isn’t the first company that comes to mind. Microsoft, Amazon, Google, even Rackspace – I have used each of these company’s cloud platforms. However I didn’t even realize Oracle had an honest to goodness Public Cloud. A bit of google-fu tells me that their “generation 2” cloud has been around since 2018 so I guess I am just late to the show. Second, Oracle producing something for cheap let alone “free” is truly curious. Third, if it was truly free or at least cheap then that meant I could finally have a hosting provider for my site within the USA. My KimSufi box is being taken care of by some kind Canadians; most of my readers are in the US.
All hasn’t been roses, partly because of Oracle and partly because a VM with a meager 1 GB of RAM means you have to be thoughtful about how you host your application. I am not complaining on the latter account – it’s free. For anyone else thinking of hosting on Oracle’s free tier, I will provide some work arounds to a few of the annoyances I came across. But first, let me share the surprisingly good things about OCI!
If you have worked on Azure for a decent length of time and/or are familiar with cloud concepts you will find yourself pretty well at home on the OCI platform. I really want to applaud Oracle for keeping their marketing people away from their service naming conventions. Virtual Machines, Virtual Networks, Network Security Groups, etc. – all recognizable terminology. Their Object Storage –get this– is called “Object Storage.” That’s just uncanny… It’ a genuine relief compared to the likes of AWS which requires one to learn a whole new vocabulary to discuss basic/common cloud concepts. So cheers to Oracle for apparently just deciding to call things what they are.
Beyond the terminology, the web interface is excellent. This may be due in part to comparatively fewer service offerings vs. Azure/AWS. That said, the console is clean, easy, and well documented. Spinning up a VM, configuring network security rules, creating block storage and backups – all were deceptively simple in that I am sure what is going on behind the scenes is exceedingly complex. I also applaud Oracle’s lack of GUI configurable settings… Microsoft, Amazon, and especially Google should take notes as Azure/AWS/GCP are typically a mess by comparison to what Oracle has accomplished. I should also note that Oracle has put all of that functionality in ONE place governed by a consistent UI design language. This stands in sharp contrast to GCP. Google needs to unify their horrendous cloud and enterprise services interfaces which are spread across multiple domains and were clearly designed by different teams working in relative isolation from one another.
I also briefly delved into using the OCI Command Line, which is accessible from a pull-up console at the bottom of the web interface (just like Azure’s excellent Cloud Shell). I was delighted to see that the command syntax is fairly straightforward and if you have familiarity with the likes of Azure CLI you should take to it pretty quickly. It took me a few minutes (mainly with getting JSON syntax correct) but I was able to craft a one-line command to add 20+ Network Security Policies to my network’s “security list.” – Why – I had to do this in the first place is discussed further down.
It’s (relatively) Fast and Modern
The “Free Tier” documentation mentioned I get ONE vCPU running on an “old” generation hypervisor host. I had extremely low expectations to say the least. However checking /proc/cpuinfo in my VM made me quickly realize that Oracle and I have different definitions of “old.” Coming from Kimsufi I was expecting something like a 2nd or 3rd generation Xeon… Maybe even an Opteron. I now realize Oracle’s infrastructure isn’t old enough for either of those options. Lo’ and behold, my systems are running on an EPYC 7551… not shabby, not at all.
Storage performance is really solid for such small provisioned disks. My VM’s on OCI have a 50 GB OS disk attached with a rated throughput of 24 MB/sec, which is not great. However their IO is rated at 2820 IOPS… Which is quite good when compared to Azure’s “240” IOPS for a single “Premium SSD” Tier 64 GB disk. I will note that Microsoft has “Burst IOPS” up to 3,500 for up to 30 minutes. But the only way to get sustained “high-iops” in azure is to marry several large disks together with something like storage spaces and have workloads with deep queue depths. Microsoft did recently release “Ultra” disks however they are only available when certain conditions are met (i.e. use specific VM types in certain regions). I hope/imagine that will change over time. The Azure Ultra disk tier does far exceed the quickest block devices Oracle currently has on offer though. In either case, those upper echelons of performance aren’t really in scope for this discussion and I more wanted to highlight that even on “mid-range” virtual disks you get a decent amount of sustained throughput.
VM creation and spin-up – at least for these tiny “free tier” VM’s – is also relatively quick. You can go from starting the configuration to remotely connecting to your running VM in under 15 minutes… 8 – 10 minutes of which is VM configuration… and the spin-up for me only took around 6 minutes or so.
“Unfathomable Power, Itty Bitty Living Space” – Dealing with Limited Memory
Operating within 1 GB RAM and a single vCPU is tricky. This isn’t a complaint against Oracle, the service is free and the fact they give you 1 GB of RAM is quite generous. I quickly found out though that trying to run an Ubuntu LAMP stack on a single VM with only 1 GB of RAM is not simple. I did some tuning and eventually threw in the towel and just spun up my second free VM and put MySQL on that instance. I did learn a few things I will share…
1. I deployed from the Ubuntu 20.04 LTS image. After my system froze up for the third time due to memory issues, I realized that there is no swap file configured by default. I don’t know if Oracle or Canonical is to blame. I fixed this by creating a 3 GB swap file on both of my VM’s like so:
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
sudo echo "/swapfile swap swap defaults 0 0" >> /etc/fstab
2. MySQL’s default install isn’t meant for 1 GB of RAM – I provided some links in the “REFERENCES” section for some optimization you can do. One of the main things I did was limit the number of connections to 100.
3. Finally, Use “Ubuntu Minimal” for your deployment. OCI also offers Oracle Linux and Centos. I don’t have nearly as much experience on those distributions and they may be significantly slimmer than Ubuntu.
There were a few bumps with OCI itself along the way… First, trying to sort out the syntax needed for my public/private SSH key was way more headache than was necessary. If you are using Putty, save yourself some time and don’t let Oracle generate keys for you. Instead, use PuttyGen to create a key and save the PPK for use with Putty. When you create your VM in the Oracle console, paste the output from PuttyGen for the public key, the syntax looks like this:
Generating your own key is also better security practice anyhow.
Second, getting the network security rules sorted out was a pain. Port 22 is open for SSH as part of the VM creation process. When it came time to open up 443 for Apache I ran into some trouble. Getting the rule added on the Oracle security list in the web console was easy but things still weren’t working for me. The short answer is that IPtables is pre-configured in the host operating system of your VM. This was something I finally thought to check after all else had failed. The problem was a default “deny” rule (among many) that Oracle includes in IPtables on the host. You cannot just install UFW (at least not on Ubuntu) and configure and move forward from there. You need to work with IPtables to get things done. Here is an example of commands I ran to get myself sorted (with notes).
iptables -D INPUT 6 #Delete rule number 6 from the INPUT table - this is the default deny-all that Oracle puts in.
iptables -L --line-numbers #List all current rules again to make sure I deleted the correct policy
iptables -A INPUT -p tcp --dport 80 -j ACCEPT #Add a policy for HTTP traffic in
iptables -A INPUT -p tcp --dport 443 -j ACCEPT #Add a policy for HTTPS traffic in
Thirds, Security Lists and NSG policies in Oracle are easy but very limited. This was a real headache for me because I only allow 80 and 443 traffic from Cloudflare (which I use as a reverse proxy). Cloudflare has I think 11 or 12 different CIDR blocks that need to be allowed. On Azure this can all be handled by a single policy. On Oracle, you can only add a single IP address or CIDR range to a policy… You can only add a single port -or- a port range (which 80-443 is BAD) per policy. What this equates to was me needing to create 22+ different policies. For this I turned to the OCI CLI and used the console pop-up in the portal. That command looked like this (short example showing three rules):
Getting the JSON syntax correct was tricky but once I did it wasn’t too hard to use a text editor to quickly create all the rules I needed in a one-line command and run it. It’s also imperative that you make sure any existing policies you want to keep are included in the command as it completely overwrites the security list vs. just appending to it.
While I enjoyed a brief dance with the Oracle Cloud Infrastructure Platform CLI, the fact that policies are limited to only a single IP block or CIDR range is not good. This was the one odd oversight I came across on the platform.
The OCI platform is wonderful for my limited use case and the Free Tier is perfectly usable for small projects. I would commend it to anyone that enjoys tinkering and needs to host a blog for cheap. I would have loved to have spent time discussing the setting up of networking between the two VM’s and also how cool and easy it was to mount Oracle’s Object Storage as a (mostly) POSIX compatible file system within Linux. Setting the object storage up this way greatly simplified the shell scripts I use for web and database backups. Check some of the links in the references section if you are interested.
Oracle has done a fantastic job with “keeping it simple” when it comes to design, UI, and available services. Even the OCI CLI is approachable for anyone with a modest amount of comfort on any command line. In short, the platform is perfect for weekend technical warriors and really no more complicated than any other dedicated hosting solution while also having a bevy of powerful features on tap. Being Oracle, I would imagine it is probably very well suited to the enterprise as well, particularly for companies already heavily invested with other Oracle products and services.
What I didn’t delve into here are very many PaaS type services and I am not sure how Oracle compares to the other big players in the cloud space right now. But for simple IaaS infrastructure hosting it is surprisingly good.
Thanks for reading. Cheers!
Oracle Cloud List of “Always Free Tier” Resources:
Reducing Max Connections on MySQL and Other Tuning Tips:
Creating Object Storage and Mounting as a File System for Database and Web Backups:
Oracle Cloud and IPtables Conundrum:
Oracle Cloud CLI – Using it to quickly create Security List Rules:
Configuring IP Tables:
Adding Swap File on Ubuntu:
Moving a WordPress Site – PHP module needed for XML-RPC: