Host a Website for Free: Oracle Cloud Server + One Setup Script (Complete Guide)

⏱ 3 min readUpdated 28 September 2026

You can run a real website on a cloud server that costs nothing. Oracle Cloud’s Always Free tier includes small virtual machines that are enough for a blog or small shop. This guide is the exact process used for this site.

In this article
  1. What you get for free
  2. 1. Create the server
  3. 2. Open ports 80 and 443
  4. 3. Connect
  5. 4. The one-command setup
  6. 5. Domain and free HTTPS with Cloudflare
  7. 6. Keep it healthy

What you get for free

  • Two small AMD VMs (1 GB RAM each) — or, if capacity is available in your region, Arm VMs with more RAM.
  • Around 200 GB of block storage in total and a public IPv4 address per VM.
  • A card is needed at sign-up for verification; Always-Free resources are not charged.
⚠️ Choose your home region carefully at sign-up (for India: Mumbai or Hyderabad) — it cannot be changed later, and free VMs are created only there.

1. Create the server

  1. Compute → Instances → Create instance.
  2. Image: Ubuntu 24.04. Shape: an Always-Free eligible one.
  3. Networking: assign a public IPv4 address.
  4. SSH keys: upload your public key (or let Oracle generate one and download the private key — you cannot get it later).
  5. Create, and note the public IP.

2. Open ports 80 and 443

Oracle blocks web traffic in two places:

  • Security list (VCN → Security Lists → Default → Add Ingress Rules): source 0.0.0.0/0, TCP ports 80,443.
  • The VM’s own iptables — the script below opens them.

3. Connect

“`bash
ssh -i ~/.ssh/oracle.key ubuntu@YOUR_IP
“`

On Windows the same command works in PowerShell or Git Bash. If it complains about permissions, restrict the key file to your user.

4. The one-command setup

Save this as setup.sh on the server and run sudo bash setup.sh example.com. It is safe to run again.

“`bash
#!/usr/bin/env bash
# Usage: sudo bash setup.sh example.com
set -euo pipefail
DOMAIN=$1; DB=wp_$(echo “$DOMAIN” | tr ‘.-‘ ‘__’); PASS=$(openssl rand -hex 16)
export DEBIAN_FRONTEND=noninteractive
apt-get update -qq
apt-get install -y -qq nginx mariadb-server fail2ban unattended-upgrades webp \
php8.3-fpm php8.3-mysql php8.3-gd php8.3-intl php8.3-zip php8.3-curl php8.3-mbstring php8.3-xml php8.3-imagick
# 2 GB swap: essential on 1 GB RAM
[ -f /swapfile ] || { fallocate -l 2G /swapfile; chmod 600 /swapfile; mkswap /swapfile; swapon /swapfile; echo “/swapfile none swap sw 0 0” >> /etc/fstab; }
# open web ports in Oracle’s iptables
for p in 80 443; do iptables -C INPUT -p tcp –dport $p -j ACCEPT 2>/dev/null || iptables -I INPUT 5 -p tcp –dport $p -j ACCEPT; done
apt-get install -y -qq iptables-persistent; netfilter-persistent save
# small-server tuning
printf “[mysqld]\ninnodb_buffer_pool_size=96M\nmax_connections=30\nperformance_schema=OFF\n” > /etc/mysql/mariadb.conf.d/99-small.cnf
sed -i ‘s/^pm = .*/pm = ondemand/; s/^pm.max_children = .*/pm.max_children = 4/’ /etc/php/8.3/fpm/pool.d/www.conf
systemctl restart mariadb php8.3-fpm
# database
mariadb -e “CREATE DATABASE IF NOT EXISTS $DB CHARACTER SET utf8mb4; CREATE USER IF NOT EXISTS ‘$DB’@’localhost’ IDENTIFIED BY ‘$PASS’; GRANT ALL ON $DB.* TO ‘$DB’@’localhost’;”
# WordPress
curl -sSLo /usr/local/bin/wp https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar && chmod +x /usr/local/bin/wp
mkdir -p /var/www/$DOMAIN && chown www-data: /var/www/$DOMAIN
sudo -u www-data wp core download –path=/var/www/$DOMAIN –quiet || true
sudo -u www-data wp config create –path=/var/www/$DOMAIN –dbname=$DB –dbuser=$DB –dbpass=$PASS –quiet –force
# nginx site
cat > /etc/nginx/sites-available/$DOMAIN <5. Domain and free HTTPS with Cloudflare

  1. Add your domain to Cloudflare (free plan) and change the nameservers at your registrar.
  2. DNS: an A record for @ and www pointing to the server IP, Proxied (orange cloud).
  3. SSL/TLS: create an Origin Certificate, save it on the server, add listen 443 ssl with the certificate paths to the Nginx site, then set SSL mode to Full (strict).
  4. Turn on Always Use HTTPS.

6. Keep it healthy

  • Backups: a nightly cron with wp db export and a tar of wp-content, keeping a few days — and copy them off the server now and then.
  • Updates: unattended-upgrades installs security patches automatically.
  • Page cache: Nginx FastCGI cache makes a 1 GB server serve pages in about 0.1 s.
  • Monitoring: check free -m and df -h monthly.
💡 A second free VM is perfect for a separate site (for example a shop), so one busy site never slows the other.
✨ Ask AI about this article

Stuck on a step? Ask a question and the AI answers using this article.

Free · AI can be wrong