Hack the Cloud: Free Oracle VM + Coolify = Your Own PaaS

Introduction

As a founder, solo hacker, or freelancer, you need a reliable and cost-effective way to host your applications. Oracle Cloud’s Free Tier offers an excellent opportunity to run a virtual machine (VM) for free, and Coolify provides a self-hostable alternative to platforms like Heroku or Netlify.

In this guide, you’ll learn how to:

  1. Set up an Oracle Cloud Free Tier VM using Terraform (Infrastructure as Code).

  2. Install and configure Coolify for app deployment.

  3. Connect a domain name to access your Coolify instance securely.


Prerequisites

Before starting, ensure you have:
✅ An Oracle Cloud Free Tier account (Sign up here).
Terraform installed on your local machine (Installation guide).
✅ A domain name (You can get one from Namecheap, Cloudflare, or Google Domains).
✅ Basic familiarity with SSH, Linux, and Terraform.


Step 1: Setting Up Oracle Cloud VM with Terraform

We’ll use Terraform to automate VM creation on Oracle Cloud Infrastructure (OCI).

1.1 Configure OCI Provider

First, set up authentication:

  1. Generate an API Key in Oracle Cloud:

    • Navigate to Profile (User Icon) → API Keys → Add API Key. (As shown below)

    • Download the private key and note the fingerprint.

    • Generate a public key with ssh-keygen , and note the path of your public key

  1. Gather Required OCI Details:

    • Tenancy OCID (User Settings → Tenancy)

    • User OCID (User Settings → User)

    • Compartment OCID (Identity → Compartments)

  2. Create a terraform.tfvars file:

     tenancy_ocid     = "ocid1.tenancy.oc1..xxxx"
     user_ocid        = "ocid1.user.oc1..xxxx"
     fingerprint      = "xx:xx:xx:xx:xx:xx:xx:xx"
     private_key_path = "~/.oci/oci_api_key.pem"
     compartment_ocid = "ocid1.compartment.oc1..xxxx"
     region           = "us-phoenix-1" # Choose your region
     public_key_path = "~/.ssh/id_rsa.pub"
    

1.2 Write Terraform Configuration

Create a main.tf file, copy and paste the terraform code below in the file.

provider "oci" {
  tenancy_ocid     = var.tenancy_ocid
  user_ocid        = var.user_ocid
  fingerprint      = var.fingerprint
  private_key_path = var.private_key_path
  region           = var.region
}


resource "oci_core_vcn" "vcn" {
  compartment_id = var.compartment_ocid
  cidr_block     = "10.0.0.0/16"
  display_name   = "my_vcn"
}

resource "oci_core_subnet" "subnet" {
  compartment_id = var.compartment_ocid
  vcn_id         = oci_core_vcn.vcn.id
  cidr_block     = "10.0.1.0/24"
  display_name   = "my_subnet"
  route_table_id = oci_core_route_table.rt.id
  security_list_ids = [oci_core_security_list.security_list.id]

}

resource "oci_core_internet_gateway" "igw" {
  compartment_id = var.compartment_ocid
  vcn_id         = oci_core_vcn.vcn.id
  display_name   = "my_igw"
}

resource "oci_core_route_table" "rt" {
  compartment_id = var.compartment_ocid
  vcn_id         = oci_core_vcn.vcn.id
  display_name   = "my_route_table"

  route_rules {
    destination       = "0.0.0.0/0"
    destination_type  = "CIDR_BLOCK"
    network_entity_id = oci_core_internet_gateway.igw.id
  }
}

resource "oci_core_security_list" "security_list" {
  compartment_id = var.compartment_ocid
  vcn_id         = oci_core_vcn.vcn.id
  display_name   = "my_security_list"

  ingress_security_rules {
    protocol = "6" # TCP
    source   = "0.0.0.0/0"

    tcp_options {
      min = 22
      max = 22
    }
  }
  # Allow Coolify (port 8000)
  ingress_security_rules {
    protocol = "6" # TCP
    source   = "0.0.0.0/0"

    tcp_options {
      min = 8000
      max = 8000
    }
  }

  # Allow ICMP (ping)
  ingress_security_rules {
    protocol = 1 # ICMP
    source   = "0.0.0.0/0"

    icmp_options {
      type = 8 # Echo request (ping)
    }
  }

  # Allow HTTPS (port 443)
  ingress_security_rules {
    protocol = "6" # TCP
    source   = "0.0.0.0/0"

    tcp_options {
      min = 443
      max = 443
    }
  }

  ingress_security_rules {
    protocol = "6" # TCP
    source   = "0.0.0.0/0"

    tcp_options {
      min = 80
      max = 80
    }
  }

  egress_security_rules {
    protocol    = "all"
    destination = "0.0.0.0/0"
  }
}

resource "oci_core_instance" "vm" {
  compartment_id      = var.compartment_ocid
  availability_domain = data.oci_identity_availability_domain.ad.name
  shape               = "VM.Standard.A1.Flex" # Flexible shape for custom RAM/CPU

  shape_config {
    ocpus         = 4
    memory_in_gbs = 24
  }

  display_name = "coolify_vm"

  source_details {
    source_type = "image"
    source_id   = data.oci_core_images.ubuntu.images[0].id
    boot_volume_size_in_gbs = 200 # 500 GB boot volume
  }

  create_vnic_details {
    subnet_id        = oci_core_subnet.subnet.id
    assign_public_ip = true
    # hostname_label   = "myvm"
  }

  metadata = {
    ssh_authorized_keys = file(var.public_key_path) # Path to your public SSH key
  }
}

data "oci_identity_availability_domain" "ad" {
  compartment_id = var.tenancy_ocid
  ad_number      = 1
}

data "oci_core_images" "ubuntu" {
  compartment_id           = var.compartment_ocid
  operating_system         = "Canonical Ubuntu"
  operating_system_version = "22.04"
  shape                    = "VM.Standard.A1.Flex"
}

Create a output.tf file, the intent of the file is to get the VM IP address. The content is shown below:

output "public_ip" {
  value = oci_core_instance.vm.public_ip
}

1.3 Deploy the VM

Run:

terraform init
terraform plan
terraform apply

After completion, note the VM’s public IP from the output.


Step 2: Installing Coolify on the VM

SSH into your VM:

# If there is an error, confirm the path of your ssh private key: ' ssh ubuntu@<PUBLIC_IP> -i {path_to_private_key}' 
ssh ubuntu@<PUBLIC_IP>

2.1 Install Docker & Coolify

Run:

curl -fsSL https://cdn.coollabs.io/coolify/install.sh | sudo bash

Follow the prompts to set up Coolify (admin email, password, etc.).

2.2 Access Coolify Dashboard

By default, Coolify runs on http://<PUBLIC_IP>:3000.


Step 3: Connecting a Domain Name

To access Coolify via a domain (e.g., coolify.yourdomain.com):

3.1 Configure DNS

  1. Go to your domain registrar (Cloudflare, Namecheap, etc.).

  2. Add an A record:

    • Name: coolify

    • Value: <VM_PUBLIC_IP>

    • TTL: Auto

3.2 Set Up Domain on Coolify

Nginx is installed on coolify by default, all you need to do is add your domain in the settings (e.g., coolify.yourdomain.com), Enable DNS Validation and the save the configuration. The steps is shown in the image below.

Now, access Coolify securely at https://coolify.yourdomain.com.


Conclusion

You’ve successfully:
✔ Created a free Oracle Cloud VM using Terraform.
✔ Installed Coolify for app deployment.
✔ Connected a custom domain with HTTPS.

Now, you can deploy apps effortlessly without relying on expensive cloud providers.

Next steps for you

  • Explore Coolify’s GitHub integration for CI/CD.

  • Set up automated backups for your VM.

  • Deploy your first app!

Happy hacking! 🚀


Questions?
Drop a comment below or reach out on Twitter/X.


References

0
Subscribe to my newsletter

Read articles from Abdulsalam Lukmon directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Abdulsalam Lukmon
Abdulsalam Lukmon