There are several cloud services these days that have a free-tier for certain cloud services. I’ve tried several. Amazon Web Services gives you 700 hours per month free, which is pretty close to free. Microsoft Azure gives you a whole year of free services, and then you have to pay (a comparable price to AWS). Oracle Cloud, however, by far has the best deal. You can have up to two micro-class VPSs free — forever.

So in this guide, we will be setting up a NGINX / PHP-FPM server stack on an Oracle Cloud free VPS.

Step 1 — Create Your Free VPS Instance

First, let’s get set up with a free account. Follow this link to get started.

Enter your full name and email address

You’ll need to confirm your email address. Once that’s done, you should be able to log in.

Once you’re at your dashboard, click the menu button in the upper left corner and click on Compute, then Instances.

Click on compute and then instances

It may take some time to get to the instances dashboard. Once you’re there, click Create Instance.

Click create instance

You can name your VPS whatever you like, in my example, I named mine nginx-server. Leave everything else as-is and then click edit on the right-hand side of the image and shape section.

Name your instance then click edit under image and shape

The default OS image is Oracle Linux 8 (at the time of this writing). In my example, we’re going to use Ubuntu 20.04 LTS.

Click change image

Next, scroll down to Add SSH keys and make sure generate a key pair for me is checked and then click download private key. You won’t need the public key as it will automatically be installed on the VPS.

Once your key is downloaded click the Create button.

Download your Private Key, then click the Create button.

You should now see your VPS instance listed. Copy the Public IP Address and create a hostname with your DNS / Domain provider. For this example, I’m going to use

Step 2 — Setup Your Firewall

Ok, we’re getting there. Inbound port 22 is allowed to the world by default, which you may want to restrict to your own CIDR subnet or IP address. In this example, we’re just going to leave port 22 open and also open ports 80 and 443.

In the search bar at the top of the dashboard, search for security groups and then click Default Security List for vcn-…

Click Default Security List…

Scroll down and click Add Ingress Rules.

Click Add Ingress Rules.

Alright, in the Source CIDR field, enter If you’re unfamiliar with firewalls, that allows the source IP address to be any address in the world. Alternatively, you could set that to your own IP address or subnet, but on a web server, you probably want the HTTP and HTTPS ports to be open to the world.

Now in the Destination Port Range enter 80. And in Description enter HTTP.

Enter in Source CIDR, 80 in Destination Port Range, and HTTP in Description.

Now click + Another Ingress Rule and do the same for port 443 / HTTPS, and then click Add Ingress Rules.

Step 3 — Connect to Your VPS and Update

Alright! We now have a totally free Ubuntu server. Now we need to get connected. If you’re on MacOS, you can just open terminal to connect, but if you’re on Windows, you’ll need to enable SSH. You can find a guide here on how to do just that. Alternatively, you can download the free PUTTY SSH Client.

If you don’t already have an SSH Key Pair create one now by entering:

$ ssh-keygen

You can enter a password (recommended) but you don’t have to. Hit enter to place the file in the default location which is /your_home_directory/.ssh.

Now that that’s done, do the following:

$ cd ~/.ssh<br></br>$ mv ~/Downloads/ssh_key.key ./
$ nano config

The above example is for MacOS. For Windows you should be able to do notepad instead of nano. Also Windows uses for path separator, and MacOS or other ‘IXes use /.

Now in the new config file copy and paste the following. Change to suit your environment:

Host host_nickname
  IdentityFile ~/.ssh/key_key.key
  User ubuntu

The nice thing about setting up host configs is you don’t have to specify the key file every time and you can assign the host a nickname that you can use on the command line.

Hit CTRL-X, Y, Enter if using nano or CTRL-S if using notepad.

Now let’s connect to our VPS!

$ ssh host_nickname

Hopefully you are now logged in to your VPS and have a shell prompt. Now we need to update:

$ sudo apt-get update; apt-get -y upgrade; apt-get -y dist-upgrade

This will take a little time to complete. Next, let’s set our server’s Fully Qualified Domain Name or FQDN:

$ sudo hostnamectl set-hostname

Now, although we've already setup our VCN firewall for the virtual network, we need to update IP Tables from within Ubuntu. You have two options: you can either disable IP tables completely and rely on the subnet firewall, or we can add the allow rules for ports 443 and 80 manually. You could also install a firewall management tool, such as the Uncomplicated Firewall (UFW). Your choice.

Option 1 - Remove IP Tables Completely:

$ sudo iptables -P INPUT ACCEPT
$ sudo iptables -P OUTPUT ACCEPT
$ sudo iptables -P FORWARD ACCEPT
$ sudo iptables -F
$ sudo netfilter-persistent save

Option 2 - Allow Ports 443 and 80:

$ sudo iptables -I INPUT 6 -m state --state NEW -p tcp --dport 80 -j ACCEPT
$ sudo iptables -I INPUT 6 -m state --state NEW -p tcp --dport 443 -j ACCEPT
$ sudo netfilter-persistent save

Step 4 — Install Server Software

Now we’ll install the NGINX http server:

$ sudo apt -y install nginx

Once that’s done you can test to see if it’s working by entering in your web browser. You should see the default (it works) web page.

Next let’s install PHP-FPM, which is a very fast version of PHP that runs as a daemon. We’ll install the latest version, which is v8.1 at the time of this writing:

$ sudo apt -y install software-properties-common unzip
$ sudo add-apt-repository ppa:ondrej/php
$ sudo apt -y install php8.1-fpm

Let’s see if it’s working:

$ sudo systemctl status php8.1-fpm
php8.1-fpm.service - The PHP 8.1 FastCGI Process Manager
Loaded: loaded (/lib/systemd/system/php8.1-fpm.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2021-03-01 16:10:47 UTC; 6s ago

Hopefully, you will see the above output.

Now it’s time to install Mysql, which you’re probably going to want:

$ sudo apt -y install mysql-server

Once that’s done, we need to setup Mysql for production by running:

$ sudo mysql_secure_installation

Enter y for the first question if you want to enforce complex passwords, and then set a root password. Enter y for the rest of the questions.

Next we’ll install the php-mysql extension:

$ sudo apt -y install php8.1-mysql

Now we need to create a Mysql super user:

$ sudo mysql
CREATE USER 'admin'@'localhost' IDENTIFIED BY 'your-password';

Step 5 — Configure NGINX

First we’ll create a non-privileged user to store our public HTML files:

$ sudo adduser web

You can enter the finger information if you like but it’s optional.

You’ll probably want to import your public key that you created with ssh-keygen:

$ sudo su web
$ cd
$ ssh-keygen
$ cd .ssh
$ nano authorized_keys

Now copy and paste your contents from your .ssh directory on your local PC into the authorized_keys file.

Hit CTRL-X, Y, Enter to save.

Ok, let’s create some directories for our server root:

$ cd
$ mkdir wwwroot
$ cd wwwroot
$ mkdir pub
$ cd pub
$ nano index.php

Enter the following into the new file:


Now let’s create a directory for PHPMyAdmin, a web-based Mysql admin tool:

$ cd
$ wget
$ unzip
$ mv phpMyAdmin-5.1.3-all-languages pma
$ rm -f

Save the file and then hit CTRL-D to exit the web user session.

Now we need to configure NGINX. First we’ll set up cache control:

$ cd /etc/nginx/conf.d
$ sudo nano expires.conf

Copy and past the following into the new file:

map $sent_http_content_type $expires {
    default                    off;
    text/html                  epoch;
    text/css                   max;
    application/javascript     max;
    ~image/                    max;

Again, CTRL-X, Y, Enter to save. Now we’ll create a virtual host configuration:

$ cd /etc/nginx/sites-enabled
$ sudo rm -f default
$ cd ../sites-available
$ sudo nano

Copy and paste the following config into the new file, change to suit your situation, and then hit CTRL-X, Y, Enter:

server {
    root /home/web/wwwroot/pub;
    error_log /var/log/nginx/ error;
    access_log /var/log/nginx/;
    expires $expires;
    index index.html index.php;
    location / {
        try_files $uri $uri/ /index.php?$args;
    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
    location ~ /\.ht {
        deny all;

The above configuration will route any files not found to index.php, which is usually what you want.

Next, we’ll create a configuration for PHPMyAdmin:

$ sudo nano

Copy and paste the following configuration:

server {
    root /home/web/wwwroot/pma;
    error_log /var/log/nginx/ error;
    access_log /var/log/nginx/;
    expires $expires;
    index index.html index.php;
    location / {
        try_files $uri $uri/ =404;
    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
    location ~ /\.ht {
        deny all;

Now let’s enable the configurations by creating symbolic links:

$ cd ../sites-enabled
$ sudo ln -s /etc/nginx/sites-available/ .
$ sudo ln -s /etc/nginx/sites-available/ .

And reload NGINX:

$ sudo systemctl reload nginx

Now refresh your page. You should see the phpinfo page.

Step 6 — Setup SSL

In my example, we’re going to use certbot, a free SSL certificate tool provided by the Electronic Frontier Foundation:

$ sudo snap install core; sudo snap refresh core
$ sudo snap install --classic certbot
$ sudo certbot --nginx

Certbot will ask you to enter an admin email address. This will be your login identifier for Let’s Encrypt. Next, certbot will ask you if you want to receive periodic emails from the EFF. This is totally up to you.

Next you should see a list of virtual hosts that are configured in NGINX. In this example, we only have two: and You can just hit enter to select them all. Certbot will then do the following:

  • Create a hash file in each virtual host’s root directory
  • Verify those hashes via HTTP
  • Install the newly issues SSL certificates
  • Automatically configure your NGINX config files for SSL

Now if you refresh your web browser, it should automatically redirect you from http to https. If not, just change it in the address bar. Check that you are able to connect to and login with the admin user we created.

I hope everything went as planned and you are now the proud new owner of a completely free web server.

For information on how to create backups of your VPS, please see: Scheduling Backups on an Oracle Cloud VPS.

Thanks for reading!